From 86a164b6bca882d0993a1ba2d85912a25b2c5d19 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Wed, 7 Feb 2024 16:36:15 +0200 Subject: [PATCH 01/13] fix: fix typos (#807) --- packages/api-bindings-v1/TROUBLESHOOTING.md | 4 ++-- packages/api-bindings-v1/src/lens/generated.ts | 4 ++-- packages/api-bindings/TROUBLESHOOTING.md | 4 ++-- .../use-cases/transactions/__tests__/TransactionQueue.spec.ts | 2 +- packages/react-v1/src/lifecycle/useCurrentSession.ts | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/api-bindings-v1/TROUBLESHOOTING.md b/packages/api-bindings-v1/TROUBLESHOOTING.md index 05d587448e..dfa62fb142 100644 --- a/packages/api-bindings-v1/TROUBLESHOOTING.md +++ b/packages/api-bindings-v1/TROUBLESHOOTING.md @@ -3,7 +3,7 @@ Quite likely type policies configuration is broken. To get the exact fields that are missing go to the `@apollo/client` `QueryManager.ts` and log the result of `readCache` method call inside `cache-first` fetch policy switch -(make sure you modify the file that get's imported by the bundler). +(make sure you modify the file that gets imported by the bundler). ```ts // ... @@ -12,7 +12,7 @@ switch (fetchPolicy) { default: case "cache-first": { const diff = readCache(); - console.log(diff) // should have a `misssing` properly + console.log(diff) // should have a `missing` properly if (diff.complete) { return [ diff --git a/packages/api-bindings-v1/src/lens/generated.ts b/packages/api-bindings-v1/src/lens/generated.ts index e0330491d1..af700b524a 100644 --- a/packages/api-bindings-v1/src/lens/generated.ts +++ b/packages/api-bindings-v1/src/lens/generated.ts @@ -443,7 +443,7 @@ export enum CustomFiltersTypes { } export type DataAvailabilityTransactionRequest = { - /** The DA transaction id or internal publiation id */ + /** The DA transaction id or internal publication id */ id: Scalars['String']; }; @@ -506,7 +506,7 @@ export type Erc4626FeeCollectModuleParams = { endTimestamp?: InputMaybe; /** True if only followers of publisher may collect the post. */ followerOnly: Scalars['Boolean']; - /** The address of the recipient who will recieve vault shares after depositing is completed. */ + /** The address of the recipient who will receive vault shares after depositing is completed. */ recipient: Scalars['EthereumAddress']; /** The referral fee associated with this publication. */ referralFee?: InputMaybe; diff --git a/packages/api-bindings/TROUBLESHOOTING.md b/packages/api-bindings/TROUBLESHOOTING.md index 05d587448e..dfa62fb142 100644 --- a/packages/api-bindings/TROUBLESHOOTING.md +++ b/packages/api-bindings/TROUBLESHOOTING.md @@ -3,7 +3,7 @@ Quite likely type policies configuration is broken. To get the exact fields that are missing go to the `@apollo/client` `QueryManager.ts` and log the result of `readCache` method call inside `cache-first` fetch policy switch -(make sure you modify the file that get's imported by the bundler). +(make sure you modify the file that gets imported by the bundler). ```ts // ... @@ -12,7 +12,7 @@ switch (fetchPolicy) { default: case "cache-first": { const diff = readCache(); - console.log(diff) // should have a `misssing` properly + console.log(diff) // should have a `missing` properly if (diff.complete) { return [ diff --git a/packages/domain/src/use-cases/transactions/__tests__/TransactionQueue.spec.ts b/packages/domain/src/use-cases/transactions/__tests__/TransactionQueue.spec.ts index 7954498a4a..e746f5dadc 100644 --- a/packages/domain/src/use-cases/transactions/__tests__/TransactionQueue.spec.ts +++ b/packages/domain/src/use-cases/transactions/__tests__/TransactionQueue.spec.ts @@ -261,7 +261,7 @@ describe(`Given an instance of the ${TransactionQueue.name} interactor`, () => { expect(transactionQueuePresenter.settled).toHaveBeenCalledWith(expectedTxData); }); - it('should avoid update loops with other threads by not re-saving straightaway the transaction back into the storage', async () => { + it('should avoid update loops with other threads by not re-saving straight away the transaction back into the storage', async () => { const { transactionGateway } = setupTestScenario({ request, }); diff --git a/packages/react-v1/src/lifecycle/useCurrentSession.ts b/packages/react-v1/src/lifecycle/useCurrentSession.ts index bbd8751aaa..220a25decd 100644 --- a/packages/react-v1/src/lifecycle/useCurrentSession.ts +++ b/packages/react-v1/src/lifecycle/useCurrentSession.ts @@ -149,7 +149,7 @@ export function useCurrentSession(): ReadResult< }; } - // shoudn't happen, but just in case, fallback to loading + // shouldn't happen, but just in case, fallback to loading return { data: undefined, error: undefined, From da4c26e344a04a9f2f869df6ef72822326335af2 Mon Sep 17 00:00:00 2001 From: Kris Urbas <605420+krzysu@users.noreply.github.com> Date: Fri, 9 Feb 2024 09:56:09 +0100 Subject: [PATCH 02/13] react: add useLazyProfilesManaged hook (#834) --- .changeset/gentle-glasses-jam.md | 7 ++ packages/react/src/wallet/index.ts | 1 + .../src/wallet/useLazyProfilesManaged.ts | 67 +++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 .changeset/gentle-glasses-jam.md create mode 100644 packages/react/src/wallet/useLazyProfilesManaged.ts diff --git a/.changeset/gentle-glasses-jam.md b/.changeset/gentle-glasses-jam.md new file mode 100644 index 0000000000..32f244ffaa --- /dev/null +++ b/.changeset/gentle-glasses-jam.md @@ -0,0 +1,7 @@ +--- +"@lens-protocol/react": minor +"@lens-protocol/react-native": minor +"@lens-protocol/react-web": minor +--- + +**feat:** Added `useLazyProfilesManaged` hook diff --git a/packages/react/src/wallet/index.ts b/packages/react/src/wallet/index.ts index 843688c838..c6b4de4fa5 100644 --- a/packages/react/src/wallet/index.ts +++ b/packages/react/src/wallet/index.ts @@ -3,6 +3,7 @@ */ export * from './useCanClaimHandle'; export * from './useLastLoggedInProfile'; +export * from './useLazyProfilesManaged'; export * from './useOwnedHandles'; export * from './useProfilesManaged'; diff --git a/packages/react/src/wallet/useLazyProfilesManaged.ts b/packages/react/src/wallet/useLazyProfilesManaged.ts new file mode 100644 index 0000000000..7f361b8fce --- /dev/null +++ b/packages/react/src/wallet/useLazyProfilesManaged.ts @@ -0,0 +1,67 @@ +import { + Profile, + ProfilesManagedRequest, + UnspecifiedError, + useProfilesManagedLazyQuery, +} from '@lens-protocol/api-bindings'; +import { failure, invariant, PromiseResult, success } from '@lens-protocol/shared-kernel'; + +import { useLensApolloClient } from '../helpers/arguments'; +import { PaginatedArgs } from '../helpers/reads'; +import { useDeferredTask, UseDeferredTask } from '../helpers/tasks'; + +/** + * {@link useLazyProfilesManaged} callback hook arguments + */ +export type ProfilesManagedArgs = PaginatedArgs; + +/** + * `useLazyProfilesManaged` is a lazy version of {@link useProfilesManaged} React Hook. + * + * This version doesn't support pagination! + * + * This hook will not fetch profiles until the returned function is called. + * + * @experimental This hook is experimental and may change in the future. + * @example + * ```ts + * const { called, data, error, loading, execute } = useLazyProfilesManaged(); + * + * const callback = async () => { + * const result = await execute({ + * for: '0x1234567890123456789012345678901234567890', + * }); + * + * if (result.isFailure()) { + * toast.error(result.error.message); + * return; + * } + * + * const profiles = result.value; + * + * // do something with the profiles + * } + * ``` + * + * @category Wallet + * @group Hooks + */ +export function useLazyProfilesManaged(): UseDeferredTask< + Profile[], + UnspecifiedError, + ProfilesManagedArgs +> { + const [fetch] = useProfilesManagedLazyQuery(useLensApolloClient({ fetchPolicy: 'no-cache' })); + + return useDeferredTask(async (args): PromiseResult => { + const { data, error } = await fetch({ variables: args }); + + if (error) { + return failure(new UnspecifiedError(error)); + } + + invariant(data, 'Data must be defined'); + + return success(data.result.items); + }); +} From 9c7fd3ee339facc45a43cdb96f73d6b19102c8de Mon Sep 17 00:00:00 2001 From: Cesare Naldi Date: Mon, 12 Feb 2024 08:02:18 +0000 Subject: [PATCH 03/13] T 19097/investigate (#838) * Domain changes * Clarify XMTP SignerAdapter Signer with alias * Removes redundant implements clause * Fix typos * Format files * Implementation * Fixes as per review comments * Adds changeset --- .changeset/thirty-eyes-act.md | 10 ++ examples/web/src/App.tsx | 6 +- examples/web/src/misc/UseValidateHandle.tsx | 2 +- examples/web/src/profiles/ProfilesPage.tsx | 5 + .../web/src/profiles/UseCreateProfile.tsx | 59 +++++++ examples/web/src/profiles/index.ts | 1 + .../lens/__helpers__/queries/transaction.ts | 17 +- .../src/lens/graphql/generated.ts | 160 +++++++++++++++++- .../src/lens/graphql/transaction.graphql | 4 + .../src/abi/PermissionlessCreator.json | 66 ++++++++ packages/blockchain-bindings/src/contracts.ts | 6 + .../blockchain-bindings/src/types/Erc20.ts | 10 +- .../src/types/LensFollowNFT.ts | 10 +- .../blockchain-bindings/src/types/LensHub.ts | 10 +- .../src/types/LensTokenHandleRegistry.ts | 10 +- .../src/types/PermissionlessCreator.ts | 145 ++++++++++++++++ .../src/types/PublicActProxy.ts | 10 +- .../blockchain-bindings/src/types/common.ts | 2 +- .../blockchain-bindings/src/types/index.ts | 3 +- .../src/use-cases/authentication/Login.ts | 5 +- .../authentication/__tests__/Login.spec.ts | 9 +- .../src/use-cases/profile/CreateProfile.ts | 53 +++--- .../use-cases/profile/__helpers__/mocks.ts | 56 ++---- .../profile/__tests__/CreateProfile.spec.ts | 142 ++++++++++------ .../transactions/IPaidTransactionGateway.ts | 6 + .../use-cases/transactions/PaidTransaction.ts | 9 +- .../transactions/__helpers__/mocks.ts | 29 +++- .../__tests__/PaidTransaction.spec.ts | 31 ++-- .../src/use-cases/transactions/index.ts | 9 +- .../src/use-cases/wallets/IWalletFactory.ts | 7 + .../use-cases/wallets/__helpers__/mocks.ts | 21 +-- .../domain/src/use-cases/wallets/index.ts | 3 +- .../src/inbox/adapters/SignerAdapter.ts | 4 +- packages/react/src/environments.ts | 12 ++ packages/react/src/misc/useValidateHandle.ts | 28 ++- .../adapters/AbstractContractCallGateway.ts | 46 ++++- .../adapters/ApproveTransactionGateway.ts | 10 +- ...ePresenter.ts => ClaimProfilePresenter.ts} | 6 +- .../adapters/CreateProfilePresenter.ts | 76 +++++++++ .../CreateProfileTransactionGateway.ts | 63 +++++++ .../adapters/OpenActionGateway.ts | 20 +-- .../ApproveTransactionGateway.spec.ts | 4 +- .../CreateProfileTransactionGateway.spec.ts | 120 +++++++++++++ .../__tests__/OpenActionGateway.spec.ts | 4 +- .../adapters/profiles/BlockProfilesGateway.ts | 2 +- .../adapters/profiles/FollowProfileGateway.ts | 20 +-- .../adapters/profiles/LinkHandleGateway.ts | 2 +- .../profiles/ProfileMetadataGateway.ts | 6 +- .../profiles/UnblockProfilesGateway.ts | 2 +- .../profiles/UnfollowProfileGateway.ts | 2 +- .../adapters/profiles/UnlinkHandleGateway.ts | 2 +- .../profiles/UpdateFollowPolicyGateway.ts | 6 +- .../profiles/UpdateProfileManagersGateway.ts | 2 +- .../__tests__/BlockProfilesGateway.spec.ts | 2 +- .../__tests__/FollowProfileGateway.spec.ts | 12 +- .../__tests__/LinkHandleGateway.spec.ts | 6 +- .../__tests__/ProfileMetadataGateway.spec.ts | 2 +- .../__tests__/UnblockProfilesGateway.spec.ts | 2 +- .../__tests__/UnfollowProfileGateway.spec.ts | 2 +- .../__tests__/UnlinkHandleGateway.spec.ts | 6 +- .../UpdateFollowPolicyGateway.spec.ts | 6 +- .../CreateOnChainCommentGateway.ts | 18 +- .../CreateOnChainMirrorGateway.ts | 6 +- .../publications/CreateOnChainPostGateway.ts | 18 +- .../publications/CreateOnChainQuoteGateway.ts | 22 ++- .../CreateOnChainCommentGateway.spec.ts | 4 +- .../CreateOnChainMirrorGateway.spec.ts | 6 +- .../CreateOnChainPostGateway.spec.ts | 14 +- .../CreateOnChainQuoteGateway.spec.ts | 6 +- .../transactions/adapters/schemas/profiles.ts | 11 +- .../adapters/useClaimHandleController.ts | 4 +- .../adapters/useCreateProfileController.ts | 53 ++++++ packages/react/src/transactions/index.ts | 6 +- .../src/transactions/useCreateProfile.ts | 112 ++++++++++++ .../src/wallet/adapters/WalletFactory.ts | 2 +- .../adapters/__tests__/ConcreteWallet.spec.ts | 17 +- 76 files changed, 1320 insertions(+), 370 deletions(-) create mode 100644 .changeset/thirty-eyes-act.md create mode 100644 examples/web/src/profiles/UseCreateProfile.tsx create mode 100644 packages/blockchain-bindings/src/abi/PermissionlessCreator.json create mode 100644 packages/blockchain-bindings/src/types/PermissionlessCreator.ts create mode 100644 packages/domain/src/use-cases/transactions/IPaidTransactionGateway.ts create mode 100644 packages/domain/src/use-cases/wallets/IWalletFactory.ts rename packages/react/src/transactions/adapters/{NewProfilePresenter.ts => ClaimProfilePresenter.ts} (98%) create mode 100644 packages/react/src/transactions/adapters/CreateProfilePresenter.ts create mode 100644 packages/react/src/transactions/adapters/CreateProfileTransactionGateway.ts create mode 100644 packages/react/src/transactions/adapters/__tests__/CreateProfileTransactionGateway.spec.ts create mode 100644 packages/react/src/transactions/adapters/useCreateProfileController.ts create mode 100644 packages/react/src/transactions/useCreateProfile.ts diff --git a/.changeset/thirty-eyes-act.md b/.changeset/thirty-eyes-act.md new file mode 100644 index 0000000000..c8f36ec2e5 --- /dev/null +++ b/.changeset/thirty-eyes-act.md @@ -0,0 +1,10 @@ +--- +"@lens-protocol/react-web": minor +"@lens-protocol/react": minor +"@lens-protocol/react-native": minor +"@lens-protocol/blockchain-bindings": patch +"@lens-protocol/api-bindings": patch +"@lens-protocol/domain": patch +--- + +**feat:** `useCreateProfile` hook diff --git a/examples/web/src/App.tsx b/examples/web/src/App.tsx index d4cc38404f..d627311ccd 100644 --- a/examples/web/src/App.tsx +++ b/examples/web/src/App.tsx @@ -3,7 +3,7 @@ import { bindings as wagmiBindings } from '@lens-protocol/wagmi'; import { XMTPProvider } from '@xmtp/react-sdk'; import { Toaster } from 'react-hot-toast'; import { Outlet, Route, BrowserRouter as Router, Routes } from 'react-router-dom'; -import { configureChains, createConfig, WagmiConfig } from 'wagmi'; +import { WagmiConfig, configureChains, createConfig } from 'wagmi'; import { polygonMumbai } from 'wagmi/chains'; import { InjectedConnector } from 'wagmi/connectors/injected'; import { publicProvider } from 'wagmi/providers/public'; @@ -45,6 +45,7 @@ import { ProfilesPage, UseBlockAndUnblockProfiles, UseBlockedProfiles, + UseCreateProfile, UseFollowAndUnfollow, UseLastLoggedInProfile, UseLazyProfile, @@ -66,8 +67,8 @@ import { } from './profiles'; import { PublicationsPage, - UseBookmarks, UseBookmarkToggle, + UseBookmarks, UseCreateComment, UseCreateMirror, UseCreatePost, @@ -149,6 +150,7 @@ export function App() { } /> + } /> } /> } /> } /> diff --git a/examples/web/src/misc/UseValidateHandle.tsx b/examples/web/src/misc/UseValidateHandle.tsx index 5a01cedda7..8e3236f013 100644 --- a/examples/web/src/misc/UseValidateHandle.tsx +++ b/examples/web/src/misc/UseValidateHandle.tsx @@ -11,7 +11,7 @@ export function UseValidateHandle() { const localName = formData.get('localName') as string; - const result = await execute({ handle: localName }); + const result = await execute({ localName }); if (result.isFailure()) { toast.error(result.error.message); diff --git a/examples/web/src/profiles/ProfilesPage.tsx b/examples/web/src/profiles/ProfilesPage.tsx index e9b2db5e25..91848f010d 100644 --- a/examples/web/src/profiles/ProfilesPage.tsx +++ b/examples/web/src/profiles/ProfilesPage.tsx @@ -1,6 +1,11 @@ import { LinkCard } from '../components/LinkCard'; const profileHooks = [ + { + label: 'useCreateProfile', + description: 'Create a new Profile.', + path: '/profiles/useCreateProfile', + }, { label: 'useProfile', description: 'Fetch a single profile.', diff --git a/examples/web/src/profiles/UseCreateProfile.tsx b/examples/web/src/profiles/UseCreateProfile.tsx new file mode 100644 index 0000000000..31c203b939 --- /dev/null +++ b/examples/web/src/profiles/UseCreateProfile.tsx @@ -0,0 +1,59 @@ +import { useCreateProfile } from '@lens-protocol/react-web'; +import toast from 'react-hot-toast'; + +import { RequireConnectedWallet } from '../components/auth'; + +export function CreateProfileForm({ address }: { address: string }) { + const { execute, loading } = useCreateProfile(); + + const createProfile = async (event: React.FormEvent) => { + event.preventDefault(); + const form = event.currentTarget; + const formData = new FormData(form); + + const localName = formData.get('localName') as string; + + const result = await execute({ localName, to: address }); + + if (result.isFailure()) { + toast.error(result.error.message); + return; + } + + const profile = result.value; + + toast.success(`Congratulations! You now own: ${profile.handle?.fullHandle}!`); + return; + }; + + return ( +
+
+ Choose an handle for your profile + +
+ +
+
+
+ ); +} + +export function UseCreateProfile() { + return ( +
+

+ useCreateProfile +

+ + + {(address) => } + +
+ ); +} diff --git a/examples/web/src/profiles/index.ts b/examples/web/src/profiles/index.ts index cd3296a8dc..3479c9d431 100644 --- a/examples/web/src/profiles/index.ts +++ b/examples/web/src/profiles/index.ts @@ -1,6 +1,7 @@ export * from './ProfilesPage'; export * from './UseBlockAndUnblockProfiles'; export * from './UseBlockedProfiles'; +export * from './UseCreateProfile'; export * from './UseFollowAndUnfollow'; export * from './UseLastLoggedInProfile'; export * from './UseLazyProfile'; diff --git a/packages/api-bindings/src/lens/__helpers__/queries/transaction.ts b/packages/api-bindings/src/lens/__helpers__/queries/transaction.ts index 0d513a9fd6..cb113fa61c 100644 --- a/packages/api-bindings/src/lens/__helpers__/queries/transaction.ts +++ b/packages/api-bindings/src/lens/__helpers__/queries/transaction.ts @@ -1,11 +1,13 @@ import { MockedResponse } from '@apollo/client/testing'; import { mockTransactionHash } from '@lens-protocol/domain/mocks'; +import { EvmAddress } from '@lens-protocol/shared-kernel'; import { + GenerateLensApiRelayAddressDocument, + LensTransactionResult, LensTransactionStatusData, - LensTransactionStatusRequest, LensTransactionStatusDocument, - LensTransactionResult, + LensTransactionStatusRequest, LensTransactionStatusType, } from '../../graphql/generated'; @@ -39,3 +41,14 @@ export function mockLensTransactionResult( __typename: 'LensTransactionResult', }; } + +export function mockGenerateLensAPIRelayAddressResponse({ address }: { address: EvmAddress }) { + return { + request: { + query: GenerateLensApiRelayAddressDocument, + }, + result: { + data: { result: address }, + }, + }; +} diff --git a/packages/api-bindings/src/lens/graphql/generated.ts b/packages/api-bindings/src/lens/graphql/generated.ts index eb85369483..092389e19d 100644 --- a/packages/api-bindings/src/lens/graphql/generated.ts +++ b/packages/api-bindings/src/lens/graphql/generated.ts @@ -499,6 +499,17 @@ export type HandleToAddressRequest = { handle: Scalars['Handle']; }; +export enum HiddenCommentsType { + HiddenOnly = 'HIDDEN_ONLY', + Hide = 'HIDE', + Show = 'SHOW', +} + +export type HideCommentRequest = { + /** The comment to hide. It has to be under a publication made by the user making the request. If already hidden, nothing will happen. */ + for: Scalars['PublicationId']; +}; + export type HidePublicationRequest = { for: Scalars['PublicationId']; }; @@ -627,6 +638,11 @@ export type LastLoggedInProfileRequest = { for: Scalars['EvmAddress']; }; +export type LatestPaidActionsFilter = { + openActionFilters?: InputMaybe>; + openActionPublicationMetadataFilters?: InputMaybe; +}; + export type LegacyCollectRequest = { on: Scalars['PublicationId']; referrer?: InputMaybe; @@ -641,11 +657,6 @@ export enum LensProfileManagerRelayErrorReasonType { RequiresSignature = 'REQUIRES_SIGNATURE', } -export enum LensProtocolVersion { - V1 = 'V1', - V2 = 'V2', -} - export enum LensTransactionFailureType { MetadataError = 'METADATA_ERROR', Reverted = 'REVERTED', @@ -760,6 +771,7 @@ export enum MomokaValidatorError { PotentialReorg = 'POTENTIAL_REORG', PublicationNonceInvalid = 'PUBLICATION_NONCE_INVALID', PublicationNoneDa = 'PUBLICATION_NONE_DA', + PublicationNotRecognized = 'PUBLICATION_NOT_RECOGNIZED', PublicationNoPointer = 'PUBLICATION_NO_POINTER', PublicationSignerNotAllowed = 'PUBLICATION_SIGNER_NOT_ALLOWED', SimulationFailed = 'SIMULATION_FAILED', @@ -1237,6 +1249,7 @@ export type ProfileSpamReasonInput = { export type ProfileStatsArg = { customFilters?: InputMaybe>; forApps?: InputMaybe>; + hiddenComments?: InputMaybe; }; export type ProfileStatsCountOpenActionArgs = { @@ -1292,6 +1305,8 @@ export type PublicationBookmarksWhere = { }; export type PublicationCommentOn = { + /** You can use this enum to show, hide or show only hidden comments */ + hiddenComments?: InputMaybe; id: Scalars['PublicationId']; ranking?: InputMaybe; }; @@ -1464,6 +1479,7 @@ export type PublicationStatsCountOpenActionArgs = { export type PublicationStatsInput = { customFilters?: InputMaybe>; + hiddenComments?: InputMaybe; /** Filter the returned stats on apps and 1 of the following filters: tags, contentWarning, mainContentFocus, locale */ metadata?: InputMaybe; }; @@ -1704,6 +1720,11 @@ export type UnfollowRequest = { unfollow: Array; }; +export type UnhideCommentRequest = { + /** The comment to unhide. It has to be under a publication made by the user making the request. If already visible, nothing will happen. */ + for: Scalars['PublicationId']; +}; + export type UnknownFollowModuleInput = { address: Scalars['EvmAddress']; data: Scalars['BlockchainData']; @@ -1734,6 +1755,11 @@ export type UnlinkHandleFromProfileRequest = { handle: Scalars['Handle']; }; +export type UserCurrentRateLimitRequest = { + profileId?: InputMaybe; + userAddress: Scalars['EvmAddress']; +}; + export type UserPoapsQueryRequest = { cursor?: InputMaybe; for: Scalars['ProfileId']; @@ -4439,6 +4465,10 @@ export type BroadcastOnMomokaVariables = Exact<{ export type BroadcastOnMomokaData = { result: CreateMomokaPublicationResult | RelayError }; +export type GenerateLensApiRelayAddressVariables = Exact<{ [key: string]: never }>; + +export type GenerateLensApiRelayAddressData = { result: EvmAddress }; + export type OwnedHandlesVariables = Exact<{ for: Scalars['EvmAddress']; limit?: InputMaybe; @@ -249809,6 +249839,76 @@ export type BroadcastOnMomokaMutationOptions = Apollo.BaseMutationOptions< BroadcastOnMomokaData, BroadcastOnMomokaVariables >; +export const GenerateLensApiRelayAddressDocument = /*#__PURE__*/ { + kind: 'Document', + definitions: [ + { + kind: 'OperationDefinition', + operation: 'query', + name: { kind: 'Name', value: 'GenerateLensAPIRelayAddress' }, + selectionSet: { + kind: 'SelectionSet', + selections: [ + { + kind: 'Field', + alias: { kind: 'Name', value: 'result' }, + name: { kind: 'Name', value: 'generateLensAPIRelayAddress' }, + }, + ], + }, + }, + ], +} as unknown as DocumentNode; + +/** + * __useGenerateLensApiRelayAddress__ + * + * To run a query within a React component, call `useGenerateLensApiRelayAddress` and pass it any options that fit your needs. + * When your component renders, `useGenerateLensApiRelayAddress` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGenerateLensApiRelayAddress({ + * variables: { + * }, + * }); + */ +export function useGenerateLensApiRelayAddress( + baseOptions?: Apollo.QueryHookOptions< + GenerateLensApiRelayAddressData, + GenerateLensApiRelayAddressVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useQuery( + GenerateLensApiRelayAddressDocument, + options, + ); +} +export function useGenerateLensApiRelayAddressLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions< + GenerateLensApiRelayAddressData, + GenerateLensApiRelayAddressVariables + >, +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useLazyQuery( + GenerateLensApiRelayAddressDocument, + options, + ); +} +export type GenerateLensApiRelayAddressHookResult = ReturnType< + typeof useGenerateLensApiRelayAddress +>; +export type GenerateLensApiRelayAddressLazyQueryHookResult = ReturnType< + typeof useGenerateLensApiRelayAddressLazyQuery +>; +export type GenerateLensApiRelayAddressQueryResult = Apollo.QueryResult< + GenerateLensApiRelayAddressData, + GenerateLensApiRelayAddressVariables +>; export const OwnedHandlesDocument = /*#__PURE__*/ { kind: 'Document', definitions: [ @@ -252545,6 +252645,7 @@ export type CommentKeySpecifier = ( | 'createdAt' | 'firstComment' | 'hashtagsMentioned' + | 'hiddenByAuthor' | 'id' | 'isEncrypted' | 'isHidden' @@ -252566,6 +252667,7 @@ export type CommentFieldPolicy = { createdAt?: FieldPolicy | FieldReadFunction; firstComment?: FieldPolicy | FieldReadFunction; hashtagsMentioned?: FieldPolicy | FieldReadFunction; + hiddenByAuthor?: FieldPolicy | FieldReadFunction; id?: FieldPolicy | FieldReadFunction; isEncrypted?: FieldPolicy | FieldReadFunction; isHidden?: FieldPolicy | FieldReadFunction; @@ -254630,6 +254732,7 @@ export type MutationKeySpecifier = ( | 'deleteNftGallery' | 'dismissRecommendedProfiles' | 'follow' + | 'hideComment' | 'hidePublication' | 'idKitPhoneVerifyWebhook' | 'internalAddCuratedTag' @@ -254666,6 +254769,7 @@ export type MutationKeySpecifier = ( | 'unblock' | 'undoPublicationNotInterested' | 'unfollow' + | 'unhideComment' | 'unlinkHandleFromProfile' | 'updateNftGalleryInfo' | 'updateNftGalleryItems' @@ -254711,6 +254815,7 @@ export type MutationFieldPolicy = { deleteNftGallery?: FieldPolicy | FieldReadFunction; dismissRecommendedProfiles?: FieldPolicy | FieldReadFunction; follow?: FieldPolicy | FieldReadFunction; + hideComment?: FieldPolicy | FieldReadFunction; hidePublication?: FieldPolicy | FieldReadFunction; idKitPhoneVerifyWebhook?: FieldPolicy | FieldReadFunction; internalAddCuratedTag?: FieldPolicy | FieldReadFunction; @@ -254747,6 +254852,7 @@ export type MutationFieldPolicy = { unblock?: FieldPolicy | FieldReadFunction; undoPublicationNotInterested?: FieldPolicy | FieldReadFunction; unfollow?: FieldPolicy | FieldReadFunction; + unhideComment?: FieldPolicy | FieldReadFunction; unlinkHandleFromProfile?: FieldPolicy | FieldReadFunction; updateNftGalleryInfo?: FieldPolicy | FieldReadFunction; updateNftGalleryItems?: FieldPolicy | FieldReadFunction; @@ -255622,6 +255728,7 @@ export type QueryKeySpecifier = ( | 'followStatusBulk' | 'followers' | 'following' + | 'generateLensAPIRelayAddress' | 'generateModuleCurrencyApprovalData' | 'handleToAddress' | 'internalAllowedDomains' @@ -255678,6 +255785,7 @@ export type QueryKeySpecifier = ( | 'supportedOpenActionModules' | 'supportedReferenceModules' | 'txIdToTxHash' + | 'userRateLimit' | 'userSigNonces' | 'validatePublicationMetadata' | 'verify' @@ -255704,6 +255812,7 @@ export type QueryFieldPolicy = { followStatusBulk?: FieldPolicy | FieldReadFunction; followers?: FieldPolicy | FieldReadFunction; following?: FieldPolicy | FieldReadFunction; + generateLensAPIRelayAddress?: FieldPolicy | FieldReadFunction; generateModuleCurrencyApprovalData?: FieldPolicy | FieldReadFunction; handleToAddress?: FieldPolicy | FieldReadFunction; internalAllowedDomains?: FieldPolicy | FieldReadFunction; @@ -255760,6 +255869,7 @@ export type QueryFieldPolicy = { supportedOpenActionModules?: FieldPolicy | FieldReadFunction; supportedReferenceModules?: FieldPolicy | FieldReadFunction; txIdToTxHash?: FieldPolicy | FieldReadFunction; + userRateLimit?: FieldPolicy | FieldReadFunction; userSigNonces?: FieldPolicy | FieldReadFunction; validatePublicationMetadata?: FieldPolicy | FieldReadFunction; verify?: FieldPolicy | FieldReadFunction; @@ -256245,6 +256355,32 @@ export type UnknownSupportedModuleFieldPolicy = { contract?: FieldPolicy | FieldReadFunction; moduleName?: FieldPolicy | FieldReadFunction; }; +export type UserCurrentRateLimitKeySpecifier = ( + | 'dayAllowance' + | 'dayAllowanceLeft' + | 'dayAllowanceUsed' + | 'hourAllowance' + | 'hourAllowanceLeft' + | 'hourAllowanceUsed' + | UserCurrentRateLimitKeySpecifier +)[]; +export type UserCurrentRateLimitFieldPolicy = { + dayAllowance?: FieldPolicy | FieldReadFunction; + dayAllowanceLeft?: FieldPolicy | FieldReadFunction; + dayAllowanceUsed?: FieldPolicy | FieldReadFunction; + hourAllowance?: FieldPolicy | FieldReadFunction; + hourAllowanceLeft?: FieldPolicy | FieldReadFunction; + hourAllowanceUsed?: FieldPolicy | FieldReadFunction; +}; +export type UserCurrentRateLimitResultKeySpecifier = ( + | 'momoka' + | 'onchain' + | UserCurrentRateLimitResultKeySpecifier +)[]; +export type UserCurrentRateLimitResultFieldPolicy = { + momoka?: FieldPolicy | FieldReadFunction; + onchain?: FieldPolicy | FieldReadFunction; +}; export type UserSigNoncesKeySpecifier = ( | 'lensHubOnchainSigNonce' | 'lensPublicActProxyOnchainSigNonce' @@ -258082,6 +258218,20 @@ export type StrictTypedTypePolicies = { | (() => undefined | UnknownSupportedModuleKeySpecifier); fields?: UnknownSupportedModuleFieldPolicy; }; + UserCurrentRateLimit?: Omit & { + keyFields?: + | false + | UserCurrentRateLimitKeySpecifier + | (() => undefined | UserCurrentRateLimitKeySpecifier); + fields?: UserCurrentRateLimitFieldPolicy; + }; + UserCurrentRateLimitResult?: Omit & { + keyFields?: + | false + | UserCurrentRateLimitResultKeySpecifier + | (() => undefined | UserCurrentRateLimitResultKeySpecifier); + fields?: UserCurrentRateLimitResultFieldPolicy; + }; UserSigNonces?: Omit & { keyFields?: false | UserSigNoncesKeySpecifier | (() => undefined | UserSigNoncesKeySpecifier); fields?: UserSigNoncesFieldPolicy; diff --git a/packages/api-bindings/src/lens/graphql/transaction.graphql b/packages/api-bindings/src/lens/graphql/transaction.graphql index c24b4c9338..2139534660 100644 --- a/packages/api-bindings/src/lens/graphql/transaction.graphql +++ b/packages/api-bindings/src/lens/graphql/transaction.graphql @@ -52,3 +52,7 @@ mutation BroadcastOnMomoka($request: BroadcastRequest!) { } } } + +query GenerateLensAPIRelayAddress { + result: generateLensAPIRelayAddress +} diff --git a/packages/blockchain-bindings/src/abi/PermissionlessCreator.json b/packages/blockchain-bindings/src/abi/PermissionlessCreator.json new file mode 100644 index 0000000000..8ed74dab21 --- /dev/null +++ b/packages/blockchain-bindings/src/abi/PermissionlessCreator.json @@ -0,0 +1,66 @@ +[ + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "followModule", + "type": "address" + }, + { + "internalType": "bytes", + "name": "followModuleInitData", + "type": "bytes" + } + ], + "internalType": "struct Types.CreateProfileParams", + "name": "createProfileParams", + "type": "tuple" + }, + { + "internalType": "string", + "name": "handle", + "type": "string" + }, + { + "internalType": "address[]", + "name": "delegatedExecutors", + "type": "address[]" + } + ], + "name": "createProfileWithHandle", + "outputs": [ + { + "internalType": "uint256", + "name": "profileId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "handleId", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getProfileWithHandleCreationPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/packages/blockchain-bindings/src/contracts.ts b/packages/blockchain-bindings/src/contracts.ts index ebe23959ec..a534d03e08 100644 --- a/packages/blockchain-bindings/src/contracts.ts +++ b/packages/blockchain-bindings/src/contracts.ts @@ -5,6 +5,7 @@ import { EvmAddress } from '@lens-protocol/shared-kernel'; import lensFollowNftAbi from './abi/LensFollowNFT.json'; import lensHubAbi from './abi/LensHub.json'; import lensTokenHandleRegistryAbi from './abi/LensTokenHandleRegistry.json'; +import permissionlessCreatorAbi from './abi/PermissionlessCreator.json'; import publicActProxyAbi from './abi/PublicActProxy.json'; import erc20Abi from './abi/erc-20.json'; import type { @@ -12,6 +13,7 @@ import type { LensFollowNFT, LensHub, LensTokenHandleRegistry, + PermissionlessCreator, PublicActProxy, } from './types'; @@ -34,3 +36,7 @@ export function lensTokenHandleRegistry(address: EvmAddress, provider?: Provider export function publicActProxy(address: EvmAddress, provider?: Provider) { return new Contract(address, publicActProxyAbi, provider) as PublicActProxy; } + +export function permissionlessCreator(address: EvmAddress, provider?: Provider) { + return new Contract(address, permissionlessCreatorAbi, provider) as PermissionlessCreator; +} diff --git a/packages/blockchain-bindings/src/types/Erc20.ts b/packages/blockchain-bindings/src/types/Erc20.ts index 79c4ab4be6..f13dddff29 100755 --- a/packages/blockchain-bindings/src/types/Erc20.ts +++ b/packages/blockchain-bindings/src/types/Erc20.ts @@ -1,6 +1,8 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +import type { EventFragment, FunctionFragment, Result } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; import type { BaseContract, BigNumber, @@ -13,14 +15,12 @@ import type { Signer, utils, } from 'ethers'; -import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi'; -import type { Listener, Provider } from '@ethersproject/providers'; import type { - TypedEventFilter, - TypedEvent, - TypedListener, OnEvent, PromiseOrValue, + TypedEvent, + TypedEventFilter, + TypedListener, } from './common'; export interface Erc20Interface extends utils.Interface { diff --git a/packages/blockchain-bindings/src/types/LensFollowNFT.ts b/packages/blockchain-bindings/src/types/LensFollowNFT.ts index be6394cc48..db0381a11e 100644 --- a/packages/blockchain-bindings/src/types/LensFollowNFT.ts +++ b/packages/blockchain-bindings/src/types/LensFollowNFT.ts @@ -1,6 +1,8 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +import type { EventFragment, FunctionFragment, Result } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; import type { BaseContract, BigNumber, @@ -13,14 +15,12 @@ import type { Signer, utils, } from 'ethers'; -import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi'; -import type { Listener, Provider } from '@ethersproject/providers'; import type { - TypedEventFilter, - TypedEvent, - TypedListener, OnEvent, PromiseOrValue, + TypedEvent, + TypedEventFilter, + TypedListener, } from './common'; export declare namespace DataTypes { diff --git a/packages/blockchain-bindings/src/types/LensHub.ts b/packages/blockchain-bindings/src/types/LensHub.ts index f9c3302020..24994626a1 100644 --- a/packages/blockchain-bindings/src/types/LensHub.ts +++ b/packages/blockchain-bindings/src/types/LensHub.ts @@ -1,6 +1,8 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +import type { EventFragment, FunctionFragment, Result } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; import type { BaseContract, BigNumber, @@ -13,14 +15,12 @@ import type { Signer, utils, } from 'ethers'; -import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi'; -import type { Listener, Provider } from '@ethersproject/providers'; import type { - TypedEventFilter, - TypedEvent, - TypedListener, OnEvent, PromiseOrValue, + TypedEvent, + TypedEventFilter, + TypedListener, } from './common'; export declare namespace Types { diff --git a/packages/blockchain-bindings/src/types/LensTokenHandleRegistry.ts b/packages/blockchain-bindings/src/types/LensTokenHandleRegistry.ts index 3b2e31e5bf..135efbc1f5 100644 --- a/packages/blockchain-bindings/src/types/LensTokenHandleRegistry.ts +++ b/packages/blockchain-bindings/src/types/LensTokenHandleRegistry.ts @@ -1,6 +1,8 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +import type { FunctionFragment, Result } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; import type { BaseContract, BigNumber, @@ -13,14 +15,12 @@ import type { Signer, utils, } from 'ethers'; -import type { FunctionFragment, Result } from '@ethersproject/abi'; -import type { Listener, Provider } from '@ethersproject/providers'; import type { - TypedEventFilter, - TypedEvent, - TypedListener, OnEvent, PromiseOrValue, + TypedEvent, + TypedEventFilter, + TypedListener, } from './common'; export declare namespace Types { diff --git a/packages/blockchain-bindings/src/types/PermissionlessCreator.ts b/packages/blockchain-bindings/src/types/PermissionlessCreator.ts new file mode 100644 index 0000000000..4f88f3d9ed --- /dev/null +++ b/packages/blockchain-bindings/src/types/PermissionlessCreator.ts @@ -0,0 +1,145 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { FunctionFragment, Result } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; +import type { + BaseContract, + BigNumber, + BytesLike, + CallOverrides, + ContractTransaction, + PayableOverrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers'; +import type { + OnEvent, + PromiseOrValue, + TypedEvent, + TypedEventFilter, + TypedListener, +} from './common'; + +export declare namespace Types { + export type CreateProfileParamsStruct = { + to: PromiseOrValue; + followModule: PromiseOrValue; + followModuleInitData: PromiseOrValue; + }; + + export type CreateProfileParamsStructOutput = [string, string, string] & { + to: string; + followModule: string; + followModuleInitData: string; + }; +} + +export interface PermissionlessCreatorInterface extends utils.Interface { + functions: { + 'createProfileWithHandle((address,address,bytes),string,address[])': FunctionFragment; + 'getProfileWithHandleCreationPrice()': FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: 'createProfileWithHandle' | 'getProfileWithHandleCreationPrice', + ): FunctionFragment; + + encodeFunctionData( + functionFragment: 'createProfileWithHandle', + values: [Types.CreateProfileParamsStruct, PromiseOrValue, PromiseOrValue[]], + ): string; + encodeFunctionData( + functionFragment: 'getProfileWithHandleCreationPrice', + values?: undefined, + ): string; + + decodeFunctionResult(functionFragment: 'createProfileWithHandle', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'getProfileWithHandleCreationPrice', + data: BytesLike, + ): Result; + + events: {}; +} + +export interface PermissionlessCreator extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: PermissionlessCreatorInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined, + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter, + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners(eventFilter: TypedEventFilter): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + createProfileWithHandle( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + getProfileWithHandleCreationPrice(overrides?: CallOverrides): Promise<[BigNumber]>; + }; + + createProfileWithHandle( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + getProfileWithHandleCreationPrice(overrides?: CallOverrides): Promise; + + callStatic: { + createProfileWithHandle( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: CallOverrides, + ): Promise<[BigNumber, BigNumber] & { profileId: BigNumber; handleId: BigNumber }>; + + getProfileWithHandleCreationPrice(overrides?: CallOverrides): Promise; + }; + + filters: {}; + + estimateGas: { + createProfileWithHandle( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + getProfileWithHandleCreationPrice(overrides?: CallOverrides): Promise; + }; + + populateTransaction: { + createProfileWithHandle( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + getProfileWithHandleCreationPrice(overrides?: CallOverrides): Promise; + }; +} diff --git a/packages/blockchain-bindings/src/types/PublicActProxy.ts b/packages/blockchain-bindings/src/types/PublicActProxy.ts index 8c72e38dd3..10d47fd4c2 100644 --- a/packages/blockchain-bindings/src/types/PublicActProxy.ts +++ b/packages/blockchain-bindings/src/types/PublicActProxy.ts @@ -1,6 +1,8 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +import type { FunctionFragment, Result } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; import type { BaseContract, BigNumber, @@ -13,14 +15,12 @@ import type { Signer, utils, } from 'ethers'; -import type { FunctionFragment, Result } from '@ethersproject/abi'; -import type { Listener, Provider } from '@ethersproject/providers'; import type { - TypedEventFilter, - TypedEvent, - TypedListener, OnEvent, PromiseOrValue, + TypedEvent, + TypedEventFilter, + TypedListener, } from './common'; export declare namespace Types { diff --git a/packages/blockchain-bindings/src/types/common.ts b/packages/blockchain-bindings/src/types/common.ts index 85be448831..ab1286c6ef 100644 --- a/packages/blockchain-bindings/src/types/common.ts +++ b/packages/blockchain-bindings/src/types/common.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ import type { Listener } from '@ethersproject/providers'; -import type { Event, EventFilter } from '@ethersproject/contracts'; +import type { Event, EventFilter } from 'ethers'; export interface TypedEvent = any, TArgsObject = any> extends Event { args: TArgsArray & TArgsObject; diff --git a/packages/blockchain-bindings/src/types/index.ts b/packages/blockchain-bindings/src/types/index.ts index 8c44870ebc..8f7c3036a6 100644 --- a/packages/blockchain-bindings/src/types/index.ts +++ b/packages/blockchain-bindings/src/types/index.ts @@ -1,11 +1,12 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +export type { Erc20 } from './Erc20'; export type { LensFollowNFT } from './LensFollowNFT'; export type { LensHub } from './LensHub'; export type { LensTokenHandleRegistry } from './LensTokenHandleRegistry'; +export type { PermissionlessCreator } from './PermissionlessCreator'; export type { PublicActProxy } from './PublicActProxy'; -export type { Erc20 } from './Erc20'; export type ChainId = number; diff --git a/packages/domain/src/use-cases/authentication/Login.ts b/packages/domain/src/use-cases/authentication/Login.ts index ed82074f8c..6d6f1798b5 100644 --- a/packages/domain/src/use-cases/authentication/Login.ts +++ b/packages/domain/src/use-cases/authentication/Login.ts @@ -8,6 +8,7 @@ import { Wallet, WalletConnectionError, } from '../../entities'; +import { IWalletFactory } from '../wallets/IWalletFactory'; import { ICredentialsWriter } from './ICredentialsWriter'; import { SessionData, profileSessionData, walletOnlySessionData } from './SessionData'; @@ -31,10 +32,6 @@ export type LoginRequest = { profileId?: ProfileId; }; -export interface IWalletFactory { - create(address: EvmAddress): Promise; -} - export interface IWritableWalletGateway { save(wallet: Wallet): Promise; } diff --git a/packages/domain/src/use-cases/authentication/__tests__/Login.spec.ts b/packages/domain/src/use-cases/authentication/__tests__/Login.spec.ts index 016d969b86..8fb1b763dc 100644 --- a/packages/domain/src/use-cases/authentication/__tests__/Login.spec.ts +++ b/packages/domain/src/use-cases/authentication/__tests__/Login.spec.ts @@ -9,14 +9,9 @@ import { WalletConnectionErrorReason, } from '../../../entities'; import { mockICredentials, mockWallet } from '../../../entities/__helpers__/mocks'; +import { IWalletFactory } from '../../wallets/IWalletFactory'; import { ICredentialsWriter } from '../ICredentialsWriter'; -import { - ICredentialsIssuer, - IWalletFactory, - ILoginPresenter, - IWritableWalletGateway, - Login, -} from '../Login'; +import { ICredentialsIssuer, ILoginPresenter, IWritableWalletGateway, Login } from '../Login'; import { profileSessionData, walletOnlySessionData } from '../SessionData'; import { mockJustWalletLoginRequest, mockProfileLoginRequest } from '../__helpers__/mocks'; diff --git a/packages/domain/src/use-cases/profile/CreateProfile.ts b/packages/domain/src/use-cases/profile/CreateProfile.ts index 059fa63b0e..8fb0a0e0a9 100644 --- a/packages/domain/src/use-cases/profile/CreateProfile.ts +++ b/packages/domain/src/use-cases/profile/CreateProfile.ts @@ -1,46 +1,46 @@ -import { PromiseResult, Url } from '@lens-protocol/shared-kernel'; - -import { NativeTransaction, TransactionKind, AnyTransactionRequestModel } from '../../entities'; -import { BroadcastingError } from '../transactions/BroadcastingError'; +import { EvmAddress } from '@lens-protocol/shared-kernel'; + +import { + AnyTransactionRequestModel, + InsufficientGasError, + PendingSigningRequestError, + TransactionKind, + UserRejectedError, + WalletConnectionError, +} from '../../entities'; +import { IPaidTransactionGateway } from '../transactions/IPaidTransactionGateway'; import { ITransactionResultPresenter } from '../transactions/ITransactionResultPresenter'; import { TransactionQueue } from '../transactions/TransactionQueue'; -import { FollowPolicyConfig } from './FollowPolicy'; +import { IWalletFactory } from '../wallets/IWalletFactory'; export type CreateProfileRequest = { - handle: string; kind: TransactionKind.CREATE_PROFILE; - followPolicy?: FollowPolicyConfig; - profileImage?: Url; + to: EvmAddress; + localName: string; + approveSignless: boolean; }; -export class DuplicatedHandleError extends Error { - name = 'DuplicatedHandleError' as const; - - constructor(handle: string) { - super(`Handle "${handle}" is already taken`); - } -} - -export interface IProfileTransactionGateway { - createProfileTransaction( - request: T, - ): PromiseResult, BroadcastingError | DuplicatedHandleError>; -} +export type ICreateProfileTransactionGateway = IPaidTransactionGateway; export type ICreateProfilePresenter = ITransactionResultPresenter< CreateProfileRequest, - BroadcastingError | DuplicatedHandleError + PendingSigningRequestError | InsufficientGasError | UserRejectedError | WalletConnectionError >; export class CreateProfile { constructor( - private readonly transactionFactory: IProfileTransactionGateway, - private readonly transactionQueue: TransactionQueue, + private readonly walletFactory: IWalletFactory, + private readonly gateway: ICreateProfileTransactionGateway, private readonly presenter: ICreateProfilePresenter, + private readonly queue: TransactionQueue, ) {} async execute(request: CreateProfileRequest) { - const result = await this.transactionFactory.createProfileTransaction(request); + const wallet = await this.walletFactory.create(request.to); + + const unsigned = await this.gateway.createUnsignedTransaction(request, wallet); + + const result = await wallet.sendTransaction(unsigned); if (result.isFailure()) { this.presenter.present(result); @@ -48,7 +48,6 @@ export class CreateProfile { } const transaction = result.value; - - await this.transactionQueue.push(transaction, this.presenter); + await this.queue.push(transaction, this.presenter); } } diff --git a/packages/domain/src/use-cases/profile/__helpers__/mocks.ts b/packages/domain/src/use-cases/profile/__helpers__/mocks.ts index b7ddc6efdc..91a972c0c8 100644 --- a/packages/domain/src/use-cases/profile/__helpers__/mocks.ts +++ b/packages/domain/src/use-cases/profile/__helpers__/mocks.ts @@ -1,24 +1,19 @@ import { faker } from '@faker-js/faker'; -import { ChainType, Result } from '@lens-protocol/shared-kernel'; +import { ChainType } from '@lens-protocol/shared-kernel'; import { - mockEvmAddress, mockDaiAmount, - mockUsdcAmount, mockData, + mockEvmAddress, + mockUsdcAmount, } from '@lens-protocol/shared-kernel/mocks'; import { mock } from 'jest-mock-extended'; import { when } from 'jest-when'; -import { TransactionKind, NftOwnershipChallenge, NativeTransaction } from '../../../entities'; +import { NftOwnershipChallenge, TransactionKind } from '../../../entities'; import { mockProfileId, mockSignature } from '../../../entities/__helpers__/mocks'; -import { BroadcastingError } from '../../transactions'; import { BlockProfilesRequest } from '../BlockProfiles'; import { ClaimHandleRequest } from '../ClaimHandle'; -import { - CreateProfileRequest, - DuplicatedHandleError, - IProfileTransactionGateway, -} from '../CreateProfile'; +import { CreateProfileRequest } from '../CreateProfile'; import { ChargeFollowConfig, FollowPolicyType } from '../FollowPolicy'; import { FreeFollowRequest, PaidFollowRequest, UnknownFollowRequest } from '../FollowProfile'; import { LinkHandleRequest } from '../LinkHandle'; @@ -34,35 +29,6 @@ import { UnlinkHandleRequest } from '../UnlinkHandle'; import { UpdateFollowPolicyRequest } from '../UpdateFollowPolicy'; import { UpdateProfileManagersRequest } from '../UpdateProfileManagers'; -export function mockCreateProfileRequest( - overrides?: Partial, -): CreateProfileRequest { - return { - handle: faker.internet.userName(), - ...overrides, - kind: TransactionKind.CREATE_PROFILE, - }; -} - -export function mockIProfileTransactionGateway({ - request, - result, -}: { - request: CreateProfileRequest; - result: Result< - NativeTransaction, - DuplicatedHandleError | BroadcastingError - >; -}) { - const profileTransactionGateway = mock(); - - when(profileTransactionGateway.createProfileTransaction) - .calledWith(request) - .mockResolvedValue(result); - - return profileTransactionGateway; -} - export function mockChargeFollowConfig( overrides?: Partial, ): ChargeFollowConfig { @@ -74,6 +40,18 @@ export function mockChargeFollowConfig( }; } +export function mockCreateProfileRequest( + overrides?: Partial, +): CreateProfileRequest { + return { + localName: faker.internet.userName(), + approveSignless: true, + to: mockEvmAddress(), + ...overrides, + kind: TransactionKind.CREATE_PROFILE, + }; +} + export function mockUpdateFollowPolicyRequest( overrides?: Partial, ): UpdateFollowPolicyRequest { diff --git a/packages/domain/src/use-cases/profile/__tests__/CreateProfile.spec.ts b/packages/domain/src/use-cases/profile/__tests__/CreateProfile.spec.ts index 80a17b1bc6..84b27002a4 100644 --- a/packages/domain/src/use-cases/profile/__tests__/CreateProfile.spec.ts +++ b/packages/domain/src/use-cases/profile/__tests__/CreateProfile.spec.ts @@ -1,85 +1,127 @@ -import { failure, success } from '@lens-protocol/shared-kernel'; +import { failure, matic, success } from '@lens-protocol/shared-kernel'; import { mock } from 'jest-mock-extended'; +import { when } from 'jest-when'; -import { NativeTransaction } from '../../../entities'; -import { MockedNativeTransaction } from '../../../entities/__helpers__/mocks'; -import { BroadcastingError } from '../../transactions'; -import { TransactionQueue } from '../../transactions/TransactionQueue'; import { - mockAnyBroadcastingError, + AnyTransactionRequestModel, + InsufficientGasError, + NativeTransaction, + PendingSigningRequestError, + UnsignedTransaction, + UserRejectedError, + Wallet, + WalletConnectionError, + WalletConnectionErrorReason, +} from '../../../entities'; +import { + MockedNativeTransaction, + mockCreateProfileRequest, + mockIPaidTransactionGateway, mockTransactionQueue, -} from '../../transactions/__helpers__/mocks'; + mockUnsignedTransaction, + mockWallet, +} from '../../../mocks'; +import { TransactionQueue } from '../../transactions'; +import { IWalletFactory } from '../../wallets/IWalletFactory'; import { CreateProfile, - CreateProfileRequest, - DuplicatedHandleError, ICreateProfilePresenter, - IProfileTransactionGateway, + ICreateProfileTransactionGateway, } from '../CreateProfile'; -import { mockCreateProfileRequest, mockIProfileTransactionGateway } from '../__helpers__/mocks'; function setupCreateProfile({ - presenter, - transactionFactory, - transactionQueue = mockTransactionQueue(), + gateway, + presenter = mock(), + queue = mockTransactionQueue(), + wallet, }: { - presenter: ICreateProfilePresenter; - transactionFactory: IProfileTransactionGateway; - transactionQueue?: TransactionQueue; + gateway: ICreateProfileTransactionGateway; + presenter?: ICreateProfilePresenter; + queue?: TransactionQueue; + wallet: Wallet; }) { - return new CreateProfile(transactionFactory, transactionQueue, presenter); + const walletFactory = mock(); + + when(walletFactory.create).calledWith(wallet.address).mockResolvedValue(wallet); + + return new CreateProfile(walletFactory, gateway, presenter, queue); } -describe(`Given an instance of the ${CreateProfile.name} interactor`, () => { - describe(`when calling the "${CreateProfile.prototype.execute.name}" method`, () => { - const request = mockCreateProfileRequest(); - const transaction = MockedNativeTransaction.fromRequest(request); +describe(`Given the ${CreateProfile.name} interactor`, () => { + const wallet = mockWallet(); + const request = mockCreateProfileRequest({ to: wallet.address }); + const unsignedTransaction = mockUnsignedTransaction(request); + const transaction = MockedNativeTransaction.fromUnsignedTransaction(unsignedTransaction); + describe(`when invoking the "${CreateProfile.prototype.execute.name}" method`, () => { it(`should: - - create a ${NativeTransaction.name} + - create an ${UnsignedTransaction.name} + - sign and broadcast the transaction with the user's wallet - queue the resulting ${NativeTransaction.name} into the ${TransactionQueue.name}`, async () => { - const presenter = mock(); - const transactionFactory = mockIProfileTransactionGateway({ + const queue = mockTransactionQueue(); + const gateway = mockIPaidTransactionGateway({ request, - result: success(transaction), + wallet, + unsignedTransaction, }); - const transactionQueue = mockTransactionQueue(); - - const createProfile = setupCreateProfile({ - transactionFactory, + const presenter = mock(); + const payTransaction = setupCreateProfile({ + gateway, presenter, - transactionQueue, + queue, + wallet, }); - await createProfile.execute(request); + when(wallet.sendTransaction) + .calledWith(unsignedTransaction) + .mockResolvedValue(success(transaction)); + + await payTransaction.execute(request); - expect(transactionQueue.push).toHaveBeenCalledWith(transaction, presenter); + expect(queue.push).toHaveBeenCalledWith(transaction, presenter); }); it.each([ { - ErrorCtor: DuplicatedHandleError, - error: new DuplicatedHandleError('bob'), + ErrorCtor: PendingSigningRequestError, + error: new PendingSigningRequestError(), }, { - ErrorCtor: BroadcastingError, - error: mockAnyBroadcastingError(), + ErrorCtor: WalletConnectionError, + error: new WalletConnectionError(WalletConnectionErrorReason.WRONG_ACCOUNT), }, - ])(`should present any $ErrorCtor might occur`, async ({ error }) => { - const transactionFactory = mockIProfileTransactionGateway({ - request, - result: failure(error), - }); - const presenter = mock(); + { + ErrorCtor: InsufficientGasError, + error: new InsufficientGasError(matic()), + }, + { + ErrorCtor: UserRejectedError, + error: new UserRejectedError('user does not want'), + }, + ])( + `should present any "$ErrorCtor.name" the transaction sending fails with`, + async ({ error }) => { + when(wallet.sendTransaction) + .calledWith(unsignedTransaction) + .mockResolvedValue(failure(error)); - const createProfile = setupCreateProfile({ - transactionFactory, - presenter, - }); + const gateway = mockIPaidTransactionGateway({ + request, + wallet, + unsignedTransaction, + }); - await createProfile.execute(request); + const presenter = mock(); + const payTransaction = setupCreateProfile({ + gateway, + presenter, + wallet, + }); - expect(presenter.present).toHaveBeenCalledWith(failure(error)); - }); + await payTransaction.execute(request); + + expect(presenter.present).toHaveBeenCalledWith(failure(error)); + }, + ); }); }); diff --git a/packages/domain/src/use-cases/transactions/IPaidTransactionGateway.ts b/packages/domain/src/use-cases/transactions/IPaidTransactionGateway.ts new file mode 100644 index 0000000000..d3ddfb9b23 --- /dev/null +++ b/packages/domain/src/use-cases/transactions/IPaidTransactionGateway.ts @@ -0,0 +1,6 @@ +import { AnyTransactionRequestModel, Wallet } from '../../entities'; +import { UnsignedTransaction } from '../../entities/Transactions'; + +export interface IPaidTransactionGateway { + createUnsignedTransaction(request: T, wallet: Wallet): Promise>; +} diff --git a/packages/domain/src/use-cases/transactions/PaidTransaction.ts b/packages/domain/src/use-cases/transactions/PaidTransaction.ts index 2d6ac5a63d..93ace2c903 100644 --- a/packages/domain/src/use-cases/transactions/PaidTransaction.ts +++ b/packages/domain/src/use-cases/transactions/PaidTransaction.ts @@ -1,20 +1,15 @@ import { + AnyTransactionRequestModel, InsufficientGasError, PendingSigningRequestError, - AnyTransactionRequestModel, UserRejectedError, - Wallet, WalletConnectionError, } from '../../entities'; -import { UnsignedTransaction } from '../../entities/Transactions'; import { ActiveWallet } from '../authentication/ActiveWallet'; +import { IPaidTransactionGateway } from './IPaidTransactionGateway'; import { ITransactionResultPresenter } from './ITransactionResultPresenter'; import { TransactionQueue } from './TransactionQueue'; -export interface IPaidTransactionGateway { - createUnsignedTransaction(request: T, wallet: Wallet): Promise>; -} - export type IPaidTransactionPresenter = ITransactionResultPresenter< T, diff --git a/packages/domain/src/use-cases/transactions/__helpers__/mocks.ts b/packages/domain/src/use-cases/transactions/__helpers__/mocks.ts index c1606aa992..6413407e15 100644 --- a/packages/domain/src/use-cases/transactions/__helpers__/mocks.ts +++ b/packages/domain/src/use-cases/transactions/__helpers__/mocks.ts @@ -6,16 +6,18 @@ import { when } from 'jest-when'; import waitFor from 'wait-for-expect'; import { + AnyTransactionRequestModel, + DataTransaction, + ISignedProtocolCall, IUnsignedProtocolCall, MetaTransaction, NativeTransaction, Nonce, - ISignedProtocolCall, - TransactionKind, - AnyTransactionRequestModel, ProtocolTransactionRequestModel, - DataTransaction, TransactionError, + TransactionKind, + UnsignedTransaction, + Wallet, } from '../../../entities'; import { mockNonce } from '../../../entities/__helpers__/mocks'; import { BroadcastingError, BroadcastingErrorReason } from '../BroadcastingError'; @@ -23,6 +25,7 @@ import { DelegableProtocolTransactionRequestModel, IDelegatedTransactionGateway, } from '../DelegableSigning'; +import { IPaidTransactionGateway } from '../IPaidTransactionGateway'; import { IMomokaRelayer, ISignedMomokaGateway } from '../SignedMomoka'; import { IMetaTransactionNonceGateway, @@ -183,3 +186,21 @@ export function mockTokenAllowanceRequest( export function mockAnyBroadcastingError() { return new BroadcastingError(BroadcastingErrorReason.UNKNOWN); } + +export function mockIPaidTransactionGateway({ + request, + wallet, + unsignedTransaction, +}: { + request: T; + wallet: Wallet; + unsignedTransaction: UnsignedTransaction; +}): IPaidTransactionGateway { + const gateway = mock>(); + + when(gateway.createUnsignedTransaction) + .calledWith(request, wallet) + .mockResolvedValue(unsignedTransaction); + + return gateway; +} diff --git a/packages/domain/src/use-cases/transactions/__tests__/PaidTransaction.spec.ts b/packages/domain/src/use-cases/transactions/__tests__/PaidTransaction.spec.ts index ef422b79fb..30e1ccb7cd 100644 --- a/packages/domain/src/use-cases/transactions/__tests__/PaidTransaction.spec.ts +++ b/packages/domain/src/use-cases/transactions/__tests__/PaidTransaction.spec.ts @@ -3,33 +3,30 @@ import { mock } from 'jest-mock-extended'; import { when } from 'jest-when'; import { + AnyTransactionRequestModel, + InsufficientGasError, NativeTransaction, + PendingSigningRequestError, UnsignedTransaction, - InsufficientGasError, + UserRejectedError, Wallet, WalletConnectionError, WalletConnectionErrorReason, - UserRejectedError, - PendingSigningRequestError, - AnyTransactionRequestModel, } from '../../../entities'; import { MockedNativeTransaction, + mockActiveWallet, mockAnyTransactionRequestModel, + mockIPaidTransactionGateway, + mockTransactionQueue, mockUnsignedTransaction, mockWallet, - mockActiveWallet, - mockIPayTransactionGateway, - mockTransactionQueue, } from '../../../mocks'; -import { - IPaidTransactionGateway, - IPaidTransactionPresenter, - PaidTransaction, -} from '../PaidTransaction'; +import { IPaidTransactionGateway } from '../IPaidTransactionGateway'; +import { IPaidTransactionPresenter, PaidTransaction } from '../PaidTransaction'; import { TransactionQueue } from '../TransactionQueue'; -function setupPayTransaction({ +function setupPaidTransaction({ gateway, presenter = mock>(), queue = mockTransactionQueue(), @@ -55,13 +52,13 @@ describe(`Given the ${PaidTransaction.name} interactor`, () => { - queue the resulting ${NativeTransaction.name} into the ${TransactionQueue.name}`, async () => { const wallet = mockWallet(); const queue = mockTransactionQueue(); - const gateway = mockIPayTransactionGateway({ + const gateway = mockIPaidTransactionGateway({ request, wallet, unsignedTransaction, }); const presenter = mock>(); - const payTransaction = setupPayTransaction({ + const payTransaction = setupPaidTransaction({ gateway, presenter, queue, @@ -102,14 +99,14 @@ describe(`Given the ${PaidTransaction.name} interactor`, () => { .calledWith(unsignedTransaction) .mockResolvedValue(failure(error)); - const gateway = mockIPayTransactionGateway({ + const gateway = mockIPaidTransactionGateway({ request, wallet, unsignedTransaction, }); const presenter = mock>(); - const payTransaction = setupPayTransaction({ + const payTransaction = setupPaidTransaction({ gateway, presenter, wallet, diff --git a/packages/domain/src/use-cases/transactions/index.ts b/packages/domain/src/use-cases/transactions/index.ts index 8da88bad01..445c8ec2a8 100644 --- a/packages/domain/src/use-cases/transactions/index.ts +++ b/packages/domain/src/use-cases/transactions/index.ts @@ -1,10 +1,11 @@ +export * from './BroadcastingError'; export * from './DelegableSigning'; export * from './IGenericResultPresenter'; +export * from './IPaidTransactionGateway'; +export * from './ITransactionResultPresenter'; +export * from './PaidTransaction'; export * from './SignedMomoka'; export * from './SignedOnChain'; export * from './SupportedTransactionRequest'; -export * from './TransactionQueue'; -export * from './BroadcastingError'; -export * from './PaidTransaction'; -export * from './ITransactionResultPresenter'; export * from './TokenAllowance'; +export * from './TransactionQueue'; diff --git a/packages/domain/src/use-cases/wallets/IWalletFactory.ts b/packages/domain/src/use-cases/wallets/IWalletFactory.ts new file mode 100644 index 0000000000..ac36494dbb --- /dev/null +++ b/packages/domain/src/use-cases/wallets/IWalletFactory.ts @@ -0,0 +1,7 @@ +import { EvmAddress } from '@lens-protocol/shared-kernel'; + +import { Wallet } from '../../entities'; + +export interface IWalletFactory { + create(address: EvmAddress): Promise; +} diff --git a/packages/domain/src/use-cases/wallets/__helpers__/mocks.ts b/packages/domain/src/use-cases/wallets/__helpers__/mocks.ts index c9a8c8ac31..8bb5542404 100644 --- a/packages/domain/src/use-cases/wallets/__helpers__/mocks.ts +++ b/packages/domain/src/use-cases/wallets/__helpers__/mocks.ts @@ -3,8 +3,7 @@ import { mockDaiAmount, mockEvmAddress } from '@lens-protocol/shared-kernel/mock import { mock } from 'jest-mock-extended'; import { when } from 'jest-when'; -import { Wallet, AnyTransactionRequestModel, UnsignedTransaction } from '../../../entities'; -import { IPaidTransactionGateway } from '../../transactions/PaidTransaction'; +import { Wallet } from '../../../entities'; import { IBalanceGateway, ITokenGateway, @@ -72,21 +71,3 @@ export function mockTokeAvailability({ return tokenAvailability; } - -export function mockIPayTransactionGateway({ - request, - wallet, - unsignedTransaction, -}: { - request: T; - wallet: Wallet; - unsignedTransaction: UnsignedTransaction; -}): IPaidTransactionGateway { - const gateway = mock>(); - - when(gateway.createUnsignedTransaction) - .calledWith(request, wallet) - .mockResolvedValue(unsignedTransaction); - - return gateway; -} diff --git a/packages/domain/src/use-cases/wallets/index.ts b/packages/domain/src/use-cases/wallets/index.ts index 8cdceef404..6905bf5c31 100644 --- a/packages/domain/src/use-cases/wallets/index.ts +++ b/packages/domain/src/use-cases/wallets/index.ts @@ -1,2 +1,3 @@ -export * from './TokenAvailability'; +export * from './IWalletFactory'; export * from './InviteWallets'; +export * from './TokenAvailability'; diff --git a/packages/react-web/src/inbox/adapters/SignerAdapter.ts b/packages/react-web/src/inbox/adapters/SignerAdapter.ts index 0daebfbcbe..bbe78b4adb 100644 --- a/packages/react-web/src/inbox/adapters/SignerAdapter.ts +++ b/packages/react-web/src/inbox/adapters/SignerAdapter.ts @@ -8,7 +8,7 @@ import type { ActiveWallet } from '@lens-protocol/domain/use-cases/authenticatio import { SignArbitraryMessage } from '@lens-protocol/domain/use-cases/inbox'; import { IEquatableError } from '@lens-protocol/react'; import { Deferred, Result } from '@lens-protocol/shared-kernel'; -import { Signer } from '@xmtp/react-sdk'; +import { Signer as XmtpSigner } from '@xmtp/react-sdk'; class PromiseResultPresenter { private deferredResult = new Deferred>(); @@ -22,7 +22,7 @@ class PromiseResultPresenter { } } -export class SignerAdapter implements Signer { +export class SignerAdapter implements XmtpSigner { constructor(private activeWallet: ActiveWallet) {} async getAddress() { diff --git a/packages/react/src/environments.ts b/packages/react/src/environments.ts index 9ec2fe75df..f71eee3b6e 100644 --- a/packages/react/src/environments.ts +++ b/packages/react/src/environments.ts @@ -42,6 +42,9 @@ export type EnvironmentConfig = { backend: URL; chains: ChainConfigRegistry; timings: TransactionObserverTimings; + contracts: { + permissionlessCreator: string; + }; handleResolver: ProfileHandleResolver; snapshot: SnapshotConfig; // gated: GatedEnvironments.EnvironmentConfig; @@ -69,6 +72,9 @@ export const production: EnvironmentConfig = { maxIndexingWaitTime: 120000, maxMiningWaitTime: 60000, }, + contracts: { + permissionlessCreator: '0x42b302BBB4fA27c21d32EdF602E4e2aA65746999', + }, handleResolver: (localName) => `lens/${localName}`, snapshot: { hub: 'https://hub.snapshot.org/graphql' as URL, @@ -100,6 +106,9 @@ export const development: EnvironmentConfig = { maxIndexingWaitTime: 240000, maxMiningWaitTime: 120000, }, + contracts: { + permissionlessCreator: '0x42b302BBB4fA27c21d32EdF602E4e2aA65746999', + }, handleResolver: (localName) => `test/${localName}`, snapshot: { hub: 'https://testnet.snapshot.org/graphql' as URL, @@ -124,6 +133,9 @@ export const staging: EnvironmentConfig = { maxIndexingWaitTime: 240000, maxMiningWaitTime: 2400000, }, + contracts: { + permissionlessCreator: '0x42b302BBB4fA27c21d32EdF602E4e2aA65746999', + }, handleResolver: (localName) => `test/${localName}`, snapshot: { hub: 'https://testnet.snapshot.org' as URL, diff --git a/packages/react/src/misc/useValidateHandle.ts b/packages/react/src/misc/useValidateHandle.ts index 33be3c5a50..a1d622817d 100644 --- a/packages/react/src/misc/useValidateHandle.ts +++ b/packages/react/src/misc/useValidateHandle.ts @@ -17,14 +17,23 @@ export class HandleNotAvailableError extends Error { export class InvalidHandleError extends Error { name = 'InvalidHandleError' as const; - constructor(handle: string) { - super(`Handle "${handle}" is not valid`); + constructor(localName: string) { + super(`Handle "${localName}" is not valid`); } } export type ValidateHandleRequest = { - /** Just the localname portion of a new handle */ - handle: string; + /** + * Just the local-name portion of the desired Handle. + * + * @example + * ```ts + * // lens/wagmi + * + * const localName = 'wagmi'; + * ``` + */ + localName: string; }; /** @@ -42,7 +51,7 @@ export type ValidateHandleRequest = { * const { called, error, loading, execute } = useValidateHandle(); * * const callback = async () => { - * const result = await execute({ handle: 'wagmi' }); + * const result = await execute({ localName: 'wagmi' }); * * if (result.isFailure()) { * console.error(result.error.message); // handle not valid or already taken @@ -74,14 +83,15 @@ export function useValidateHandle(): UseDeferredTask< async ( request, ): PromiseResult => { - if (!isValidHandle(request.handle)) { - return failure(new InvalidHandleError(request.handle)); + if (!isValidHandle(request.localName)) { + return failure(new InvalidHandleError(request.localName)); } + const handle = environment.handleResolver(request.localName); const { data, error } = await fetch({ variables: { request: { - handle: environment.handleResolver(request.handle), + handle: handle, }, }, }); @@ -93,7 +103,7 @@ export function useValidateHandle(): UseDeferredTask< invariant(data, 'Data must be defined'); if (data.result) { - return failure(new HandleNotAvailableError(request.handle)); + return failure(new HandleNotAvailableError(handle)); } return success(); diff --git a/packages/react/src/transactions/adapters/AbstractContractCallGateway.ts b/packages/react/src/transactions/adapters/AbstractContractCallGateway.ts index 063910b5c6..a05f2869b1 100644 --- a/packages/react/src/transactions/adapters/AbstractContractCallGateway.ts +++ b/packages/react/src/transactions/adapters/AbstractContractCallGateway.ts @@ -1,11 +1,12 @@ -import { TransactionRequest } from '@ethersproject/providers'; +import { JsonRpcProvider } from '@ethersproject/providers'; import { bigNumber } from '@lens-protocol/blockchain-bindings'; -import { Wallet, UnsignedTransaction } from '@lens-protocol/domain/entities'; +import { UnsignedTransaction, Wallet } from '@lens-protocol/domain/entities'; import { AnyTransactionRequest, IPaidTransactionGateway, } from '@lens-protocol/domain/use-cases/transactions'; import { Amount, ChainType, Data, EvmAddress } from '@lens-protocol/shared-kernel'; +import { BigNumberish, BytesLike } from 'ethers'; import { v4 } from 'uuid'; import { LensConfig } from '../../config'; @@ -13,11 +14,28 @@ import { ITransactionRequest } from '../../wallet/adapters/ConcreteWallet'; import { IProviderFactory } from '../../wallet/adapters/IProviderFactory'; import { Eip1559GasPriceEstimator, TransactionExecutionSpeed } from './Eip1559GasPriceEstimator'; +export type Eip1559TransactionRequest = { + to: string; + from: string; + nonce?: BigNumberish; + + gasLimit?: BigNumberish; + + data: BytesLike; + value?: BigNumberish; + chainId?: number; + + type: 2; + + maxPriorityFeePerGas?: BigNumberish; + maxFeePerGas?: BigNumberish; +}; + export class UnsignedContractCallTransaction extends UnsignedTransaction implements ITransactionRequest { - constructor(request: TRequest, readonly transactionRequest: TransactionRequest) { + constructor(request: TRequest, readonly transactionRequest: Eip1559TransactionRequest) { super(v4(), ChainType.POLYGON, request); } } @@ -25,12 +43,16 @@ export class UnsignedContractCallTransaction implements IPaidTransactionGateway { - constructor(readonly config: LensConfig, private readonly providerFactory: IProviderFactory) {} + constructor( + protected readonly config: LensConfig, + private readonly providerFactory: IProviderFactory, + ) {} async createUnsignedTransaction( request: TRequest, @@ -40,14 +62,15 @@ export abstract class AbstractContractCallGateway Amount.matic(value)); + const gasEstimator = new Eip1559GasPriceEstimator(provider, (v) => Amount.matic(v)); const gasPriceEstimate = await gasEstimator.estimate(TransactionExecutionSpeed.FAST); - const transactionRequest = { + const transactionRequest: Eip1559TransactionRequest = { to: contractAddress, from: wallet.address, data: encodedData, @@ -71,10 +95,14 @@ export abstract class AbstractContractCallGateway; + protected abstract createCallDetails( + request: TRequest, + provider: JsonRpcProvider, + ): Promise; } diff --git a/packages/react/src/transactions/adapters/ApproveTransactionGateway.ts b/packages/react/src/transactions/adapters/ApproveTransactionGateway.ts index 86415a2a80..1dd0b888fb 100644 --- a/packages/react/src/transactions/adapters/ApproveTransactionGateway.ts +++ b/packages/react/src/transactions/adapters/ApproveTransactionGateway.ts @@ -1,19 +1,15 @@ import { BigNumber } from '@ethersproject/bignumber'; import { MaxUint256 } from '@ethersproject/constants'; -import { erc20, bigNumber } from '@lens-protocol/blockchain-bindings'; +import { bigNumber, erc20 } from '@lens-protocol/blockchain-bindings'; import { IPaidTransactionGateway, TokenAllowanceLimit, TokenAllowanceRequest, } from '@lens-protocol/domain/use-cases/transactions'; -import { Amount, BigDecimal, CryptoNativeAsset, Data } from '@lens-protocol/shared-kernel'; +import { Data } from '@lens-protocol/shared-kernel'; import { AbstractContractCallGateway, ContractCallDetails } from './AbstractContractCallGateway'; -export type CryptoNativeAmountFactory = ( - value: BigDecimal, -) => Amount; - function resolveApproveAmount(request: TokenAllowanceRequest): BigNumber { switch (request.limit) { case TokenAllowanceLimit.EXACT: @@ -27,7 +23,7 @@ export class ApproveTransactionGateway extends AbstractContractCallGateway implements IPaidTransactionGateway { - protected async createEncodedData(request: TokenAllowanceRequest): Promise { + protected async createCallDetails(request: TokenAllowanceRequest): Promise { const contract = erc20(request.amount.asset.address); const amount = resolveApproveAmount(request); diff --git a/packages/react/src/transactions/adapters/NewProfilePresenter.ts b/packages/react/src/transactions/adapters/ClaimProfilePresenter.ts similarity index 98% rename from packages/react/src/transactions/adapters/NewProfilePresenter.ts rename to packages/react/src/transactions/adapters/ClaimProfilePresenter.ts index 775e6c90e4..5e4a3aa036 100644 --- a/packages/react/src/transactions/adapters/NewProfilePresenter.ts +++ b/packages/react/src/transactions/adapters/ClaimProfilePresenter.ts @@ -9,10 +9,10 @@ import { import { TransactionData } from '@lens-protocol/domain/use-cases/transactions'; import { Deferred, - failure, Failure, - invariant, Result, + failure, + invariant, success, } from '@lens-protocol/shared-kernel'; @@ -22,7 +22,7 @@ import { AsyncTransactionResult } from './AsyncTransactionResult'; type EarlyFailureError = ClaimHandleError; -export class NewProfilePresenter +export class ClaimProfilePresenter implements IClaimHandlePresenter { private deferredResult = new Deferred>(); diff --git a/packages/react/src/transactions/adapters/CreateProfilePresenter.ts b/packages/react/src/transactions/adapters/CreateProfilePresenter.ts new file mode 100644 index 0000000000..eecaefe663 --- /dev/null +++ b/packages/react/src/transactions/adapters/CreateProfilePresenter.ts @@ -0,0 +1,76 @@ +import { Profile } from '@lens-protocol/api-bindings'; +import { + InsufficientGasError, + PendingSigningRequestError, + TransactionError, + UserRejectedError, + WalletConnectionError, +} from '@lens-protocol/domain/entities'; +import { + CreateProfileRequest, + ICreateProfilePresenter, +} from '@lens-protocol/domain/use-cases/profile'; +import { TransactionData } from '@lens-protocol/domain/use-cases/transactions'; +import { + Deferred, + Failure, + Result, + failure, + invariant, + success, +} from '@lens-protocol/shared-kernel'; + +import { ProfileHandleResolver } from '../../environments'; +import { IProfileCacheManager } from '../../profile/adapters/IProfileCacheManager'; +import { AsyncTransactionResult } from './AsyncTransactionResult'; + +type EarlyFailureError = + | PendingSigningRequestError + | InsufficientGasError + | UserRejectedError + | WalletConnectionError; + +export class CreateProfilePresenter implements ICreateProfilePresenter { + private deferredResult = new Deferred>(); + + private earlyFailure: Failure | null = null; + + constructor( + private readonly profileCacheManager: IProfileCacheManager, + private readonly fullHandleResolver: ProfileHandleResolver, + ) {} + + async present( + result: Result, EarlyFailureError | TransactionError>, + ) { + if (result.isFailure()) { + if (!(result.error instanceof TransactionError)) { + this.earlyFailure = failure(result.error); + return; + } + + this.deferredResult.resolve(failure(result.error)); + return; + } + + const profile = await this.profileCacheManager.fetchProfileByHandle( + this.fullHandleResolver(result.value.request.localName), + ); + + invariant(profile, 'Profile not found'); + + this.deferredResult.resolve(success(profile)); + } + + asResult(): Result, EarlyFailureError> { + if (this.earlyFailure) { + return this.earlyFailure; + } + + return success({ + waitForCompletion: async () => { + return this.deferredResult.promise; + }, + }); + } +} diff --git a/packages/react/src/transactions/adapters/CreateProfileTransactionGateway.ts b/packages/react/src/transactions/adapters/CreateProfileTransactionGateway.ts new file mode 100644 index 0000000000..ad2b5b6924 --- /dev/null +++ b/packages/react/src/transactions/adapters/CreateProfileTransactionGateway.ts @@ -0,0 +1,63 @@ +import { JsonRpcProvider } from '@ethersproject/providers'; +import { + GenerateLensApiRelayAddressData, + GenerateLensApiRelayAddressDocument, + SafeApolloClient, +} from '@lens-protocol/api-bindings'; +import { permissionlessCreator } from '@lens-protocol/blockchain-bindings'; +import { CreateProfileRequest } from '@lens-protocol/domain/use-cases/profile'; +import { Data, EvmAddress } from '@lens-protocol/shared-kernel'; + +import { LensConfig } from '../../config'; +import { IProviderFactory } from '../../wallet/adapters/IProviderFactory'; +import { AbstractContractCallGateway, ContractCallDetails } from './AbstractContractCallGateway'; + +export class CreateProfileTransactionGateway extends AbstractContractCallGateway { + constructor( + private apolloClient: SafeApolloClient, + config: LensConfig, + providerFactory: IProviderFactory, + ) { + super(config, providerFactory); + } + + protected async createCallDetails( + request: CreateProfileRequest, + provider: JsonRpcProvider, + ): Promise { + const delegatedExecutors = await this.resolveDelegatedExecutors(request); + + const contract = permissionlessCreator( + this.config.environment.contracts.permissionlessCreator, + provider, + ); + + const encodedData = contract.interface.encodeFunctionData('createProfileWithHandle', [ + { + to: request.to, + followModule: '0x0000000000000000000000000000000000000000', + followModuleInitData: '0x', + }, + request.localName, + delegatedExecutors, + ]); + + return { + contractAddress: this.config.environment.contracts.permissionlessCreator, + encodedData: encodedData as Data, + value: await contract.getProfileWithHandleCreationPrice(), + }; + } + + private async resolveDelegatedExecutors(request: CreateProfileRequest): Promise { + if (!request.approveSignless) { + return []; + } + + const { data } = await this.apolloClient.query({ + query: GenerateLensApiRelayAddressDocument, + }); + + return [data.result]; + } +} diff --git a/packages/react/src/transactions/adapters/OpenActionGateway.ts b/packages/react/src/transactions/adapters/OpenActionGateway.ts index 1da590f67b..af7952110b 100644 --- a/packages/react/src/transactions/adapters/OpenActionGateway.ts +++ b/packages/react/src/transactions/adapters/OpenActionGateway.ts @@ -1,16 +1,16 @@ +import * as gql from '@lens-protocol/api-bindings'; import { - SafeApolloClient, - omitTypename, - isPublicationId, - RelaySuccess, ActOnOpenActionData, - ActOnOpenActionVariables, ActOnOpenActionDocument, + ActOnOpenActionVariables, LegacyCollectData, - LegacyCollectVariables, LegacyCollectDocument, + LegacyCollectVariables, + RelaySuccess, + SafeApolloClient, + isPublicationId, + omitTypename, } from '@lens-protocol/api-bindings'; -import * as gql from '@lens-protocol/api-bindings'; import { lensHub, publicActProxy } from '@lens-protocol/blockchain-bindings'; import { NativeTransaction, Nonce } from '@lens-protocol/domain/entities'; import { @@ -26,7 +26,6 @@ import { import { BroadcastingError, IDelegatedTransactionGateway, - IPaidTransactionGateway, ISignedOnChainGateway, } from '@lens-protocol/domain/use-cases/transactions'; import { ChainType, Data, PromiseResult, success } from '@lens-protocol/shared-kernel'; @@ -48,8 +47,7 @@ export class OpenActionGateway extends AbstractContractCallGateway implements ISignedOnChainGateway, - IDelegatedTransactionGateway, - IPaidTransactionGateway + IDelegatedTransactionGateway { constructor( config: LensConfig, @@ -88,7 +86,7 @@ export class OpenActionGateway return this.createOpenActionUnsignedProtocolCall(request, nonce); } - protected override async createEncodedData( + protected override async createCallDetails( request: OpenActionRequest, ): Promise { if (request.public) { diff --git a/packages/react/src/transactions/adapters/__tests__/ApproveTransactionGateway.spec.ts b/packages/react/src/transactions/adapters/__tests__/ApproveTransactionGateway.spec.ts index e512b9e715..9e15371754 100644 --- a/packages/react/src/transactions/adapters/__tests__/ApproveTransactionGateway.spec.ts +++ b/packages/react/src/transactions/adapters/__tests__/ApproveTransactionGateway.spec.ts @@ -36,7 +36,7 @@ describe(`Given an instance of the ${ApproveTransactionGateway.name}`, () => { const wallet = mockWallet(); describe(`when creating an approve transaction for an exact amount`, () => { - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const request = mockTokenAllowanceRequest({ limit: TokenAllowanceLimit.EXACT, }); @@ -72,7 +72,7 @@ describe(`Given an instance of the ${ApproveTransactionGateway.name}`, () => { }); describe(`when creating an infinite approve transaction`, () => { - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const request = mockTokenAllowanceRequest({ limit: TokenAllowanceLimit.INFINITE, }); diff --git a/packages/react/src/transactions/adapters/__tests__/CreateProfileTransactionGateway.spec.ts b/packages/react/src/transactions/adapters/__tests__/CreateProfileTransactionGateway.spec.ts new file mode 100644 index 0000000000..653383b2bb --- /dev/null +++ b/packages/react/src/transactions/adapters/__tests__/CreateProfileTransactionGateway.spec.ts @@ -0,0 +1,120 @@ +/** + * @jest-environment node + */ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { MockedResponse } from '@apollo/client/testing'; +import { faker } from '@faker-js/faker'; +import { + mockGenerateLensAPIRelayAddressResponse, + mockLensApolloClient, +} from '@lens-protocol/api-bindings/mocks'; +import { permissionlessCreator } from '@lens-protocol/blockchain-bindings'; +import { mockCreateProfileRequest, mockWallet } from '@lens-protocol/domain/mocks'; +import { ChainType } from '@lens-protocol/shared-kernel'; +import { mockEvmAddress } from '@lens-protocol/shared-kernel/mocks'; +import { deployMockContract } from 'ethereum-waffle'; +import { BigNumber, Wallet, utils } from 'ethers'; +import { mock } from 'jest-mock-extended'; + +import { LensConfig } from '../../../config'; +import { staging } from '../../../environments'; +import { mockIProviderFactory } from '../../../wallet/adapters/__helpers__/mocks'; +import { UnsignedContractCallTransaction } from '../AbstractContractCallGateway'; +import { CreateProfileTransactionGateway } from '../CreateProfileTransactionGateway'; +import { mockJsonRpcProvider } from '../__helpers__/mocks'; + +const contract = permissionlessCreator(staging.contracts.permissionlessCreator); + +async function setupTestScenario(mocks: MockedResponse[] = []) { + const apolloClient = mockLensApolloClient(mocks); + + const provider = await mockJsonRpcProvider(); + const providerFactory = mockIProviderFactory({ + chainType: ChainType.POLYGON, + provider, + }); + + const [deployer] = provider.getWallets() as [Wallet]; + + const mockContract = await deployMockContract( + deployer, + contract.interface.fragments as unknown as string[], + { + address: staging.contracts.permissionlessCreator, + }, + ); + + // eslint-disable-next-line @typescript-eslint/await-thenable + await mockContract.mock.getProfileWithHandleCreationPrice!.returns(utils.parseEther('10')); + + const config = mock({ environment: staging }); + + return new CreateProfileTransactionGateway(apolloClient, config, providerFactory); +} + +describe(`Given an instance of the ${CreateProfileTransactionGateway.name}`, () => { + const relayer = mockEvmAddress(); + const wallet = mockWallet(); + const localName = faker.internet.userName(); + + describe.each([ + { + description: '', + request: mockCreateProfileRequest({ to: wallet.address, localName }), + params: [ + { + to: wallet.address, + followModule: '0x0000000000000000000000000000000000000000', + followModuleInitData: '0x', + }, + localName, + [relayer], + ] as any, + }, + { + description: 'with signless disabled', + request: mockCreateProfileRequest({ to: wallet.address, localName, approveSignless: false }), + params: [ + { + to: wallet.address, + followModule: '0x0000000000000000000000000000000000000000', + followModuleInitData: '0x', + }, + localName, + [], + ] as any, + }, + ])(`when creating an new Profile $description`, ({ request, params }) => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { + const gateway = await setupTestScenario([ + mockGenerateLensAPIRelayAddressResponse({ + address: relayer, + }), + ]); + + const unsignedTransaction = await gateway.createUnsignedTransaction(request, wallet); + + const expectedCall = permissionlessCreator( + staging.contracts.permissionlessCreator, + ).interface.encodeFunctionData('createProfileWithHandle', params); + + expect(unsignedTransaction).toBeInstanceOf(UnsignedContractCallTransaction); + expect(unsignedTransaction).toEqual({ + chainType: ChainType.POLYGON, + id: expect.any(String), + request, + transactionRequest: expect.objectContaining({ + data: expectedCall, + gasLimit: expect.any(BigNumber), + maxFeePerGas: expect.any(BigNumber), + maxPriorityFeePerGas: expect.any(BigNumber), + from: wallet.address, + type: 2, // EIP-1559 + value: utils.parseEther('10'), + }), + }); + }); + }); +}); diff --git a/packages/react/src/transactions/adapters/__tests__/OpenActionGateway.spec.ts b/packages/react/src/transactions/adapters/__tests__/OpenActionGateway.spec.ts index 183c53eb03..16b3268ecb 100644 --- a/packages/react/src/transactions/adapters/__tests__/OpenActionGateway.spec.ts +++ b/packages/react/src/transactions/adapters/__tests__/OpenActionGateway.spec.ts @@ -290,7 +290,7 @@ describe(`Given an instance of ${OpenActionGateway.name}`, () => { ])(`when creating an ${UnsignedTransaction.name}<$name>`, ({ request, response }) => { const wallet = mockWallet(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([response]); @@ -486,7 +486,7 @@ describe(`Given an instance of ${OpenActionGateway.name}`, () => { const wallet = mockWallet(); const data = mockCreateActOnOpenActionTypedDataData(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ diff --git a/packages/react/src/transactions/adapters/profiles/BlockProfilesGateway.ts b/packages/react/src/transactions/adapters/profiles/BlockProfilesGateway.ts index 7fb211f3a8..7748468f09 100644 --- a/packages/react/src/transactions/adapters/profiles/BlockProfilesGateway.ts +++ b/packages/react/src/transactions/adapters/profiles/BlockProfilesGateway.ts @@ -95,7 +95,7 @@ export class BlockProfilesGateway return success(data.result); } - protected async createEncodedData(request: BlockProfilesRequest): Promise { + protected async createCallDetails(request: BlockProfilesRequest): Promise { const result = await this.createTypedData(request); return this.createSetBlockStatusCallDetails(result); } diff --git a/packages/react/src/transactions/adapters/profiles/FollowProfileGateway.ts b/packages/react/src/transactions/adapters/profiles/FollowProfileGateway.ts index f3166417eb..612ec69781 100644 --- a/packages/react/src/transactions/adapters/profiles/FollowProfileGateway.ts +++ b/packages/react/src/transactions/adapters/profiles/FollowProfileGateway.ts @@ -1,17 +1,17 @@ import { + CreateFollowBroadcastItemResult, CreateFollowTypedDataData, CreateFollowTypedDataDocument, CreateFollowTypedDataVariables, Follow, - FollowRequest as TypedDataFollowRequest, - omitTypename, - RelaySuccess, - SafeApolloClient, - CreateFollowBroadcastItemResult, FollowData, - FollowVariables, FollowDocument, FollowLensManagerRequest, + FollowVariables, + RelaySuccess, + SafeApolloClient, + FollowRequest as TypedDataFollowRequest, + omitTypename, } from '@lens-protocol/api-bindings'; import { lensHub } from '@lens-protocol/blockchain-bindings'; import { NativeTransaction, Nonce } from '@lens-protocol/domain/entities'; @@ -25,7 +25,6 @@ import { import { BroadcastingError, IDelegatedTransactionGateway, - IPaidTransactionGateway, ISignedOnChainGateway, } from '@lens-protocol/domain/use-cases/transactions'; import { ChainType, Data, PromiseResult, success } from '@lens-protocol/shared-kernel'; @@ -74,10 +73,7 @@ function resolveProfileFollow(request: FollowRequest): Follow[] { export class FollowProfileGateway extends AbstractContractCallGateway - implements - IDelegatedTransactionGateway, - ISignedOnChainGateway, - IPaidTransactionGateway + implements IDelegatedTransactionGateway, ISignedOnChainGateway { constructor( config: LensConfig, @@ -119,7 +115,7 @@ export class FollowProfileGateway }); } - protected override async createEncodedData(request: FollowRequest): Promise { + protected override async createCallDetails(request: FollowRequest): Promise { const result = await this.createTypedData(request); return this.createFollowCallDetails(result); } diff --git a/packages/react/src/transactions/adapters/profiles/LinkHandleGateway.ts b/packages/react/src/transactions/adapters/profiles/LinkHandleGateway.ts index b049018984..f738e68a46 100644 --- a/packages/react/src/transactions/adapters/profiles/LinkHandleGateway.ts +++ b/packages/react/src/transactions/adapters/profiles/LinkHandleGateway.ts @@ -74,7 +74,7 @@ export class LinkHandleGateway }); } - protected async createEncodedData(request: LinkHandleRequest): Promise { + protected async createCallDetails(request: LinkHandleRequest): Promise { const result = await this.createTypedData(request); return this.createLinkCallDetails(result); } diff --git a/packages/react/src/transactions/adapters/profiles/ProfileMetadataGateway.ts b/packages/react/src/transactions/adapters/profiles/ProfileMetadataGateway.ts index dab0971a7e..2e1b39f1ec 100644 --- a/packages/react/src/transactions/adapters/profiles/ProfileMetadataGateway.ts +++ b/packages/react/src/transactions/adapters/profiles/ProfileMetadataGateway.ts @@ -16,7 +16,6 @@ import { SetProfileMetadataRequest } from '@lens-protocol/domain/use-cases/profi import { BroadcastingError, IDelegatedTransactionGateway, - IPaidTransactionGateway, ISignedOnChainGateway, } from '@lens-protocol/domain/use-cases/transactions'; import { ChainType, Data, PromiseResult, success } from '@lens-protocol/shared-kernel'; @@ -33,8 +32,7 @@ export class ProfileMetadataGateway extends AbstractContractCallGateway implements IDelegatedTransactionGateway, - ISignedOnChainGateway, - IPaidTransactionGateway + ISignedOnChainGateway { constructor( config: LensConfig, @@ -79,7 +77,7 @@ export class ProfileMetadataGateway }); } - protected override async createEncodedData( + protected override async createCallDetails( request: SetProfileMetadataRequest, ): Promise { const result = await this.createTypedData(request); diff --git a/packages/react/src/transactions/adapters/profiles/UnblockProfilesGateway.ts b/packages/react/src/transactions/adapters/profiles/UnblockProfilesGateway.ts index d25c949837..d5611fc08c 100644 --- a/packages/react/src/transactions/adapters/profiles/UnblockProfilesGateway.ts +++ b/packages/react/src/transactions/adapters/profiles/UnblockProfilesGateway.ts @@ -76,7 +76,7 @@ export class UnblockProfilesGateway }); } - protected async createEncodedData(request: UnblockProfilesRequest): Promise { + protected async createCallDetails(request: UnblockProfilesRequest): Promise { const result = await this.createTypedData(request); return this.createSetBlockStatusCallDetails(result); } diff --git a/packages/react/src/transactions/adapters/profiles/UnfollowProfileGateway.ts b/packages/react/src/transactions/adapters/profiles/UnfollowProfileGateway.ts index c660d24c49..3b4b52d9c4 100644 --- a/packages/react/src/transactions/adapters/profiles/UnfollowProfileGateway.ts +++ b/packages/react/src/transactions/adapters/profiles/UnfollowProfileGateway.ts @@ -72,7 +72,7 @@ export class UnfollowProfileGateway }); } - protected async createEncodedData(request: UnfollowRequest): Promise { + protected async createCallDetails(request: UnfollowRequest): Promise { const result = await this.createTypedData(request); return this.createUnfollowCallData(result); } diff --git a/packages/react/src/transactions/adapters/profiles/UnlinkHandleGateway.ts b/packages/react/src/transactions/adapters/profiles/UnlinkHandleGateway.ts index 4ac13f801f..bb8ae69f80 100644 --- a/packages/react/src/transactions/adapters/profiles/UnlinkHandleGateway.ts +++ b/packages/react/src/transactions/adapters/profiles/UnlinkHandleGateway.ts @@ -74,7 +74,7 @@ export class UnlinkHandleGateway }); } - protected async createEncodedData(request: UnlinkHandleRequest): Promise { + protected async createCallDetails(request: UnlinkHandleRequest): Promise { const result = await this.createTypedData(request); return this.createUnlinkCallData(result); } diff --git a/packages/react/src/transactions/adapters/profiles/UpdateFollowPolicyGateway.ts b/packages/react/src/transactions/adapters/profiles/UpdateFollowPolicyGateway.ts index 142cf9dcae..d592d2fdb7 100644 --- a/packages/react/src/transactions/adapters/profiles/UpdateFollowPolicyGateway.ts +++ b/packages/react/src/transactions/adapters/profiles/UpdateFollowPolicyGateway.ts @@ -17,7 +17,6 @@ import { UpdateFollowPolicyRequest } from '@lens-protocol/domain/use-cases/profi import { BroadcastingError, IDelegatedTransactionGateway, - IPaidTransactionGateway, ISignedOnChainGateway, } from '@lens-protocol/domain/use-cases/transactions'; import { ChainType, Data, PromiseResult, success } from '@lens-protocol/shared-kernel'; @@ -34,8 +33,7 @@ export class UpdateFollowPolicyGateway extends AbstractContractCallGateway implements IDelegatedTransactionGateway, - ISignedOnChainGateway, - IPaidTransactionGateway + ISignedOnChainGateway { constructor( config: LensConfig, @@ -77,7 +75,7 @@ export class UpdateFollowPolicyGateway }); } - protected override async createEncodedData( + protected override async createCallDetails( request: UpdateFollowPolicyRequest, ): Promise { const result = await this.createTypedData(request); diff --git a/packages/react/src/transactions/adapters/profiles/UpdateProfileManagersGateway.ts b/packages/react/src/transactions/adapters/profiles/UpdateProfileManagersGateway.ts index c1fedfba67..c6fe473bf5 100644 --- a/packages/react/src/transactions/adapters/profiles/UpdateProfileManagersGateway.ts +++ b/packages/react/src/transactions/adapters/profiles/UpdateProfileManagersGateway.ts @@ -43,7 +43,7 @@ export class UpdateProfileManagersGateway }); } - protected async createEncodedData( + protected async createCallDetails( request: UpdateProfileManagersRequest, ): Promise { const result = await this.createTypedData(request); diff --git a/packages/react/src/transactions/adapters/profiles/__tests__/BlockProfilesGateway.spec.ts b/packages/react/src/transactions/adapters/profiles/__tests__/BlockProfilesGateway.spec.ts index 20d45f0aa9..938d19a476 100644 --- a/packages/react/src/transactions/adapters/profiles/__tests__/BlockProfilesGateway.spec.ts +++ b/packages/react/src/transactions/adapters/profiles/__tests__/BlockProfilesGateway.spec.ts @@ -53,7 +53,7 @@ describe(`Given an instance of ${BlockProfilesGateway.name}`, () => { const request = mockBlockProfilesRequest(); const data = mockBlockProfilesTypedDataData(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockBlockProfilesTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/profiles/__tests__/FollowProfileGateway.spec.ts b/packages/react/src/transactions/adapters/profiles/__tests__/FollowProfileGateway.spec.ts index 1fa5b67dd3..82211e1b30 100644 --- a/packages/react/src/transactions/adapters/profiles/__tests__/FollowProfileGateway.spec.ts +++ b/packages/react/src/transactions/adapters/profiles/__tests__/FollowProfileGateway.spec.ts @@ -3,18 +3,18 @@ */ import { SafeApolloClient } from '@lens-protocol/api-bindings'; import { - mockLensApolloClient, - mockRelaySuccessFragment, + mockCreateFollowTypedDataData, mockCreateFollowTypedDataResponse, mockFollowResponse, - mockCreateFollowTypedDataData, + mockLensApolloClient, + mockRelaySuccessFragment, } from '@lens-protocol/api-bindings/mocks'; import { NativeTransaction, UnsignedTransaction } from '@lens-protocol/domain/entities'; import { - mockPaidFollowRequest, mockFreeFollowRequest, - mockWallet, + mockPaidFollowRequest, mockUnknownFollowRequest, + mockWallet, } from '@lens-protocol/domain/mocks'; import { ChainType } from '@lens-protocol/shared-kernel'; import { providers } from 'ethers'; @@ -130,7 +130,7 @@ describe(`Given an instance of ${FollowProfileGateway.name}`, () => { describe(`when creating an ${UnsignedTransaction.name}<${name}>`, () => { const wallet = mockWallet(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockCreateFollowTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/profiles/__tests__/LinkHandleGateway.spec.ts b/packages/react/src/transactions/adapters/profiles/__tests__/LinkHandleGateway.spec.ts index d00ce94162..8d1aab5c25 100644 --- a/packages/react/src/transactions/adapters/profiles/__tests__/LinkHandleGateway.spec.ts +++ b/packages/react/src/transactions/adapters/profiles/__tests__/LinkHandleGateway.spec.ts @@ -3,11 +3,11 @@ */ import { SafeApolloClient } from '@lens-protocol/api-bindings'; import { - mockLensApolloClient, - mockRelaySuccessFragment, mockCreateLinkHandleToProfileTypedDataData, mockCreateLinkHandleToProfileTypedDataResponse, + mockLensApolloClient, mockLinkHandleToProfileResponse, + mockRelaySuccessFragment, } from '@lens-protocol/api-bindings/mocks'; import { NativeTransaction, UnsignedTransaction } from '@lens-protocol/domain/entities'; import { mockLinkHandleRequest, mockWallet } from '@lens-protocol/domain/mocks'; @@ -49,7 +49,7 @@ describe(`Given an instance of ${LinkHandleGateway.name}`, () => { const wallet = mockWallet(); const data = mockCreateLinkHandleToProfileTypedDataData(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockCreateLinkHandleToProfileTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/profiles/__tests__/ProfileMetadataGateway.spec.ts b/packages/react/src/transactions/adapters/profiles/__tests__/ProfileMetadataGateway.spec.ts index 575fffe2b2..fdc8b59707 100644 --- a/packages/react/src/transactions/adapters/profiles/__tests__/ProfileMetadataGateway.spec.ts +++ b/packages/react/src/transactions/adapters/profiles/__tests__/ProfileMetadataGateway.spec.ts @@ -55,7 +55,7 @@ describe(`Given an instance of the ${ProfileMetadataGateway.name}`, () => { describe(`when creating an ${UnsignedTransaction.name}`, () => { const wallet = mockWallet(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockCreateSetProfileMetadataTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/profiles/__tests__/UnblockProfilesGateway.spec.ts b/packages/react/src/transactions/adapters/profiles/__tests__/UnblockProfilesGateway.spec.ts index da6c25a368..9b7c5629b3 100644 --- a/packages/react/src/transactions/adapters/profiles/__tests__/UnblockProfilesGateway.spec.ts +++ b/packages/react/src/transactions/adapters/profiles/__tests__/UnblockProfilesGateway.spec.ts @@ -53,7 +53,7 @@ describe(`Given an instance of ${UnblockProfilesGateway.name}`, () => { const request = mockUnblockProfilesRequest(); const data = mockUnblockProfilesTypedDataData(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockUnblockProfilesTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/profiles/__tests__/UnfollowProfileGateway.spec.ts b/packages/react/src/transactions/adapters/profiles/__tests__/UnfollowProfileGateway.spec.ts index a25e7d76d6..df04c56fa9 100644 --- a/packages/react/src/transactions/adapters/profiles/__tests__/UnfollowProfileGateway.spec.ts +++ b/packages/react/src/transactions/adapters/profiles/__tests__/UnfollowProfileGateway.spec.ts @@ -54,7 +54,7 @@ describe(`Given an instance of ${UnfollowProfileGateway.name}`, () => { const wallet = mockWallet(); const data = mockCreateUnfollowTypedDataData(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockCreateUnfollowTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/profiles/__tests__/UnlinkHandleGateway.spec.ts b/packages/react/src/transactions/adapters/profiles/__tests__/UnlinkHandleGateway.spec.ts index 6ea57ee60a..54ad43bdff 100644 --- a/packages/react/src/transactions/adapters/profiles/__tests__/UnlinkHandleGateway.spec.ts +++ b/packages/react/src/transactions/adapters/profiles/__tests__/UnlinkHandleGateway.spec.ts @@ -3,10 +3,10 @@ */ import { SafeApolloClient } from '@lens-protocol/api-bindings'; import { - mockLensApolloClient, - mockRelaySuccessFragment, mockCreateUnlinkHandleFromProfileTypedDataData, mockCreateUnlinkHandleFromProfileTypedDataResponse, + mockLensApolloClient, + mockRelaySuccessFragment, mockUnlinkHandleFromProfileResponse, } from '@lens-protocol/api-bindings/mocks'; import { NativeTransaction, UnsignedTransaction } from '@lens-protocol/domain/entities'; @@ -54,7 +54,7 @@ describe(`Given an instance of ${UnlinkHandleGateway.name}`, () => { const wallet = mockWallet(); const data = mockCreateUnlinkHandleFromProfileTypedDataData(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockCreateUnlinkHandleFromProfileTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/profiles/__tests__/UpdateFollowPolicyGateway.spec.ts b/packages/react/src/transactions/adapters/profiles/__tests__/UpdateFollowPolicyGateway.spec.ts index a0d3ed1fe0..5c235657ec 100644 --- a/packages/react/src/transactions/adapters/profiles/__tests__/UpdateFollowPolicyGateway.spec.ts +++ b/packages/react/src/transactions/adapters/profiles/__tests__/UpdateFollowPolicyGateway.spec.ts @@ -3,10 +3,10 @@ */ import { SafeApolloClient, resolveFollowModuleInput } from '@lens-protocol/api-bindings'; import { - mockLensApolloClient, - mockRelaySuccessFragment, mockCreateSetFollowModuleTypedDataData, mockCreateSetFollowModuleTypedDataResponse, + mockLensApolloClient, + mockRelaySuccessFragment, mockSetFollowModuleResponse, } from '@lens-protocol/api-bindings/mocks'; import { NativeTransaction, UnsignedTransaction } from '@lens-protocol/domain/entities'; @@ -54,7 +54,7 @@ describe(`Given an instance of ${UpdateFollowPolicyGateway.name}`, () => { const wallet = mockWallet(); const data = mockCreateSetFollowModuleTypedDataData(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockCreateSetFollowModuleTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/publications/CreateOnChainCommentGateway.ts b/packages/react/src/transactions/adapters/publications/CreateOnChainCommentGateway.ts index efcc717c0b..a03c49624a 100644 --- a/packages/react/src/transactions/adapters/publications/CreateOnChainCommentGateway.ts +++ b/packages/react/src/transactions/adapters/publications/CreateOnChainCommentGateway.ts @@ -1,15 +1,15 @@ import { - SafeApolloClient, - omitTypename, - RelaySuccess, CommentOnchainData, - CommentOnchainVariables, CommentOnchainDocument, - OnchainCommentRequest, + CommentOnchainVariables, CreateOnchainCommentBroadcastItemResult, CreateOnchainCommentTypedDataData, - CreateOnchainCommentTypedDataVariables, CreateOnchainCommentTypedDataDocument, + CreateOnchainCommentTypedDataVariables, + OnchainCommentRequest, + RelaySuccess, + SafeApolloClient, + omitTypename, } from '@lens-protocol/api-bindings'; import { lensHub } from '@lens-protocol/blockchain-bindings'; import { NativeTransaction, Nonce } from '@lens-protocol/domain/entities'; @@ -17,7 +17,6 @@ import { CreateCommentRequest } from '@lens-protocol/domain/use-cases/publicatio import { BroadcastingError, IDelegatedTransactionGateway, - IPaidTransactionGateway, ISignedOnChainGateway, } from '@lens-protocol/domain/use-cases/transactions'; import { ChainType, Data, PromiseResult, success } from '@lens-protocol/shared-kernel'; @@ -36,8 +35,7 @@ export class CreateOnChainCommentGateway extends AbstractContractCallGateway implements IDelegatedTransactionGateway, - ISignedOnChainGateway, - IPaidTransactionGateway + ISignedOnChainGateway { constructor( config: LensConfig, @@ -80,7 +78,7 @@ export class CreateOnChainCommentGateway }); } - protected override async createEncodedData( + protected override async createCallDetails( request: CreateCommentRequest, ): Promise { const input = this.resolveOnchainCommentRequest(request); diff --git a/packages/react/src/transactions/adapters/publications/CreateOnChainMirrorGateway.ts b/packages/react/src/transactions/adapters/publications/CreateOnChainMirrorGateway.ts index 060f90d8f7..371a7a1746 100644 --- a/packages/react/src/transactions/adapters/publications/CreateOnChainMirrorGateway.ts +++ b/packages/react/src/transactions/adapters/publications/CreateOnChainMirrorGateway.ts @@ -17,7 +17,6 @@ import { CreateMirrorRequest } from '@lens-protocol/domain/use-cases/publication import { BroadcastingError, IDelegatedTransactionGateway, - IPaidTransactionGateway, ISignedOnChainGateway, } from '@lens-protocol/domain/use-cases/transactions'; import { ChainType, Data, PromiseResult, success } from '@lens-protocol/shared-kernel'; @@ -34,8 +33,7 @@ export class CreateOnChainMirrorGateway extends AbstractContractCallGateway implements IDelegatedTransactionGateway, - ISignedOnChainGateway, - IPaidTransactionGateway + ISignedOnChainGateway { constructor( config: LensConfig, @@ -78,7 +76,7 @@ export class CreateOnChainMirrorGateway }); } - protected override async createEncodedData( + protected override async createCallDetails( request: CreateMirrorRequest, ): Promise { const input = this.resolveOnchainMirrorRequest(request); diff --git a/packages/react/src/transactions/adapters/publications/CreateOnChainPostGateway.ts b/packages/react/src/transactions/adapters/publications/CreateOnChainPostGateway.ts index a822b5c906..5169ce4340 100644 --- a/packages/react/src/transactions/adapters/publications/CreateOnChainPostGateway.ts +++ b/packages/react/src/transactions/adapters/publications/CreateOnChainPostGateway.ts @@ -1,15 +1,15 @@ import { - SafeApolloClient, - omitTypename, - RelaySuccess, - CreateOnchainPostTypedDataData, CreateOnchainPostBroadcastItemResult, - CreateOnchainPostTypedDataVariables, + CreateOnchainPostTypedDataData, CreateOnchainPostTypedDataDocument, + CreateOnchainPostTypedDataVariables, OnchainPostRequest, PostOnchainData, - PostOnchainVariables, PostOnchainDocument, + PostOnchainVariables, + RelaySuccess, + SafeApolloClient, + omitTypename, } from '@lens-protocol/api-bindings'; import { lensHub } from '@lens-protocol/blockchain-bindings'; import { NativeTransaction, Nonce } from '@lens-protocol/domain/entities'; @@ -17,7 +17,6 @@ import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications' import { BroadcastingError, IDelegatedTransactionGateway, - IPaidTransactionGateway, ISignedOnChainGateway, } from '@lens-protocol/domain/use-cases/transactions'; import { ChainType, Data, PromiseResult, success } from '@lens-protocol/shared-kernel'; @@ -36,8 +35,7 @@ export class CreateOnChainPostGateway extends AbstractContractCallGateway implements IDelegatedTransactionGateway, - ISignedOnChainGateway, - IPaidTransactionGateway + ISignedOnChainGateway { constructor( config: LensConfig, @@ -80,7 +78,7 @@ export class CreateOnChainPostGateway }); } - protected override async createEncodedData( + protected override async createCallDetails( request: CreatePostRequest, ): Promise { const input = this.resolveOnchainPostRequest(request); diff --git a/packages/react/src/transactions/adapters/publications/CreateOnChainQuoteGateway.ts b/packages/react/src/transactions/adapters/publications/CreateOnChainQuoteGateway.ts index 8e3ec8d016..4391f48838 100644 --- a/packages/react/src/transactions/adapters/publications/CreateOnChainQuoteGateway.ts +++ b/packages/react/src/transactions/adapters/publications/CreateOnChainQuoteGateway.ts @@ -1,15 +1,15 @@ import { - SafeApolloClient, - omitTypename, - RelaySuccess, - QuoteOnchainData, - QuoteOnchainVariables, - QuoteOnchainDocument, - OnchainQuoteRequest, CreateOnchainQuoteBroadcastItemResult, CreateOnchainQuoteTypedDataData, - CreateOnchainQuoteTypedDataVariables, CreateOnchainQuoteTypedDataDocument, + CreateOnchainQuoteTypedDataVariables, + OnchainQuoteRequest, + QuoteOnchainData, + QuoteOnchainDocument, + QuoteOnchainVariables, + RelaySuccess, + SafeApolloClient, + omitTypename, } from '@lens-protocol/api-bindings'; import { lensHub } from '@lens-protocol/blockchain-bindings'; import { NativeTransaction, Nonce } from '@lens-protocol/domain/entities'; @@ -17,7 +17,6 @@ import { CreateQuoteRequest } from '@lens-protocol/domain/use-cases/publications import { BroadcastingError, IDelegatedTransactionGateway, - IPaidTransactionGateway, ISignedOnChainGateway, } from '@lens-protocol/domain/use-cases/transactions'; import { ChainType, Data, PromiseResult, success } from '@lens-protocol/shared-kernel'; @@ -36,8 +35,7 @@ export class CreateOnChainQuoteGateway extends AbstractContractCallGateway implements IDelegatedTransactionGateway, - ISignedOnChainGateway, - IPaidTransactionGateway + ISignedOnChainGateway { constructor( config: LensConfig, @@ -80,7 +78,7 @@ export class CreateOnChainQuoteGateway }); } - protected override async createEncodedData( + protected override async createCallDetails( request: CreateQuoteRequest, ): Promise { const input = this.resolveOnchainQuoteRequest(request); diff --git a/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainCommentGateway.spec.ts b/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainCommentGateway.spec.ts index b77f15d42b..06478f2611 100644 --- a/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainCommentGateway.spec.ts +++ b/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainCommentGateway.spec.ts @@ -14,7 +14,7 @@ import { mockRelaySuccessFragment, } from '@lens-protocol/api-bindings/mocks'; import { NativeTransaction } from '@lens-protocol/domain/entities'; -import { mockNonce, mockCreateCommentRequest, mockWallet } from '@lens-protocol/domain/mocks'; +import { mockCreateCommentRequest, mockNonce, mockWallet } from '@lens-protocol/domain/mocks'; import { BroadcastingError, BroadcastingErrorReason, @@ -105,7 +105,7 @@ describe(`Given an instance of ${CreateOnChainCommentGateway.name}`, () => { describe(`when creating an UnsignedTransaction`, () => { const wallet = mockWallet(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockCreateOnchainCommentTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainMirrorGateway.spec.ts b/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainMirrorGateway.spec.ts index 21f3538203..29b152d125 100644 --- a/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainMirrorGateway.spec.ts +++ b/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainMirrorGateway.spec.ts @@ -6,12 +6,12 @@ import { SafeApolloClient, } from '@lens-protocol/api-bindings'; import { - mockLensApolloClient, mockCreateOnchainMirrorTypedDataData, mockCreateOnchainMirrorTypedDataResponse, + mockLensApolloClient, + mockLensProfileManagerRelayError, mockMirrorOnchainResponse, mockRelaySuccessFragment, - mockLensProfileManagerRelayError, } from '@lens-protocol/api-bindings/mocks'; import { NativeTransaction } from '@lens-protocol/domain/entities'; import { mockCreateMirrorRequest, mockWallet } from '@lens-protocol/domain/mocks'; @@ -86,7 +86,7 @@ describe(`Given an instance of ${CreateOnChainMirrorGateway.name}`, () => { describe(`when creating an UnsignedTransaction`, () => { const wallet = mockWallet(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockCreateOnchainMirrorTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainPostGateway.spec.ts b/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainPostGateway.spec.ts index 0e7c7a4f8c..f1408508e1 100644 --- a/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainPostGateway.spec.ts +++ b/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainPostGateway.spec.ts @@ -2,19 +2,19 @@ * @jest-environment node */ import { - SafeApolloClient, LensProfileManagerRelayErrorReasonType, + SafeApolloClient, } from '@lens-protocol/api-bindings'; import { - mockLensApolloClient, - mockCreateOnchainPostTypedDataResponse, mockCreateOnchainPostTypedDataData, - mockRelaySuccessFragment, - mockPostOnchainResponse, + mockCreateOnchainPostTypedDataResponse, + mockLensApolloClient, mockLensProfileManagerRelayError, + mockPostOnchainResponse, + mockRelaySuccessFragment, } from '@lens-protocol/api-bindings/mocks'; import { NativeTransaction } from '@lens-protocol/domain/entities'; -import { mockNonce, mockCreatePostRequest, mockWallet } from '@lens-protocol/domain/mocks'; +import { mockCreatePostRequest, mockNonce, mockWallet } from '@lens-protocol/domain/mocks'; import { BroadcastingError, BroadcastingErrorReason, @@ -105,7 +105,7 @@ describe(`Given an instance of ${CreateOnChainPostGateway.name}`, () => { describe(`when creating an UnsignedTransaction`, () => { const wallet = mockWallet(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockCreateOnchainPostTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainQuoteGateway.spec.ts b/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainQuoteGateway.spec.ts index 1ea08dfd4a..97983ce194 100644 --- a/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainQuoteGateway.spec.ts +++ b/packages/react/src/transactions/adapters/publications/__tests__/CreateOnChainQuoteGateway.spec.ts @@ -6,15 +6,15 @@ import { SafeApolloClient, } from '@lens-protocol/api-bindings'; import { - mockQuoteOnchainResponse, mockCreateOnchainQuoteTypedDataData, mockCreateOnchainQuoteTypedDataResponse, mockLensApolloClient, mockLensProfileManagerRelayError, + mockQuoteOnchainResponse, mockRelaySuccessFragment, } from '@lens-protocol/api-bindings/mocks'; import { NativeTransaction } from '@lens-protocol/domain/entities'; -import { mockNonce, mockCreateQuoteRequest, mockWallet } from '@lens-protocol/domain/mocks'; +import { mockCreateQuoteRequest, mockNonce, mockWallet } from '@lens-protocol/domain/mocks'; import { BroadcastingError, BroadcastingErrorReason, @@ -105,7 +105,7 @@ describe(`Given an instance of ${CreateOnChainQuoteGateway.name}`, () => { describe(`when creating an UnsignedTransaction`, () => { const wallet = mockWallet(); - it(`should succeed with the expected ${UnsignedContractCallTransaction.name}`, async () => { + it(`should resolve with the expected ${UnsignedContractCallTransaction.name}`, async () => { const provider = await mockJsonRpcProvider(); const apolloClient = mockLensApolloClient([ mockCreateOnchainQuoteTypedDataResponse({ diff --git a/packages/react/src/transactions/adapters/schemas/profiles.ts b/packages/react/src/transactions/adapters/schemas/profiles.ts index f2cff2a80f..6c55a1cb5f 100644 --- a/packages/react/src/transactions/adapters/schemas/profiles.ts +++ b/packages/react/src/transactions/adapters/schemas/profiles.ts @@ -1,5 +1,6 @@ import { TransactionKind } from '@lens-protocol/domain/entities'; import { + CreateProfileRequest, FollowPolicyConfig, FollowPolicyType, FollowRequest, @@ -11,9 +12,15 @@ import { z } from 'zod'; import { DataSchema, Erc20AmountSchema, EvmAddressSchema, ProfileIdSchema } from './common'; -export const CreateProfileRequestSchema = z.object({ - handle: z.string(), +export const CreateProfileRequestSchema: z.ZodType< + CreateProfileRequest, + z.ZodTypeDef, + UnknownObject +> = z.object({ kind: z.literal(TransactionKind.CREATE_PROFILE), + localName: z.string(), + approveSignless: z.boolean(), + to: EvmAddressSchema, }); const FollowRequestFeeSchema = z.object({ diff --git a/packages/react/src/transactions/adapters/useClaimHandleController.ts b/packages/react/src/transactions/adapters/useClaimHandleController.ts index 5f6d647efc..98428bef30 100644 --- a/packages/react/src/transactions/adapters/useClaimHandleController.ts +++ b/packages/react/src/transactions/adapters/useClaimHandleController.ts @@ -8,7 +8,7 @@ import { import { PromiseResult } from '@lens-protocol/shared-kernel'; import { useSharedDependencies } from '../../shared'; -import { NewProfilePresenter } from './NewProfilePresenter'; +import { ClaimProfilePresenter } from './ClaimProfilePresenter'; import { ClaimProfileGateway } from './profiles/ClaimProfileGateway'; export function useClaimHandleController() { @@ -22,7 +22,7 @@ export function useClaimHandleController() { ClaimHandleError | TransactionError > => { const gateway = new ClaimProfileGateway(apolloClient, transactionFactory); - const presenter = new NewProfilePresenter( + const presenter = new ClaimProfilePresenter( profileCacheManager, config.environment.handleResolver, ); diff --git a/packages/react/src/transactions/adapters/useCreateProfileController.ts b/packages/react/src/transactions/adapters/useCreateProfileController.ts new file mode 100644 index 0000000000..1a99e270c4 --- /dev/null +++ b/packages/react/src/transactions/adapters/useCreateProfileController.ts @@ -0,0 +1,53 @@ +import { Profile } from '@lens-protocol/api-bindings'; +import { + InsufficientGasError, + PendingSigningRequestError, + TransactionError, + UserRejectedError, + WalletConnectionError, +} from '@lens-protocol/domain/entities'; +import { CreateProfile, CreateProfileRequest } from '@lens-protocol/domain/use-cases/profile'; +import { PromiseResult } from '@lens-protocol/shared-kernel'; + +import { useSharedDependencies } from '../../shared'; +import { CreateProfilePresenter } from './CreateProfilePresenter'; +import { CreateProfileTransactionGateway } from './CreateProfileTransactionGateway'; + +export function useCreateProfileController() { + const { + apolloClient, + config, + profileCacheManager, + providerFactory, + transactionQueue, + walletFactory, + } = useSharedDependencies(); + + return async ( + request: CreateProfileRequest, + ): PromiseResult< + Profile, + | PendingSigningRequestError + | InsufficientGasError + | UserRejectedError + | WalletConnectionError + | TransactionError + > => { + const gateway = new CreateProfileTransactionGateway(apolloClient, config, providerFactory); + const presenter = new CreateProfilePresenter( + profileCacheManager, + config.environment.handleResolver, + ); + + const createProfile = new CreateProfile(walletFactory, gateway, presenter, transactionQueue); + + await createProfile.execute(request); + + const result = presenter.asResult(); + + if (result.isSuccess()) { + return result.value.waitForCompletion(); + } + return result; + }; +} diff --git a/packages/react/src/transactions/index.ts b/packages/react/src/transactions/index.ts index 15c0f61171..e4df973286 100644 --- a/packages/react/src/transactions/index.ts +++ b/packages/react/src/transactions/index.ts @@ -4,6 +4,7 @@ export * from './publications'; export * from './useApproveModule'; export * from './useBlockProfiles'; export * from './useClaimHandle'; +export * from './useCreateProfile'; export * from './useFollow'; export * from './useLinkHandle'; export * from './useOpenAction'; @@ -31,15 +32,14 @@ export type { export type { ChargeFollowConfig, FollowPolicyConfig, + NoFeeFollowConfig, NoFollowConfig, OpenFollowConfig, UnknownFollowConfig, - // deprecated below - NoFeeFollowConfig, } from '@lens-protocol/domain/use-cases/profile'; /** * Enums */ -export { OpenActionType, ReferencePolicyType } from '@lens-protocol/domain/use-cases/publications'; export { FollowPolicyType } from '@lens-protocol/domain/use-cases/profile'; +export { OpenActionType, ReferencePolicyType } from '@lens-protocol/domain/use-cases/publications'; diff --git a/packages/react/src/transactions/useCreateProfile.ts b/packages/react/src/transactions/useCreateProfile.ts new file mode 100644 index 0000000000..3f0120f422 --- /dev/null +++ b/packages/react/src/transactions/useCreateProfile.ts @@ -0,0 +1,112 @@ +import { Profile, UnspecifiedError } from '@lens-protocol/api-bindings'; +import { + InsufficientGasError, + PendingSigningRequestError, + TransactionError, + TransactionKind, + UserRejectedError, + WalletConnectionError, +} from '@lens-protocol/domain/entities'; +import { EvmAddress, PromiseResult } from '@lens-protocol/shared-kernel'; + +import { UseDeferredTask, useDeferredTask } from '../helpers/tasks'; +import { HandleNotAvailableError, InvalidHandleError, useValidateHandle } from '../misc'; +import { useCreateProfileController } from './adapters/useCreateProfileController'; + +/** + * Create Profile details. + */ +export type CreateProfileArgs = { + /** + * The user's wallet. Could be an EOA or EIP-1271 compliant Smart Wallet (e.g. ERC-6551). + */ + to: EvmAddress; + /** + * The handle local name to claim. + */ + localName: string; + /** + * Determines if the Signless Experience should be enabled. + * + * @defaultValue true, if not specified. + */ + approveSignless?: boolean; +}; + +/** + * `useCreateProfile` is a React Hook that allows you to create a Profile associated with a Handle. + * + * @example + * ```ts + * const { execute, loading, error } = useCreateProfile(); + * ``` + * + * ## Create a Profile + * + * ```ts + * const { execute, loading, error } = useCreateProfile(); + * + * // ... + * + * const result = execute({ + * localName: 'foobar', // full handle will be lens/foobar + * to: '0x1234567890123456789012345678901234567890', + * }); + * + * if (result.isFailure()) { + * console.error(result.error); + * return; + * } + * + * const profile = result.value; + * console.log(profile); + * ``` + * + * @experimental This hook is experimental and may change in future versions. + * @category Profiles + * @group Hooks + */ +export function useCreateProfile(): UseDeferredTask< + Profile, + | PendingSigningRequestError + | InsufficientGasError + | UserRejectedError + | WalletConnectionError + | TransactionError + | HandleNotAvailableError + | InvalidHandleError + | UnspecifiedError, + CreateProfileArgs +> { + const { execute: validate } = useValidateHandle(); + const createProfile = useCreateProfileController(); + + return useDeferredTask( + async ( + args: CreateProfileArgs, + ): PromiseResult< + Profile, + | PendingSigningRequestError + | InsufficientGasError + | UserRejectedError + | WalletConnectionError + | TransactionError + | HandleNotAvailableError + | InvalidHandleError + | UnspecifiedError + > => { + const result = await validate({ localName: args.localName }); + + if (result.isFailure()) { + return result; + } + + return createProfile({ + kind: TransactionKind.CREATE_PROFILE, + localName: args.localName, + to: args.to, + approveSignless: args.approveSignless ?? true, + }); + }, + ); +} diff --git a/packages/react/src/wallet/adapters/WalletFactory.ts b/packages/react/src/wallet/adapters/WalletFactory.ts index dcf46ea090..cb9e36ada5 100644 --- a/packages/react/src/wallet/adapters/WalletFactory.ts +++ b/packages/react/src/wallet/adapters/WalletFactory.ts @@ -1,5 +1,5 @@ -import { IWalletFactory } from '@lens-protocol/domain/use-cases/authentication'; import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; +import { IWalletFactory } from '@lens-protocol/domain/use-cases/wallets'; import { EvmAddress } from '@lens-protocol/shared-kernel'; import { ITransactionFactory } from '../../transactions/adapters/ITransactionFactory'; diff --git a/packages/react/src/wallet/adapters/__tests__/ConcreteWallet.spec.ts b/packages/react/src/wallet/adapters/__tests__/ConcreteWallet.spec.ts index ae2048e6a3..be21c72eb3 100644 --- a/packages/react/src/wallet/adapters/__tests__/ConcreteWallet.spec.ts +++ b/packages/react/src/wallet/adapters/__tests__/ConcreteWallet.spec.ts @@ -3,20 +3,20 @@ */ import { + InsufficientGasError, NativeTransaction, + PendingSigningRequestError, UnsignedTransaction, - InsufficientGasError, + UserRejectedError, WalletConnectionError, WalletConnectionErrorReason, - UserRejectedError, - PendingSigningRequestError, } from '@lens-protocol/domain/entities'; import { mockProtocolTransactionRequestModel, mockSignature } from '@lens-protocol/domain/mocks'; import { ChainType, failure, success } from '@lens-protocol/shared-kernel'; import { mockEvmAddress } from '@lens-protocol/shared-kernel/mocks'; import { errorCodes } from 'eth-rpc-errors'; import { MockProvider } from 'ethereum-waffle'; -import { errors, providers, utils, Wallet } from 'ethers'; +import { Wallet, errors, providers, utils } from 'ethers'; import { mock } from 'jest-mock-extended'; import { when } from 'jest-when'; @@ -187,6 +187,7 @@ describe(`Given an instance of ${ConcreteWallet.name}`, () => { it(`should: - use the user's wallet to sign and send the transaction - resolve with with a ${NativeTransaction.name}`, async () => { + // setup const provider = new MockProvider(); const [sender, receiver] = provider.getWallets() as [Wallet, Wallet]; const txRequest = await sender.populateTransaction({ @@ -202,9 +203,11 @@ describe(`Given an instance of ${ConcreteWallet.name}`, () => { const wallet = setupWalletInstance({ signerFactory }); const receiverBalanceBefore = await receiver.getBalance(); + // execute const unsignedTransaction = mockUnsignedTransactionRequest({ chainType, txRequest }); const result = await wallet.sendTransaction(unsignedTransaction); + // verify const receiverBalanceAfter = await receiver.getBalance(); expect(receiverBalanceAfter.gt(receiverBalanceBefore)).toBe(true); @@ -220,6 +223,7 @@ describe(`Given an instance of ${ConcreteWallet.name}`, () => { }, 15_000); it(`should fail with ${PendingSigningRequestError.name} in case of existing signing request`, async () => { + // setup const provider = new MockProvider(); const [sender, receiver] = provider.getWallets() as [Wallet, Wallet]; const txRequest = await sender.populateTransaction({ @@ -234,14 +238,17 @@ describe(`Given an instance of ${ConcreteWallet.name}`, () => { }); const wallet = setupWalletInstance({ signerFactory }); + // execute const unsignedTransaction = mockUnsignedTransactionRequest({ chainType, txRequest }); void wallet.sendTransaction(unsignedTransaction); // previous signing request const result = await wallet.sendTransaction(unsignedTransaction); + // verify expect(() => result.unwrap()).toThrow(PendingSigningRequestError); }); it(`should fail with ${InsufficientGasError.name} in case the wallet does not have enough Matic/Ether`, async () => { + // setup const signer = mock(); when(signer.sendTransaction).mockRejectedValue(mockErrorWithCode(errors.INSUFFICIENT_FUNDS)); @@ -252,9 +259,11 @@ describe(`Given an instance of ${ConcreteWallet.name}`, () => { }); const wallet = setupWalletInstance({ signerFactory }); + // execute const unsignedTransaction = mockUnsignedTransactionRequest({ chainType, txRequest: {} }); const result = await wallet.sendTransaction(unsignedTransaction); + // verify expect(() => result.unwrap()).toThrow(InsufficientGasError); }); From eb0b0749b65156a9c76a6352cca6efada23b32fc Mon Sep 17 00:00:00 2001 From: Kris Urbas <605420+krzysu@users.noreply.github.com> Date: Mon, 12 Feb 2024 10:11:30 +0100 Subject: [PATCH 04/13] client: improve onboarding script (#839) --- examples/node/abi/PermissonlessCreator.json | 695 ++++++++++++ .../node/contracts/PermissonlessCreator.ts | 1000 +++++++++++++++++ .../PermissonlessCreator__factory.ts | 713 ++++++++++++ examples/node/contracts/factories/index.ts | 1 + examples/node/contracts/index.ts | 2 + examples/node/scripts/misc/onboarding.ts | 103 +- .../recipes/openActionWalletOnly.ts | 29 +- 7 files changed, 2503 insertions(+), 40 deletions(-) create mode 100644 examples/node/abi/PermissonlessCreator.json create mode 100644 examples/node/contracts/PermissonlessCreator.ts create mode 100644 examples/node/contracts/factories/PermissonlessCreator__factory.ts diff --git a/examples/node/abi/PermissonlessCreator.json b/examples/node/abi/PermissonlessCreator.json new file mode 100644 index 0000000000..384dd7ecb5 --- /dev/null +++ b/examples/node/abi/PermissonlessCreator.json @@ -0,0 +1,695 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "hub", + "type": "address" + }, + { + "internalType": "address", + "name": "lensHandles", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenHandleRegistry", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "HandleAlreadyExists", + "type": "error" + }, + { + "inputs": [], + "name": "HandleLengthNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "InsufficientCredits", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidFunds", + "type": "error" + }, + { + "inputs": [], + "name": "NotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyCreditProviders", + "type": "error" + }, + { + "inputs": [], + "name": "ProfileAlreadyLinked", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creditAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remainingCredits", + "type": "uint256" + } + ], + "name": "CreditBalanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newPrice", + "type": "uint256" + } + ], + "name": "HandleCreationPriceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newPrice", + "type": "uint256" + } + ], + "name": "ProfileCreationPriceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "targetAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "trustRevoked", + "type": "bool" + } + ], + "name": "TrustStatusChanged", + "type": "event" + }, + { + "inputs": [], + "name": "LENS_HANDLES", + "outputs": [ + { + "internalType": "contract ILensHandles", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_HANDLE_REGISTRY", + "outputs": [ + { + "internalType": "contract ITokenHandleRegistry", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "creditProvider", + "type": "address" + } + ], + "name": "addCreditProvider", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "string", + "name": "handle", + "type": "string" + } + ], + "name": "createHandle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "string", + "name": "handle", + "type": "string" + } + ], + "name": "createHandleUsingCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "followModule", + "type": "address" + }, + { + "internalType": "bytes", + "name": "followModuleInitData", + "type": "bytes" + } + ], + "internalType": "struct Types.CreateProfileParams", + "name": "createProfileParams", + "type": "tuple" + }, + { + "internalType": "address[]", + "name": "delegatedExecutors", + "type": "address[]" + } + ], + "name": "createProfile", + "outputs": [ + { + "internalType": "uint256", + "name": "profileId", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "followModule", + "type": "address" + }, + { + "internalType": "bytes", + "name": "followModuleInitData", + "type": "bytes" + } + ], + "internalType": "struct Types.CreateProfileParams", + "name": "createProfileParams", + "type": "tuple" + }, + { + "internalType": "address[]", + "name": "delegatedExecutors", + "type": "address[]" + } + ], + "name": "createProfileUsingCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "followModule", + "type": "address" + }, + { + "internalType": "bytes", + "name": "followModuleInitData", + "type": "bytes" + } + ], + "internalType": "struct Types.CreateProfileParams", + "name": "createProfileParams", + "type": "tuple" + }, + { + "internalType": "string", + "name": "handle", + "type": "string" + }, + { + "internalType": "address[]", + "name": "delegatedExecutors", + "type": "address[]" + } + ], + "name": "createProfileWithHandle", + "outputs": [ + { + "internalType": "uint256", + "name": "profileId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "handleId", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "followModule", + "type": "address" + }, + { + "internalType": "bytes", + "name": "followModuleInitData", + "type": "bytes" + } + ], + "internalType": "struct Types.CreateProfileParams", + "name": "createProfileParams", + "type": "tuple" + }, + { + "internalType": "string", + "name": "handle", + "type": "string" + }, + { + "internalType": "address[]", + "name": "delegatedExecutors", + "type": "address[]" + } + ], + "name": "createProfileWithHandleUsingCredits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "decreaseCredits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "targetAddress", + "type": "address" + } + ], + "name": "getCreditBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getHandleCreationPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getHandleLengthMin", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProfileCreationPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProfileWithHandleCreationPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "increaseCredits", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "targetAddress", + "type": "address" + } + ], + "name": "isCreditProvider", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "targetAddress", + "type": "address" + } + ], + "name": "isTrustRevoked", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "creditProvider", + "type": "address" + } + ], + "name": "removeCreditProvider", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "newPrice", + "type": "uint128" + } + ], + "name": "setHandleCreationPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "newMinLength", + "type": "uint8" + } + ], + "name": "setHandleLengthMin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "newPrice", + "type": "uint128" + } + ], + "name": "setProfileCreationPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "targetAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "trustRevoked", + "type": "bool" + } + ], + "name": "setTrustRevoked", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFromKeepingDelegates", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/examples/node/contracts/PermissonlessCreator.ts b/examples/node/contracts/PermissonlessCreator.ts new file mode 100644 index 0000000000..33cba189b4 --- /dev/null +++ b/examples/node/contracts/PermissonlessCreator.ts @@ -0,0 +1,1000 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + Overrides, + PayableOverrides, + PopulatedTransaction, + Signer, + utils, +} from 'ethers'; +import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi'; +import type { Listener, Provider } from '@ethersproject/providers'; +import type { + TypedEventFilter, + TypedEvent, + TypedListener, + OnEvent, + PromiseOrValue, +} from './common'; + +export declare namespace Types { + export type CreateProfileParamsStruct = { + to: PromiseOrValue; + followModule: PromiseOrValue; + followModuleInitData: PromiseOrValue; + }; + + export type CreateProfileParamsStructOutput = [string, string, string] & { + to: string; + followModule: string; + followModuleInitData: string; + }; +} + +export interface PermissonlessCreatorInterface extends utils.Interface { + functions: { + 'LENS_HANDLES()': FunctionFragment; + 'TOKEN_HANDLE_REGISTRY()': FunctionFragment; + 'addCreditProvider(address)': FunctionFragment; + 'createHandle(address,string)': FunctionFragment; + 'createHandleUsingCredits(address,string)': FunctionFragment; + 'createProfile((address,address,bytes),address[])': FunctionFragment; + 'createProfileUsingCredits((address,address,bytes),address[])': FunctionFragment; + 'createProfileWithHandle((address,address,bytes),string,address[])': FunctionFragment; + 'createProfileWithHandleUsingCredits((address,address,bytes),string,address[])': FunctionFragment; + 'decreaseCredits(address,uint256)': FunctionFragment; + 'getCreditBalance(address)': FunctionFragment; + 'getHandleCreationPrice()': FunctionFragment; + 'getHandleLengthMin()': FunctionFragment; + 'getProfileCreationPrice()': FunctionFragment; + 'getProfileWithHandleCreationPrice()': FunctionFragment; + 'increaseCredits(address,uint256)': FunctionFragment; + 'isCreditProvider(address)': FunctionFragment; + 'isTrustRevoked(address)': FunctionFragment; + 'owner()': FunctionFragment; + 'removeCreditProvider(address)': FunctionFragment; + 'renounceOwnership()': FunctionFragment; + 'setHandleCreationPrice(uint128)': FunctionFragment; + 'setHandleLengthMin(uint8)': FunctionFragment; + 'setProfileCreationPrice(uint128)': FunctionFragment; + 'setTrustRevoked(address,bool)': FunctionFragment; + 'transferFromKeepingDelegates(address,address,uint256)': FunctionFragment; + 'transferOwnership(address)': FunctionFragment; + 'withdrawFunds()': FunctionFragment; + }; + + getFunction( + nameOrSignatureOrTopic: + | 'LENS_HANDLES' + | 'TOKEN_HANDLE_REGISTRY' + | 'addCreditProvider' + | 'createHandle' + | 'createHandleUsingCredits' + | 'createProfile' + | 'createProfileUsingCredits' + | 'createProfileWithHandle' + | 'createProfileWithHandleUsingCredits' + | 'decreaseCredits' + | 'getCreditBalance' + | 'getHandleCreationPrice' + | 'getHandleLengthMin' + | 'getProfileCreationPrice' + | 'getProfileWithHandleCreationPrice' + | 'increaseCredits' + | 'isCreditProvider' + | 'isTrustRevoked' + | 'owner' + | 'removeCreditProvider' + | 'renounceOwnership' + | 'setHandleCreationPrice' + | 'setHandleLengthMin' + | 'setProfileCreationPrice' + | 'setTrustRevoked' + | 'transferFromKeepingDelegates' + | 'transferOwnership' + | 'withdrawFunds', + ): FunctionFragment; + + encodeFunctionData(functionFragment: 'LENS_HANDLES', values?: undefined): string; + encodeFunctionData(functionFragment: 'TOKEN_HANDLE_REGISTRY', values?: undefined): string; + encodeFunctionData( + functionFragment: 'addCreditProvider', + values: [PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'createHandle', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'createHandleUsingCredits', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'createProfile', + values: [Types.CreateProfileParamsStruct, PromiseOrValue[]], + ): string; + encodeFunctionData( + functionFragment: 'createProfileUsingCredits', + values: [Types.CreateProfileParamsStruct, PromiseOrValue[]], + ): string; + encodeFunctionData( + functionFragment: 'createProfileWithHandle', + values: [Types.CreateProfileParamsStruct, PromiseOrValue, PromiseOrValue[]], + ): string; + encodeFunctionData( + functionFragment: 'createProfileWithHandleUsingCredits', + values: [Types.CreateProfileParamsStruct, PromiseOrValue, PromiseOrValue[]], + ): string; + encodeFunctionData( + functionFragment: 'decreaseCredits', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'getCreditBalance', + values: [PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'getHandleCreationPrice', values?: undefined): string; + encodeFunctionData(functionFragment: 'getHandleLengthMin', values?: undefined): string; + encodeFunctionData(functionFragment: 'getProfileCreationPrice', values?: undefined): string; + encodeFunctionData( + functionFragment: 'getProfileWithHandleCreationPrice', + values?: undefined, + ): string; + encodeFunctionData( + functionFragment: 'increaseCredits', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'isCreditProvider', + values: [PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'isTrustRevoked', values: [PromiseOrValue]): string; + encodeFunctionData(functionFragment: 'owner', values?: undefined): string; + encodeFunctionData( + functionFragment: 'removeCreditProvider', + values: [PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'renounceOwnership', values?: undefined): string; + encodeFunctionData( + functionFragment: 'setHandleCreationPrice', + values: [PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'setHandleLengthMin', + values: [PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'setProfileCreationPrice', + values: [PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'setTrustRevoked', + values: [PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'transferFromKeepingDelegates', + values: [PromiseOrValue, PromiseOrValue, PromiseOrValue], + ): string; + encodeFunctionData( + functionFragment: 'transferOwnership', + values: [PromiseOrValue], + ): string; + encodeFunctionData(functionFragment: 'withdrawFunds', values?: undefined): string; + + decodeFunctionResult(functionFragment: 'LENS_HANDLES', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'TOKEN_HANDLE_REGISTRY', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'addCreditProvider', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'createHandle', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'createHandleUsingCredits', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'createProfile', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'createProfileUsingCredits', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'createProfileWithHandle', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'createProfileWithHandleUsingCredits', + data: BytesLike, + ): Result; + decodeFunctionResult(functionFragment: 'decreaseCredits', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getCreditBalance', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getHandleCreationPrice', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getHandleLengthMin', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'getProfileCreationPrice', data: BytesLike): Result; + decodeFunctionResult( + functionFragment: 'getProfileWithHandleCreationPrice', + data: BytesLike, + ): Result; + decodeFunctionResult(functionFragment: 'increaseCredits', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'isCreditProvider', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'isTrustRevoked', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'owner', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'removeCreditProvider', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'renounceOwnership', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'setHandleCreationPrice', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'setHandleLengthMin', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'setProfileCreationPrice', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'setTrustRevoked', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transferFromKeepingDelegates', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'transferOwnership', data: BytesLike): Result; + decodeFunctionResult(functionFragment: 'withdrawFunds', data: BytesLike): Result; + + events: { + 'CreditBalanceChanged(address,uint256)': EventFragment; + 'HandleCreationPriceChanged(uint256)': EventFragment; + 'OwnershipTransferred(address,address)': EventFragment; + 'ProfileCreationPriceChanged(uint256)': EventFragment; + 'TrustStatusChanged(address,bool)': EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: 'CreditBalanceChanged'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'HandleCreationPriceChanged'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'OwnershipTransferred'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'ProfileCreationPriceChanged'): EventFragment; + getEvent(nameOrSignatureOrTopic: 'TrustStatusChanged'): EventFragment; +} + +export interface CreditBalanceChangedEventObject { + creditAddress: string; + remainingCredits: BigNumber; +} +export type CreditBalanceChangedEvent = TypedEvent< + [string, BigNumber], + CreditBalanceChangedEventObject +>; + +export type CreditBalanceChangedEventFilter = TypedEventFilter; + +export interface HandleCreationPriceChangedEventObject { + newPrice: BigNumber; +} +export type HandleCreationPriceChangedEvent = TypedEvent< + [BigNumber], + HandleCreationPriceChangedEventObject +>; + +export type HandleCreationPriceChangedEventFilter = + TypedEventFilter; + +export interface OwnershipTransferredEventObject { + previousOwner: string; + newOwner: string; +} +export type OwnershipTransferredEvent = TypedEvent< + [string, string], + OwnershipTransferredEventObject +>; + +export type OwnershipTransferredEventFilter = TypedEventFilter; + +export interface ProfileCreationPriceChangedEventObject { + newPrice: BigNumber; +} +export type ProfileCreationPriceChangedEvent = TypedEvent< + [BigNumber], + ProfileCreationPriceChangedEventObject +>; + +export type ProfileCreationPriceChangedEventFilter = + TypedEventFilter; + +export interface TrustStatusChangedEventObject { + targetAddress: string; + trustRevoked: boolean; +} +export type TrustStatusChangedEvent = TypedEvent<[string, boolean], TrustStatusChangedEventObject>; + +export type TrustStatusChangedEventFilter = TypedEventFilter; + +export interface PermissonlessCreator extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this; + attach(addressOrName: string): this; + deployed(): Promise; + + interface: PermissonlessCreatorInterface; + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined, + ): Promise>; + + listeners( + eventFilter?: TypedEventFilter, + ): Array>; + listeners(eventName?: string): Array; + removeAllListeners(eventFilter: TypedEventFilter): this; + removeAllListeners(eventName?: string): this; + off: OnEvent; + on: OnEvent; + once: OnEvent; + removeListener: OnEvent; + + functions: { + LENS_HANDLES(overrides?: CallOverrides): Promise<[string]>; + + TOKEN_HANDLE_REGISTRY(overrides?: CallOverrides): Promise<[string]>; + + addCreditProvider( + creditProvider: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createHandle( + to: PromiseOrValue, + handle: PromiseOrValue, + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createHandleUsingCredits( + to: PromiseOrValue, + handle: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createProfile( + createProfileParams: Types.CreateProfileParamsStruct, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileUsingCredits( + createProfileParams: Types.CreateProfileParamsStruct, + delegatedExecutors: PromiseOrValue[], + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileWithHandle( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileWithHandleUsingCredits( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + decreaseCredits( + account: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + getCreditBalance( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[BigNumber]>; + + getHandleCreationPrice(overrides?: CallOverrides): Promise<[BigNumber]>; + + getHandleLengthMin(overrides?: CallOverrides): Promise<[number]>; + + getProfileCreationPrice(overrides?: CallOverrides): Promise<[BigNumber]>; + + getProfileWithHandleCreationPrice(overrides?: CallOverrides): Promise<[BigNumber]>; + + increaseCredits( + account: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + isCreditProvider( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[boolean]>; + + isTrustRevoked( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise<[boolean]>; + + owner(overrides?: CallOverrides): Promise<[string]>; + + removeCreditProvider( + creditProvider: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + renounceOwnership( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setHandleCreationPrice( + newPrice: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setHandleLengthMin( + newMinLength: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setProfileCreationPrice( + newPrice: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setTrustRevoked( + targetAddress: PromiseOrValue, + trustRevoked: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFromKeepingDelegates( + from: PromiseOrValue, + to: PromiseOrValue, + tokenId: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferOwnership( + newOwner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + withdrawFunds( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + }; + + LENS_HANDLES(overrides?: CallOverrides): Promise; + + TOKEN_HANDLE_REGISTRY(overrides?: CallOverrides): Promise; + + addCreditProvider( + creditProvider: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createHandle( + to: PromiseOrValue, + handle: PromiseOrValue, + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createHandleUsingCredits( + to: PromiseOrValue, + handle: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createProfile( + createProfileParams: Types.CreateProfileParamsStruct, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileUsingCredits( + createProfileParams: Types.CreateProfileParamsStruct, + delegatedExecutors: PromiseOrValue[], + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileWithHandle( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileWithHandleUsingCredits( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + decreaseCredits( + account: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + getCreditBalance( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getHandleCreationPrice(overrides?: CallOverrides): Promise; + + getHandleLengthMin(overrides?: CallOverrides): Promise; + + getProfileCreationPrice(overrides?: CallOverrides): Promise; + + getProfileWithHandleCreationPrice(overrides?: CallOverrides): Promise; + + increaseCredits( + account: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + isCreditProvider( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + isTrustRevoked( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + owner(overrides?: CallOverrides): Promise; + + removeCreditProvider( + creditProvider: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + renounceOwnership( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setHandleCreationPrice( + newPrice: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setHandleLengthMin( + newMinLength: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setProfileCreationPrice( + newPrice: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setTrustRevoked( + targetAddress: PromiseOrValue, + trustRevoked: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFromKeepingDelegates( + from: PromiseOrValue, + to: PromiseOrValue, + tokenId: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferOwnership( + newOwner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + withdrawFunds( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + callStatic: { + LENS_HANDLES(overrides?: CallOverrides): Promise; + + TOKEN_HANDLE_REGISTRY(overrides?: CallOverrides): Promise; + + addCreditProvider( + creditProvider: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + createHandle( + to: PromiseOrValue, + handle: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + createHandleUsingCredits( + to: PromiseOrValue, + handle: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + createProfile( + createProfileParams: Types.CreateProfileParamsStruct, + delegatedExecutors: PromiseOrValue[], + overrides?: CallOverrides, + ): Promise; + + createProfileUsingCredits( + createProfileParams: Types.CreateProfileParamsStruct, + delegatedExecutors: PromiseOrValue[], + overrides?: CallOverrides, + ): Promise; + + createProfileWithHandle( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: CallOverrides, + ): Promise<[BigNumber, BigNumber] & { profileId: BigNumber; handleId: BigNumber }>; + + createProfileWithHandleUsingCredits( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: CallOverrides, + ): Promise<[BigNumber, BigNumber]>; + + decreaseCredits( + account: PromiseOrValue, + amount: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getCreditBalance( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getHandleCreationPrice(overrides?: CallOverrides): Promise; + + getHandleLengthMin(overrides?: CallOverrides): Promise; + + getProfileCreationPrice(overrides?: CallOverrides): Promise; + + getProfileWithHandleCreationPrice(overrides?: CallOverrides): Promise; + + increaseCredits( + account: PromiseOrValue, + amount: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + isCreditProvider( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + isTrustRevoked( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + owner(overrides?: CallOverrides): Promise; + + removeCreditProvider( + creditProvider: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + renounceOwnership(overrides?: CallOverrides): Promise; + + setHandleCreationPrice( + newPrice: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + setHandleLengthMin( + newMinLength: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + setProfileCreationPrice( + newPrice: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + setTrustRevoked( + targetAddress: PromiseOrValue, + trustRevoked: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + transferFromKeepingDelegates( + from: PromiseOrValue, + to: PromiseOrValue, + tokenId: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + transferOwnership(newOwner: PromiseOrValue, overrides?: CallOverrides): Promise; + + withdrawFunds(overrides?: CallOverrides): Promise; + }; + + filters: { + 'CreditBalanceChanged(address,uint256)'( + creditAddress?: PromiseOrValue | null, + remainingCredits?: null, + ): CreditBalanceChangedEventFilter; + CreditBalanceChanged( + creditAddress?: PromiseOrValue | null, + remainingCredits?: null, + ): CreditBalanceChangedEventFilter; + + 'HandleCreationPriceChanged(uint256)'(newPrice?: null): HandleCreationPriceChangedEventFilter; + HandleCreationPriceChanged(newPrice?: null): HandleCreationPriceChangedEventFilter; + + 'OwnershipTransferred(address,address)'( + previousOwner?: PromiseOrValue | null, + newOwner?: PromiseOrValue | null, + ): OwnershipTransferredEventFilter; + OwnershipTransferred( + previousOwner?: PromiseOrValue | null, + newOwner?: PromiseOrValue | null, + ): OwnershipTransferredEventFilter; + + 'ProfileCreationPriceChanged(uint256)'(newPrice?: null): ProfileCreationPriceChangedEventFilter; + ProfileCreationPriceChanged(newPrice?: null): ProfileCreationPriceChangedEventFilter; + + 'TrustStatusChanged(address,bool)'( + targetAddress?: PromiseOrValue | null, + trustRevoked?: null, + ): TrustStatusChangedEventFilter; + TrustStatusChanged( + targetAddress?: PromiseOrValue | null, + trustRevoked?: null, + ): TrustStatusChangedEventFilter; + }; + + estimateGas: { + LENS_HANDLES(overrides?: CallOverrides): Promise; + + TOKEN_HANDLE_REGISTRY(overrides?: CallOverrides): Promise; + + addCreditProvider( + creditProvider: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createHandle( + to: PromiseOrValue, + handle: PromiseOrValue, + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createHandleUsingCredits( + to: PromiseOrValue, + handle: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createProfile( + createProfileParams: Types.CreateProfileParamsStruct, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileUsingCredits( + createProfileParams: Types.CreateProfileParamsStruct, + delegatedExecutors: PromiseOrValue[], + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileWithHandle( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileWithHandleUsingCredits( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + decreaseCredits( + account: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + getCreditBalance( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getHandleCreationPrice(overrides?: CallOverrides): Promise; + + getHandleLengthMin(overrides?: CallOverrides): Promise; + + getProfileCreationPrice(overrides?: CallOverrides): Promise; + + getProfileWithHandleCreationPrice(overrides?: CallOverrides): Promise; + + increaseCredits( + account: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + isCreditProvider( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + isTrustRevoked( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + owner(overrides?: CallOverrides): Promise; + + removeCreditProvider( + creditProvider: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + renounceOwnership( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setHandleCreationPrice( + newPrice: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setHandleLengthMin( + newMinLength: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setProfileCreationPrice( + newPrice: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setTrustRevoked( + targetAddress: PromiseOrValue, + trustRevoked: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFromKeepingDelegates( + from: PromiseOrValue, + to: PromiseOrValue, + tokenId: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferOwnership( + newOwner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + withdrawFunds(overrides?: Overrides & { from?: PromiseOrValue }): Promise; + }; + + populateTransaction: { + LENS_HANDLES(overrides?: CallOverrides): Promise; + + TOKEN_HANDLE_REGISTRY(overrides?: CallOverrides): Promise; + + addCreditProvider( + creditProvider: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createHandle( + to: PromiseOrValue, + handle: PromiseOrValue, + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createHandleUsingCredits( + to: PromiseOrValue, + handle: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createProfile( + createProfileParams: Types.CreateProfileParamsStruct, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileUsingCredits( + createProfileParams: Types.CreateProfileParamsStruct, + delegatedExecutors: PromiseOrValue[], + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileWithHandle( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: PayableOverrides & { from?: PromiseOrValue }, + ): Promise; + + createProfileWithHandleUsingCredits( + createProfileParams: Types.CreateProfileParamsStruct, + handle: PromiseOrValue, + delegatedExecutors: PromiseOrValue[], + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + decreaseCredits( + account: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + getCreditBalance( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + getHandleCreationPrice(overrides?: CallOverrides): Promise; + + getHandleLengthMin(overrides?: CallOverrides): Promise; + + getProfileCreationPrice(overrides?: CallOverrides): Promise; + + getProfileWithHandleCreationPrice(overrides?: CallOverrides): Promise; + + increaseCredits( + account: PromiseOrValue, + amount: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + isCreditProvider( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + isTrustRevoked( + targetAddress: PromiseOrValue, + overrides?: CallOverrides, + ): Promise; + + owner(overrides?: CallOverrides): Promise; + + removeCreditProvider( + creditProvider: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + renounceOwnership( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setHandleCreationPrice( + newPrice: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setHandleLengthMin( + newMinLength: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setProfileCreationPrice( + newPrice: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + setTrustRevoked( + targetAddress: PromiseOrValue, + trustRevoked: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferFromKeepingDelegates( + from: PromiseOrValue, + to: PromiseOrValue, + tokenId: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + transferOwnership( + newOwner: PromiseOrValue, + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + + withdrawFunds( + overrides?: Overrides & { from?: PromiseOrValue }, + ): Promise; + }; +} diff --git a/examples/node/contracts/factories/PermissonlessCreator__factory.ts b/examples/node/contracts/factories/PermissonlessCreator__factory.ts new file mode 100644 index 0000000000..64ac0c0b27 --- /dev/null +++ b/examples/node/contracts/factories/PermissonlessCreator__factory.ts @@ -0,0 +1,713 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Signer, utils } from 'ethers'; +import type { Provider } from '@ethersproject/providers'; +import type { PermissonlessCreator, PermissonlessCreatorInterface } from '../PermissonlessCreator'; + +const _abi = [ + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'hub', + type: 'address', + }, + { + internalType: 'address', + name: 'lensHandles', + type: 'address', + }, + { + internalType: 'address', + name: 'tokenHandleRegistry', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [], + name: 'HandleAlreadyExists', + type: 'error', + }, + { + inputs: [], + name: 'HandleLengthNotAllowed', + type: 'error', + }, + { + inputs: [], + name: 'InsufficientCredits', + type: 'error', + }, + { + inputs: [], + name: 'InvalidFunds', + type: 'error', + }, + { + inputs: [], + name: 'NotAllowed', + type: 'error', + }, + { + inputs: [], + name: 'OnlyCreditProviders', + type: 'error', + }, + { + inputs: [], + name: 'ProfileAlreadyLinked', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'creditAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'remainingCredits', + type: 'uint256', + }, + ], + name: 'CreditBalanceChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newPrice', + type: 'uint256', + }, + ], + name: 'HandleCreationPriceChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'newPrice', + type: 'uint256', + }, + ], + name: 'ProfileCreationPriceChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'targetAddress', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'trustRevoked', + type: 'bool', + }, + ], + name: 'TrustStatusChanged', + type: 'event', + }, + { + inputs: [], + name: 'LENS_HANDLES', + outputs: [ + { + internalType: 'contract ILensHandles', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'TOKEN_HANDLE_REGISTRY', + outputs: [ + { + internalType: 'contract ITokenHandleRegistry', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'creditProvider', + type: 'address', + }, + ], + name: 'addCreditProvider', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'string', + name: 'handle', + type: 'string', + }, + ], + name: 'createHandle', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'string', + name: 'handle', + type: 'string', + }, + ], + name: 'createHandleUsingCredits', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'address', + name: 'followModule', + type: 'address', + }, + { + internalType: 'bytes', + name: 'followModuleInitData', + type: 'bytes', + }, + ], + internalType: 'struct Types.CreateProfileParams', + name: 'createProfileParams', + type: 'tuple', + }, + { + internalType: 'address[]', + name: 'delegatedExecutors', + type: 'address[]', + }, + ], + name: 'createProfile', + outputs: [ + { + internalType: 'uint256', + name: 'profileId', + type: 'uint256', + }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'address', + name: 'followModule', + type: 'address', + }, + { + internalType: 'bytes', + name: 'followModuleInitData', + type: 'bytes', + }, + ], + internalType: 'struct Types.CreateProfileParams', + name: 'createProfileParams', + type: 'tuple', + }, + { + internalType: 'address[]', + name: 'delegatedExecutors', + type: 'address[]', + }, + ], + name: 'createProfileUsingCredits', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'address', + name: 'followModule', + type: 'address', + }, + { + internalType: 'bytes', + name: 'followModuleInitData', + type: 'bytes', + }, + ], + internalType: 'struct Types.CreateProfileParams', + name: 'createProfileParams', + type: 'tuple', + }, + { + internalType: 'string', + name: 'handle', + type: 'string', + }, + { + internalType: 'address[]', + name: 'delegatedExecutors', + type: 'address[]', + }, + ], + name: 'createProfileWithHandle', + outputs: [ + { + internalType: 'uint256', + name: 'profileId', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'handleId', + type: 'uint256', + }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'address', + name: 'followModule', + type: 'address', + }, + { + internalType: 'bytes', + name: 'followModuleInitData', + type: 'bytes', + }, + ], + internalType: 'struct Types.CreateProfileParams', + name: 'createProfileParams', + type: 'tuple', + }, + { + internalType: 'string', + name: 'handle', + type: 'string', + }, + { + internalType: 'address[]', + name: 'delegatedExecutors', + type: 'address[]', + }, + ], + name: 'createProfileWithHandleUsingCredits', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'decreaseCredits', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'targetAddress', + type: 'address', + }, + ], + name: 'getCreditBalance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getHandleCreationPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getHandleLengthMin', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getProfileCreationPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getProfileWithHandleCreationPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'increaseCredits', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'targetAddress', + type: 'address', + }, + ], + name: 'isCreditProvider', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'targetAddress', + type: 'address', + }, + ], + name: 'isTrustRevoked', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'creditProvider', + type: 'address', + }, + ], + name: 'removeCreditProvider', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint128', + name: 'newPrice', + type: 'uint128', + }, + ], + name: 'setHandleCreationPrice', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint8', + name: 'newMinLength', + type: 'uint8', + }, + ], + name: 'setHandleLengthMin', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint128', + name: 'newPrice', + type: 'uint128', + }, + ], + name: 'setProfileCreationPrice', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'targetAddress', + type: 'address', + }, + { + internalType: 'bool', + name: 'trustRevoked', + type: 'bool', + }, + ], + name: 'setTrustRevoked', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'transferFromKeepingDelegates', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'withdrawFunds', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const; + +export class PermissonlessCreator__factory { + static readonly abi = _abi; + static createInterface(): PermissonlessCreatorInterface { + return new utils.Interface(_abi) as PermissonlessCreatorInterface; + } + static connect(address: string, signerOrProvider: Signer | Provider): PermissonlessCreator { + return new Contract(address, _abi, signerOrProvider) as PermissonlessCreator; + } +} diff --git a/examples/node/contracts/factories/index.ts b/examples/node/contracts/factories/index.ts index 1c2cf137a9..ec2ebe7d82 100644 --- a/examples/node/contracts/factories/index.ts +++ b/examples/node/contracts/factories/index.ts @@ -1,4 +1,5 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +export { PermissonlessCreator__factory } from './PermissonlessCreator__factory'; export { PublicActProxy__factory } from './PublicActProxy__factory'; diff --git a/examples/node/contracts/index.ts b/examples/node/contracts/index.ts index 84bd0c7058..5a21584945 100644 --- a/examples/node/contracts/index.ts +++ b/examples/node/contracts/index.ts @@ -1,6 +1,8 @@ /* Autogenerated file. Do not edit manually. */ /* tslint:disable */ /* eslint-disable */ +export type { PermissonlessCreator } from './PermissonlessCreator'; export type { PublicActProxy } from './PublicActProxy'; export * as factories from './factories'; +export { PermissonlessCreator__factory } from './factories/PermissonlessCreator__factory'; export { PublicActProxy__factory } from './factories/PublicActProxy__factory'; diff --git a/examples/node/scripts/misc/onboarding.ts b/examples/node/scripts/misc/onboarding.ts index 08ee68dce0..df5e96c64c 100644 --- a/examples/node/scripts/misc/onboarding.ts +++ b/examples/node/scripts/misc/onboarding.ts @@ -6,24 +6,36 @@ import { isValidHandle, } from '@lens-protocol/client'; import { MetadataAttributeType, profile as createProfileMetadata } from '@lens-protocol/metadata'; +import * as dotenv from 'dotenv'; +import { ethers } from 'ethers'; -import { setupWallet } from '../shared/setupWallet'; +import abi from '../../abi/PermissonlessCreator.json'; +import type { PermissonlessCreator } from '../../contracts/PermissonlessCreator'; import { uploadWithBundlr } from '../shared/uploadWithBundlr'; -const HANDLE_NAMESPACE = 'test'; // use 'lens' namespace for production +dotenv.config(); -// init LensClient -const client = new LensClient({ - environment: development, -}); +const typedAbi = abi as ethers.ContractInterface; -async function main() { - // prepare wallet of the new user - const wallet = setupWallet(); - const userAddress = await wallet.getAddress(); +const permissonlessCreatorAddress = { + development: '0x42b302BBB4fA27c21d32EdF602E4e2aA65746999', + production: 'TBD', +}; + +if (!process.env.INFURA_API_KEY) { + throw new Error('Infura API key is not defined in .env file'); +} + +const rpcUrl = { + development: `https://polygon-mumbai.infura.io/v3/${process.env.INFURA_API_KEY}`, + production: `https://polygon.infura.io/v3/${process.env.INFURA_API_KEY}`, +}; +const HANDLE_NAMESPACE = 'test'; // use 'lens' namespace for production + +async function main() { // prepare new handle - const requestedHandle = 'janedoe'; // input from the user + const requestedHandle = 'jane_doe'; // input from the user // check if the requested handle is in a valid format if (!isValidHandle(requestedHandle)) { @@ -31,6 +43,11 @@ async function main() { process.exit(1); } + // init LensClient + const client = new LensClient({ + environment: development, + }); + // check if the requested handle is available const handleOwnerAddress = await client.handle.resolveAddress({ handle: `${HANDLE_NAMESPACE}/${requestedHandle}`, @@ -41,35 +58,59 @@ async function main() { process.exit(1); } - // prepare a relayer address to enable signless experience - // const lensRelayerAddress = await client.transaction.generateLensAPIRelayAddress(); + // init a provider to interact with the blockchain + const provider = new ethers.providers.JsonRpcProvider(rpcUrl.development); - // create a new profile with a handle - const createProfileResult = await client.wallet.createProfileWithHandle({ - handle: requestedHandle, - to: userAddress, - }); - - if (!isRelaySuccess(createProfileResult)) { - console.error(`Profile creation failed with the reason: ${createProfileResult.reason}`); - process.exit(1); + // prepare wallet of the new user + if (!process.env.WALLET_PRIVATE_KEY) { + throw new Error('Private key is not defined in .env file'); } + const wallet = new ethers.Wallet(process.env.WALLET_PRIVATE_KEY, provider); + + // init a contract to mint a new profile with the handle + const permissonlessCreator = new ethers.Contract( + permissonlessCreatorAddress.development, + typedAbi, + wallet, + ) as PermissonlessCreator; + + // prepare a relayer address to enable signless experience + const lensRelayerAddress = await client.transaction.generateLensAPIRelayAddress(); + + // get the price to mint a new profile + const price = await permissonlessCreator.getProfileWithHandleCreationPrice(); + + // submit a tx to mint a new profile with the handle + const tx = await permissonlessCreator.createProfileWithHandle( + { + to: wallet.address, + followModule: '0x0000000000000000000000000000000000000000', + followModuleInitData: '0x', + }, + requestedHandle, + [lensRelayerAddress], + { + value: price, + }, + ); console.log( - `Transaction to create new profile with handle "${requestedHandle}" was successfully broadcasted with txId`, - createProfileResult.txId, + `Transaction to create a new profile with handle "${requestedHandle}" was successfully broadcasted with hash`, + tx.hash, ); + console.log(`Waiting for the transaction to be indexed...`); - const createProfileTxCompletion = await client.transaction.waitUntilComplete({ - forTxId: createProfileResult.txId, + const outcome = await client.transaction.waitUntilComplete({ + forTxHash: tx.hash, }); - // handle mining/indexing errors - if (createProfileTxCompletion?.status === LensTransactionStatusType.Failed) { - console.error(createProfileTxCompletion.reason); + if (outcome === null) { + console.error(`The transaction with hash ${tx.hash} was lost.`); process.exit(1); } + console.log('A new profile has been successfully minted.'); + // now fetch the newly created profile to get the id const fullHandle = `${HANDLE_NAMESPACE}/${requestedHandle}`; @@ -85,7 +126,7 @@ async function main() { // the profile with handle is minted, let's now authenticate them const challenge = await client.authentication.generateChallenge({ - signedBy: userAddress, + signedBy: wallet.address, for: profile.id, }); const signature = await wallet.signMessage(challenge.text); @@ -113,8 +154,8 @@ async function main() { // upload the metadata to Arweave const metadataURI = await uploadWithBundlr(metadata); + // const metadataURI = 'https://arweave.net/cv2Rw4g9NhSEXFlq3Ekx1Xo7n76zQSnrx24uBODEkGg'; console.log(`Metadata uploaded to Arweave with URI: ${metadataURI}`); - // https://arweave.net/cv2Rw4g9NhSEXFlq3Ekx1Xo7n76zQSnrx24uBODEkGg // set the profile metadata on the Lens protocol const setProfileMetadataResult = await client.profile.setProfileMetadata({ metadataURI }); diff --git a/examples/node/scripts/publication/recipes/openActionWalletOnly.ts b/examples/node/scripts/publication/recipes/openActionWalletOnly.ts index 7bc470733e..d942e57dc9 100644 --- a/examples/node/scripts/publication/recipes/openActionWalletOnly.ts +++ b/examples/node/scripts/publication/recipes/openActionWalletOnly.ts @@ -14,17 +14,21 @@ const publicActionProxyAddress = { production: '0x53582b1b7BE71622E7386D736b6baf87749B7a2B', }; +if (!process.env.INFURA_API_KEY) { + throw new Error('Infura API key is not defined in .env file'); +} + +const rpcUrl = { + development: `https://polygon-mumbai.infura.io/v3/${process.env.INFURA_API_KEY}`, + production: `https://polygon.infura.io/v3/${process.env.INFURA_API_KEY}`, +}; + async function main() { if (!process.env.WALLET_PRIVATE_KEY) { throw new Error('Private key is not defined in .env file'); } - if (!process.env.INFURA_API_KEY) { - // or define your own provider - throw new Error('Infura API key is not defined in .env file'); - } - const provider = new ethers.providers.JsonRpcProvider( - `https://polygon-mumbai.infura.io/v3/${process.env.INFURA_API_KEY}`, - ); + + const provider = new ethers.providers.JsonRpcProvider(rpcUrl.development); const wallet = new ethers.Wallet(process.env.WALLET_PRIVATE_KEY, provider); const address = await wallet.getAddress(); const client = new LensClient({ @@ -82,9 +86,16 @@ async function main() { console.log(`Submitted a tx with a hash: `, tx.hash); console.log(`Waiting for tx to be mined...`); + const outcome = await client.transaction.waitUntilComplete({ + forTxHash: tx.hash, + }); + + if (outcome === null) { + console.error('The transaction was not found'); + process.exit(1); + } - const receipt = await tx.wait(); - console.log(`Tx was mined: `, receipt); + console.log('Publication collected'); } main(); From 3a0c3539a29c4734fa522edc008388c1d74edff3 Mon Sep 17 00:00:00 2001 From: Cesare Naldi Date: Mon, 12 Feb 2024 13:29:12 +0000 Subject: [PATCH 05/13] fix: removes some legacy concepts no longer needed (#833) * Renames ICredentials into just Credentials * Removes concept of resetting WalletGateway * Fix issue w/ ESLint going in crazy loop of fixes * Adds missing file * Removes wallet storage and merge WalletFactory into WalletGateway * Removes unused mock helper * Fix linting issue * Nukes *-v1 packages --- packages/api-bindings-v1/.eslintignore | 2 - packages/api-bindings-v1/.eslintrc.cjs | 22 - packages/api-bindings-v1/.prettierignore | 2 - packages/api-bindings-v1/CHANGELOG.md | 415 - packages/api-bindings-v1/README.md | 9 - packages/api-bindings-v1/TROUBLESHOOTING.md | 26 - packages/api-bindings-v1/codegen-api.yml | 137 - packages/api-bindings-v1/jest.config.ts | 5 - packages/api-bindings-v1/mocks/package.json | 5 - packages/api-bindings-v1/package.json | 93 - packages/api-bindings-v1/src/SemVer.tsx | 8 - .../api-bindings-v1/src/__helpers__/mocks.ts | 19 - .../src/apollo/IAccessTokenStorage.ts | 4 - .../src/apollo/IGraphQLClient.ts | 54 - .../src/apollo/SafeApolloClient.ts | 141 - .../src/apollo/__helpers__/mocks.ts | 118 - .../apollo/__tests__/SafeApolloClient.spec.ts | 184 - .../src/apollo/__tests__/links.spec.ts | 97 - .../src/apollo/cache/__helpers__/mocks.ts | 48 - .../cache/__tests__/ApolloCache.spec.ts | 643 - .../apollo/cache/createAttributeTypePolicy.ts | 5 - .../cache/createExploreProfileFieldPolicy.ts | 5 - .../createExplorePublicationsFieldPolicy.ts | 19 - .../src/apollo/cache/createFeedFieldPolicy.ts | 8 - .../src/apollo/cache/createLensCache.ts | 118 - .../apollo/cache/createMediaSetTypePolicy.ts | 10 - .../src/apollo/cache/createMediaTypePolicy.ts | 5 - .../apollo/cache/createNftImageTypePolicy.ts | 5 - .../cache/createNotificationsFieldPolicy.ts | 8 - .../apollo/cache/createProfileFieldPolicy.ts | 53 - .../createProfileFollowersFieldPolicy.ts | 5 - .../createProfileFollowingFieldPolicy.ts | 5 - ...ateProfilePublicationRevenueFieldPolicy.ts | 5 - ...teProfilePublicationsForSaleFieldPolicy.ts | 5 - .../apollo/cache/createProfileTypePolicy.ts | 171 - .../apollo/cache/createProfilesFieldPolicy.ts | 9 - .../cache/createPublicationsFieldPolicy.ts | 22 - .../createPublicationsProfileBookmarks.ts | 5 - .../cache/createRevenueAggregateTypePolicy.ts | 15 - .../apollo/cache/createSearchFieldPolicy.ts | 5 - .../src/apollo/cache/createSnapshotCache.ts | 5 - .../createWhoReactedPublicationFieldPolicy.ts | 5 - .../src/apollo/cache/decryptionCriteria.ts | 259 - .../api-bindings-v1/src/apollo/cache/index.ts | 2 - .../src/apollo/cache/publication.ts | 245 - .../src/apollo/cache/session.ts | 116 - .../src/apollo/cache/transactions.ts | 185 - .../ContentInsight/__tests__/matchers.spec.ts | 48 - .../cache/utils/ContentInsight/index.ts | 1 - .../cache/utils/ContentInsight/matchers.ts | 37 - .../apollo/cache/utils/__helpers__/mocks.ts | 82 - .../__tests__/cursorBasedPagination.spec.ts | 274 - .../cache/utils/__tests__/extractUrls.spec.ts | 43 - .../cache/utils/__tests__/firstMatch.spec.ts | 55 - .../cache/utils/cursorBasedPagination.ts | 113 - .../src/apollo/cache/utils/extractUrls.ts | 7 - .../src/apollo/cache/utils/firstMatch.ts | 18 - .../src/apollo/cache/utils/noCachedField.ts | 8 - .../apollo/cache/utils/notNormalizedType.ts | 17 - .../src/apollo/cache/utils/observedBy.ts | 9 - .../api-bindings-v1/src/apollo/errors.tsx | 17 - packages/api-bindings-v1/src/apollo/index.ts | 82 - .../src/apollo/isGraphQLValidationError.ts | 26 - packages/api-bindings-v1/src/apollo/links.ts | 115 - packages/api-bindings-v1/src/constants.ts | 3 - packages/api-bindings-v1/src/index.ts | 15 - .../api-bindings-v1/src/lens/CollectPolicy.ts | 157 - .../src/lens/ContentEncryptionKey.ts | 2 - .../src/lens/ContentInsight.ts | 50 - packages/api-bindings-v1/src/lens/Cursor.ts | 7 - .../api-bindings-v1/src/lens/FollowPolicy.ts | 20 - .../api-bindings-v1/src/lens/FollowStatus.ts | 31 - .../src/lens/ImageSizeTransform.ts | 34 - .../src/lens/ProfileAttributeReader.ts | 44 - .../src/lens/ProfileAttributes.ts | 3 - .../src/lens/ReferencePolicy.ts | 26 - .../src/lens/__helpers__/fragments.ts | 773 - .../src/lens/__helpers__/index.ts | 3 - .../src/lens/__helpers__/mutations.ts | 891 -- .../src/lens/__helpers__/queries.ts | 597 - .../api-bindings-v1/src/lens/auth.graphql | 19 - .../api-bindings-v1/src/lens/client.graphql | 76 - .../src/lens/collect-typed-data.graphql | 24 - .../api-bindings-v1/src/lens/comment.graphql | 58 - .../api-bindings-v1/src/lens/common.graphql | 610 - .../src/lens/currencies.graphql | 5 - .../api-bindings-v1/src/lens/feed.graphql | 113 - .../src/lens/follow-typed-data.graphql | 23 - .../api-bindings-v1/src/lens/gated.graphql | 143 - .../api-bindings-v1/src/lens/generated.ts | 12696 ---------------- packages/api-bindings-v1/src/lens/index.ts | 139 - .../api-bindings-v1/src/lens/mirror.graphql | 53 - .../api-bindings-v1/src/lens/modules.graphql | 39 - .../src/lens/notification.graphql | 160 - .../api-bindings-v1/src/lens/post.graphql | 53 - .../src/lens/profile-dispatcher.graphql | 26 - .../src/lens/profile-guardian.graphql | 10 - .../api-bindings-v1/src/lens/profile.graphql | 338 - .../lens/profiles-followers-following.graphql | 49 - .../src/lens/proxy-actions.graphql | 36 - .../src/lens/publication.graphql | 42 - .../src/lens/publications.graphql | 181 - .../src/lens/reactions.graphql | 50 - .../src/lens/report-publication.graphql | 13 - .../api-bindings-v1/src/lens/revenue.graphql | 85 - .../api-bindings-v1/src/lens/search.graphql | 51 - packages/api-bindings-v1/src/lens/snapshot.ts | 197 - packages/api-bindings-v1/src/lens/sources.ts | 3 - .../src/lens/transactions.graphql | 71 - .../src/lens/unfollow-typed-data.graphql | 22 - .../utils/__tests__/isValidHandle.spec.ts | 27 - .../lens/utils/__tests__/publication.spec.ts | 26 - .../api-bindings-v1/src/lens/utils/amount.ts | 15 - .../api-bindings-v1/src/lens/utils/index.ts | 7 - .../src/lens/utils/isValidHandle.ts | 8 - .../src/lens/utils/omitTypename.ts | 9 - .../api-bindings-v1/src/lens/utils/profile.ts | 19 - .../src/lens/utils/publication.ts | 532 - .../api-bindings-v1/src/lens/utils/types.ts | 18 - packages/api-bindings-v1/src/metadata.ts | 91 - packages/api-bindings-v1/src/mocks.ts | 6 - .../src/snapshot/__helpers__/fragments.ts | 54 - .../src/snapshot/__helpers__/index.ts | 2 - .../src/snapshot/__helpers__/queries.ts | 30 - .../api-bindings-v1/src/snapshot/generated.ts | 370 - .../api-bindings-v1/src/snapshot/index.ts | 52 - .../src/snapshot/proposals.graphql | 57 - packages/api-bindings-v1/tsconfig.json | 10 - packages/api-bindings-v1/tsdoc.json | 4 - packages/domain/src/entities/Credentials.ts | 6 +- .../domain/src/entities/__helpers__/mocks.ts | 14 +- .../use-cases/authentication/ActiveWallet.ts | 19 +- .../src/use-cases/authentication/Bootstrap.ts | 6 +- .../authentication/ICredentialsWriter.ts | 4 +- .../src/use-cases/authentication/Login.ts | 16 +- .../src/use-cases/authentication/Logout.ts | 14 +- .../authentication/UpgradeCredentials.ts | 4 +- .../__tests__/ActiveWallet.spec.ts | 26 +- .../__tests__/Bootstrap.spec.ts | 8 +- .../authentication/__tests__/Login.spec.ts | 71 +- .../authentication/__tests__/Logout.spec.ts | 22 +- .../src/use-cases/profile/CreateProfile.ts | 6 +- .../profile/__tests__/CreateProfile.spec.ts | 8 +- .../src/use-cases/wallets/IWalletFactory.ts | 7 - .../src/use-cases/wallets/IWalletGateway.ts | 5 + .../domain/src/use-cases/wallets/index.ts | 2 +- packages/react-v1/.eslintignore | 3 - packages/react-v1/.eslintrc.cjs | 49 - packages/react-v1/.prettierignore | 2 - packages/react-v1/CHANGELOG.md | 816 - packages/react-v1/README.md | 41 - packages/react-v1/jest.config.ts | 9 - packages/react-v1/package.json | 57 - packages/react-v1/src/ConsoleLogger.ts | 24 - packages/react-v1/src/ErrorHandler.ts | 4 - packages/react-v1/src/LensProvider.tsx | 87 - packages/react-v1/src/NotFoundError.ts | 7 - .../react-v1/src/__helpers__/jest.setup.ts | 18 - .../src/__helpers__/testing-library.tsx | 28 - .../react-v1/src/__tests__/config.spec.ts | 81 - packages/react-v1/src/chains.ts | 65 - packages/react-v1/src/config.ts | 91 - packages/react-v1/src/deprecated.ts | 314 - packages/react-v1/src/environments.ts | 164 - packages/react-v1/src/experimental/index.ts | 2 - .../src/experimental/useAccessToken.ts | 13 - .../src/experimental/useApolloClient.ts | 36 - .../react-v1/src/feed/FeedEventItemType.ts | 9 - .../src/feed/__tests__/useFeed.spec.ts | 115 - packages/react-v1/src/feed/index.ts | 10 - packages/react-v1/src/feed/useFeed.ts | 104 - .../src/helpers/__tests__/operations.spec.ts | 85 - .../src/helpers/__tests__/reads.spec.ts | 125 - packages/react-v1/src/helpers/arguments.ts | 144 - packages/react-v1/src/helpers/operations.ts | 54 - packages/react-v1/src/helpers/reads.ts | 248 - .../adapters/DisableConversationsGateway.ts | 10 - packages/react-v1/src/inbox/index.ts | 2 - .../inbox/infrastructure/InboxKeyStorage.ts | 14 - packages/react-v1/src/index.ts | 155 - .../__tests__/useCurrentSession.spec.ts | 191 - .../lifecycle/adapters/SessionPresenter.ts | 48 - .../__tests__/SessionPresenter.spec.ts | 93 - .../adapters/useBootstrapController.ts | 31 - packages/react-v1/src/lifecycle/index.ts | 2 - .../src/lifecycle/useCurrentSession.ts | 185 - packages/react-v1/src/mediaTransforms.ts | 51 - .../modules/__tests__/useCurrencies.spec.ts | 28 - .../__tests__/useEnabledModules.spec.ts | 28 - packages/react-v1/src/modules/index.ts | 4 - .../react-v1/src/modules/useCurrencies.ts | 68 - .../react-v1/src/modules/useEnabledModules.ts | 12 - packages/react-v1/src/notifications/index.ts | 12 - .../src/notifications/useNotifications.ts | 97 - .../useUnreadNotificationCount.ts | 119 - .../src/polls/adapters/SnapshotVoteFactory.ts | 232 - .../src/polls/adapters/SnapshotVoteRelayer.ts | 44 - .../src/polls/adapters/__helpers__/mocks.ts | 8 - .../__tests__/SnapshotVoteFactory.spec.ts | 284 - .../__tests__/SnapshotVoteRelayer.spec.ts | 99 - packages/react-v1/src/polls/adapters/types.ts | 77 - .../polls/adapters/useVotePollController.ts | 45 - packages/react-v1/src/polls/index.ts | 10 - packages/react-v1/src/polls/usePollDetails.ts | 255 - packages/react-v1/src/polls/usePollVote.ts | 69 - .../__tests__/useActiveProfile.spec.ts | 93 - .../__tests__/useExploreProfiles.spec.ts | 102 - .../__tests__/useMutualFollowers.spec.ts | 58 - .../src/profile/__tests__/useProfile.spec.ts | 125 - .../src/profile/__tests__/useProfiles.spec.ts | 110 - .../__tests__/useProfilesOwnedBy.spec.ts | 104 - .../__tests__/useProfilesOwnedByMe.spec.ts | 110 - .../__tests__/useProfilesToFollow.spec.ts | 93 - .../__tests__/useSearchProfiles.spec.ts | 99 - .../profile/adapters/ActiveProfileGateway.ts | 35 - .../adapters/CreateProfilePresenter.ts | 59 - .../src/profile/adapters/ProfileGateway.ts | 53 - .../adapters/ProfileTransactionGateway.ts | 64 - .../__tests__/ActiveProfileGateway.spec.ts | 20 - .../__tests__/CreateProfilePresenter.spec.ts | 88 - .../adapters/__tests__/ProfileGateway.spec.ts | 94 - .../ProfileTransactionGateway.spec.ts | 176 - .../adapters/useCreateProfileController.ts | 20 - .../useSwitchActiveProfileController.ts | 20 - packages/react-v1/src/profile/index.ts | 68 - .../infrastructure/ActiveProfileStorage.ts | 11 - .../react-v1/src/profile/useActiveProfile.ts | 68 - .../src/profile/useActiveProfileSwitch.ts | 61 - .../src/profile/useCollectedPublications.ts | 49 - .../react-v1/src/profile/useCreateProfile.ts | 143 - .../src/profile/useExploreProfiles.ts | 68 - .../src/profile/useMutualFollowers.ts | 35 - packages/react-v1/src/profile/useProfile.ts | 96 - .../src/profile/useProfileFollowers.ts | 40 - .../src/profile/useProfileFollowing.ts | 43 - .../src/profile/useProfileGuardian.ts | 70 - packages/react-v1/src/profile/useProfiles.ts | 113 - .../src/profile/useProfilesOwnedBy.ts | 44 - .../src/profile/useProfilesOwnedByMe.ts | 75 - .../src/profile/useProfilesToFollow.ts | 59 - .../react-v1/src/profile/useSearchProfiles.ts | 70 - .../src/publication/__tests__/filters.spec.ts | 25 - .../__tests__/useBookmarkToggle.spec.ts | 146 - .../__tests__/useEncryptedPublication.spec.ts | 119 - .../__tests__/useExplorePublications.spec.ts | 117 - .../__tests__/useMyBookmarks.spec.ts | 129 - .../__tests__/useNotInterested.spec.ts | 146 - .../useProfilePublicationsForSale.spec.ts | 104 - .../__tests__/usePublication.spec.ts | 199 - .../__tests__/usePublications.spec.ts | 170 - .../publication/__tests__/useReaction.spec.ts | 121 - .../__tests__/useSearchPublications.spec.ts | 102 - .../useWhoCollectedPublication.spec.ts | 101 - .../useWhoMirroredPublication.spec.ts | 104 - .../__tests__/useWhoReacted.spec.ts | 101 - .../publication/adapters/BookmarksGateway.ts | 43 - .../adapters/BookmarksPresenter.ts | 38 - .../adapters/HidePublicationGateway.ts | 23 - .../adapters/HidePublicationPresenter.ts | 12 - .../adapters/NotInterestedGateway.ts | 43 - .../adapters/NotInterestedPresenter.ts | 38 - .../publication/adapters/ReactionGateway.ts | 70 - .../publication/adapters/ReactionPresenter.ts | 66 - .../adapters/ReportPublicationGateway.ts | 156 - .../publication/adapters/__helpers__/mocks.ts | 13 - .../__tests__/HidePublicationGateway.spec.ts | 30 - .../HidePublicationPresenter.spec.ts | 70 - .../__tests__/ReactionGateway.spec.ts | 130 - .../__tests__/ReactionPresenter.spec.ts | 170 - .../ReportPublicationGateway.spec.ts | 210 - .../adapters/useBookmarkToggleController.ts | 30 - .../adapters/useHidePublicationController.ts | 22 - .../adapters/useNotInterestedController.ts | 30 - .../adapters/useReactionController.ts | 30 - .../useReportPublicationController.ts | 23 - packages/react-v1/src/publication/filters.ts | 64 - packages/react-v1/src/publication/index.ts | 171 - .../src/publication/useBookmarkToggle.ts | 84 - .../react-v1/src/publication/useComments.ts | 68 - .../publication/useEncryptedPublication.ts | 125 - .../src/publication/useExplorePublications.ts | 126 - .../src/publication/useHidePublication.ts | 33 - .../src/publication/useMyBookmarks.ts | 67 - .../src/publication/useNotInterested.ts | 84 - .../useProfilePublicationsForSale.ts | 47 - .../src/publication/usePublication.ts | 74 - .../src/publication/usePublications.ts | 87 - .../react-v1/src/publication/useReaction.ts | 64 - .../src/publication/useReportPublication.ts | 34 - .../src/publication/useSearchPublications.ts | 75 - .../publication/useWhoCollectedPublication.ts | 43 - .../publication/useWhoMirroredPublication.ts | 45 - .../react-v1/src/publication/useWhoReacted.ts | 39 - .../__tests__/useProfileFollowRevenue.spec.ts | 34 - .../useProfilePublicationRevenue.spec.ts | 104 - .../__tests__/usePublicationRevenue.spec.ts | 113 - packages/react-v1/src/revenue/index.ts | 5 - .../src/revenue/useProfileFollowRevenue.ts | 52 - .../revenue/useProfilePublicationRevenue.ts | 51 - .../src/revenue/usePublicationRevenue.ts | 74 - packages/react-v1/src/shared.tsx | 301 - packages/react-v1/src/sources.ts | 8 - .../adapters/ApproveTransactionGateway.ts | 104 - .../adapters/AsyncTransactionResult.ts | 9 - .../adapters/CollectPublicationGateway.ts | 151 - .../adapters/CreateCommentController.ts | 106 - .../adapters/CreatePostController.ts | 97 - .../adapters/CreatePostPresenter.ts | 61 - .../adapters/DispatcherConfigCallGateway.ts | 62 - .../adapters/FollowPolicyCallGateway.ts | 95 - .../adapters/FollowProfilesGateway.ts | 186 - .../adapters/IMetadataUploader.ts | 9 - .../adapters/IProfileCacheManager.ts | 12 - .../adapters/ITransactionFactory.ts | 60 - .../IUpdatePublicationCacheManager.ts | 9 - .../adapters/MetadataUploadHandler.ts | 11 - .../transactions/adapters/OffChainRelayer.ts | 80 - .../transactions/adapters/OnChainRelayer.ts | 85 - .../ISerializableTransactionFactory.ts | 57 - .../PendingTransactionGateway.ts | 221 - .../PendingTransactionGateway.spec.ts | 297 - .../PendingTransactionGateway/index.ts | 7 - .../adapters/ProfileImageCallGateway.ts | 152 - .../ProfileMetadataCallGateway.ts | 177 - .../ProfileMetadataCallGateway.spec.ts | 213 - .../__tests__/createProfileMetadata.spec.ts | 168 - .../createProfileMetadata.ts | 87 - .../ProfileMetadataCallGateway/index.ts | 1 - .../adapters/PromiseResultPresenter.tsx | 16 - .../src/transactions/adapters/ProxyReceipt.ts | 3 - .../adapters/PublicationCacheManager.ts | 90 - .../adapters/SelfFundedProtocolCallGateway.ts | 68 - .../SelfFundedProtocolTransactionRequest.ts | 16 - .../adapters/TransactionQueuePresenter.tsx | 86 - .../adapters/TransactionResultPresenter.ts | 50 - .../adapters/UnfollowProfileCallGateway.ts | 55 - .../adapters/__helpers__/mocks.ts | 189 - .../ApproveTransactionGateway.spec.ts | 126 - .../CollectPublicationGateway.spec.ts | 228 - .../__tests__/CreatePostPresenter.spec.ts | 84 - .../DispatcherConfigCallGateway.spec.ts | 90 - .../__tests__/FollowPolicyCallGateway.spec.ts | 128 - .../__tests__/FollowProfilesGateway.spec.ts | 305 - .../__tests__/OffChainRelayer.spec.ts | 76 - .../adapters/__tests__/OnChainRelayer.spec.ts | 76 - .../__tests__/ProfileImageCallGateway.spec.ts | 164 - .../__tests__/PromiseResultPresenter.spec.ts | 29 - .../__tests__/PublicationCacheManager.spec.ts | 153 - .../SelfFundedProtocolCallGateway.spec.ts | 51 - .../TransactionQueuePresenter.spec.ts | 106 - .../UnfollowProfileCallGateway.spec.ts | 58 - .../CreateOffChainCommentGateway.ts | 152 - .../CreateOffChainMirrorGateway.ts | 136 - .../CreateOffChainPostGateway.ts | 147 - .../CreateOnChainCommentGateway.ts | 162 - .../CreateOnChainMirrorGateway.ts | 152 - .../CreateOnChainPostGateway.ts | 157 - .../CreateOffChainCommentGateway.spec.ts | 144 - .../CreateOffChainMirrorGateway.spec.ts | 123 - .../CreateOffChainPostGateway.spec.ts | 140 - .../CreateOnChainCommentGateway.spec.ts | 190 - .../CreateOnChainMirrorGateway.spec.ts | 123 - .../CreateOnChainPostGateway.spec.ts | 181 - .../resolveCollectModuleParams.spec.ts | 407 - .../resolveReferenceModuleParams.spec.ts | 65 - .../resolveCollectModuleParams.ts | 146 - .../resolveReferenceModuleParams.ts | 24 - .../src/transactions/adapters/relayer.ts | 30 - .../CollectPublicationResponder.tsx | 72 - .../responders/CreateMirrorResponder.ts | 72 - .../responders/CreatePostResponder.ts | 104 - .../responders/CreateProfileResponder.ts | 25 - .../responders/FollowProfilesResponder.tsx | 96 - .../adapters/responders/NoopResponder.ts | 12 - .../responders/UnfollowProfileResponder.ts | 30 - .../UpdateDispatcherConfigResponder.ts | 17 - .../responders/UpdateFollowPolicyResponder.ts | 29 - .../responders/UpdateProfileImageResponder.ts | 67 - .../UpdateProfileMetadataResponder.ts | 107 - .../CollectPublicationResponder.spec.ts | 243 - .../__tests__/CreateMirrorResponder.spec.ts | 185 - .../__tests__/CreatePostResponder.spec.ts | 153 - .../__tests__/FollowProfilesResponder.spec.ts | 114 - .../UnfollowProfileResponder.spec.ts | 83 - .../UpdateDispatcherConfigResponder.spec.ts | 46 - .../UpdateFollowPolicyResponder.spec.ts | 71 - .../UpdateProfileImageResponder.spec.ts | 68 - .../UpdateProfileMetadataResponder.spec.ts | 96 - .../schemas/__tests__/Erc20Amount.spec.ts | 25 - .../schemas/__tests__/formatters.spec.ts | 57 - .../schemas/__tests__/validators.spec.ts | 653 - .../transactions/adapters/schemas/common.ts | 62 - .../transactions/adapters/schemas/erc20.ts | 16 - .../adapters/schemas/formatters.ts | 102 - .../transactions/adapters/schemas/profiles.ts | 122 - .../adapters/schemas/publications.ts | 408 - .../adapters/schemas/transactions.ts | 181 - .../adapters/schemas/validators.ts | 70 - .../adapters/useApproveModuleController.ts | 37 - .../adapters/useCollectController.ts | 80 - .../adapters/useCreateCommentController.ts | 41 - .../useCreateEncryptedCommentController.ts | 78 - .../useCreateEncryptedPostController.ts | 80 - .../adapters/useCreateMirrorController.tsx | 76 - .../adapters/useCreatePostController.ts | 43 - .../adapters/useFollowController.ts | 80 - .../adapters/usePayTransactionController.ts | 35 - .../adapters/useUnfollowController.ts | 38 - .../useUpdateDispatcherConfigController.ts | 39 - .../useUpdateFollowPolicyController.ts | 45 - .../useUpdateProfileDetailsController.ts | 75 - .../useUpdateProfileImageController.ts | 54 - packages/react-v1/src/transactions/index.ts | 124 - .../AccessConditionBuilderFactory.ts | 201 - .../Eip1559GasPriceEstimator.ts | 119 - .../EncryptedPublicationMetadataUploader.ts | 67 - .../MetadataUploaderErrorMiddleware.ts | 40 - .../infrastructure/ProfileCacheManager.ts | 104 - .../infrastructure/PublicationIdPredictor.ts | 77 - .../PublicationMetadataUploader.ts | 27 - .../infrastructure/TransactionFactory.ts | 451 - .../infrastructure/TransactionObserver.ts | 199 - .../infrastructure/TransactionStorage.ts | 8 - .../infrastructure/__helpers__/mocks.ts | 133 - .../AccessConditionBuilderFactory.spec.ts | 280 - .../Eip1559GasPriceEstimator.spec.ts | 91 - ...cryptedPublicationMetadataUploader.spec.ts | 120 - .../MetadataUploaderErrorMiddleware.spec.ts | 41 - .../__tests__/ProfileCacheManager.spec.ts | 193 - .../__tests__/PublicationIdPredictor.spec.ts | 119 - .../PublicationMetadataUploader.spec.ts | 38 - .../__tests__/TransactionFactory.spec.ts | 364 - .../__tests__/TransactionObserver.spec.ts | 461 - .../createPublicationMetadata.spec.ts | 326 - .../infrastructure/createGatedClient.ts | 29 - .../createPublicationMetadata.ts | 169 - .../src/transactions/useApproveModule.ts | 124 - .../src/transactions/useClearRecentPosts.ts | 11 - .../react-v1/src/transactions/useCollect.ts | 43 - .../src/transactions/useCreateComment.ts | 272 - .../transactions/useCreateEncryptedComment.ts | 96 - .../transactions/useCreateEncryptedPost.ts | 104 - .../src/transactions/useCreateMirror.ts | 50 - .../src/transactions/useCreatePost.ts | 275 - .../react-v1/src/transactions/useFollow.ts | 176 - .../src/transactions/useRecentPosts.ts | 11 - .../src/transactions/useRecentTransactions.ts | 58 - .../src/transactions/useSelfFundedFallback.ts | 90 - .../react-v1/src/transactions/useUnfollow.ts | 72 - .../transactions/useUpdateDispatcherConfig.ts | 63 - .../src/transactions/useUpdateFollowPolicy.ts | 45 - .../transactions/useUpdateProfileDetails.ts | 74 - .../src/transactions/useUpdateProfileImage.ts | 42 - packages/react-v1/src/utils.ts | 33 - .../src/wallet/adapters/BalanceGateway.ts | 23 - .../src/wallet/adapters/ConcreteWallet.ts | 324 - .../src/wallet/adapters/Credentials.ts | 68 - .../adapters/CredentialsExpiryController.ts | 21 - .../src/wallet/adapters/CredentialsFactory.ts | 43 - .../src/wallet/adapters/CredentialsGateway.ts | 20 - .../src/wallet/adapters/IProviderFactory.ts | 10 - .../src/wallet/adapters/TokenGateway.ts | 27 - .../src/wallet/adapters/WalletFactory.ts | 21 - .../src/wallet/adapters/WalletGateway.ts | 62 - .../wallet/adapters/WalletLoginPresenter.ts | 30 - .../src/wallet/adapters/__helpers__/mocks.ts | 156 - .../adapters/__tests__/ConcreteWallet.spec.ts | 376 - .../adapters/__tests__/Credentials.spec.ts | 93 - .../__tests__/CredentialsFactory.spec.ts | 99 - .../__tests__/CredentialsGateway.spec.ts | 41 - .../adapters/__tests__/WalletGateway.spec.ts | 74 - .../__tests__/WalletLoginPresenter.spec.ts | 48 - .../react-v1/src/wallet/adapters/errors.ts | 11 - .../adapters/useWalletLoginController.ts | 36 - .../adapters/useWalletLogoutController.ts | 14 - packages/react-v1/src/wallet/index.ts | 10 - .../infrastructure/AccessTokenStorage.ts | 67 - .../src/wallet/infrastructure/AuthApi.ts | 51 - .../infrastructure/CredentialsStorage.ts | 69 - .../infrastructure/NotificationStorage.ts | 16 - .../wallet/infrastructure/ProviderFactory.ts | 32 - .../wallet/infrastructure/SignerFactory.ts | 109 - .../wallet/infrastructure/WalletStorage.ts | 11 - .../infrastructure/__helpers__/mocks.ts | 36 - .../__tests__/ProviderFactory.spec.ts | 58 - .../__tests__/SignerFactory.spec.ts | 156 - .../react-v1/src/wallet/useActiveWallet.ts | 50 - .../src/wallet/useActiveWalletSigner.ts | 60 - .../react-v1/src/wallet/useWalletLogin.ts | 87 - .../react-v1/src/wallet/useWalletLogout.ts | 28 - packages/react-v1/tsconfig.json | 10 - packages/react-v1/tsdoc.json | 4 - packages/react-web-v1/.eslintignore | 2 - packages/react-web-v1/.eslintrc.cjs | 48 - packages/react-web-v1/.prettierignore | 2 - packages/react-web-v1/CHANGELOG.md | 624 - packages/react-web-v1/README.md | 11 - packages/react-web-v1/inbox/package.json | 4 - packages/react-web-v1/jest.config.ts | 8 - packages/react-web-v1/package.json | 65 - packages/react-web-v1/src/LensProvider.tsx | 114 - .../src/__helpers__/jest.setup.ts | 18 - .../src/__tests__/storage.spec.ts | 115 - packages/react-web-v1/src/globals.ts | 10 - .../src/inbox/adapters/SignerAdapter.ts | 48 - .../__tests__/conversationIdUtils.spec.ts | 30 - .../src/inbox/helpers/conversationIdUtils.ts | 44 - .../helpers/createUniqueConversationId.ts | 10 - .../react-web-v1/src/inbox/helpers/index.ts | 3 - .../src/inbox/helpers/notEmpty.ts | 3 - packages/react-web-v1/src/inbox/index.ts | 5 - packages/react-web-v1/src/inbox/types.ts | 6 - .../src/inbox/useEnhanceConversation.ts | 76 - .../src/inbox/useEnhanceConversations.ts | 129 - .../src/inbox/useStartLensConversation.ts | 36 - .../react-web-v1/src/inbox/useXmtpClient.ts | 108 - packages/react-web-v1/src/index.ts | 25 - packages/react-web-v1/src/storage.ts | 74 - .../src/useBrowserEncryptionConfig.ts | 15 - .../src/useCreateEncryptedComment.ts | 24 - .../src/useCreateEncryptedPost.ts | 24 - .../src/useEncryptedPublication.ts | 21 - packages/react-web-v1/tsconfig.json | 9 - packages/react-web-v1/tsdoc.json | 4 - .../adapters/AccessTokenStorage.ts | 4 +- .../src/authentication/adapters/AuthApi.ts | 18 +- .../adapters/CredentialsFactory.ts | 14 +- .../adapters/CredentialsGateway.ts | 8 +- .../adapters/CredentialsStorage.ts | 16 +- .../adapters/CredentialsUpgrader.ts | 6 +- .../{Credentials.ts => JwtCredentials.ts} | 17 +- .../adapters/__helpers__/mocks.ts | 6 +- .../__tests__/CredentialsFactory.spec.ts | 6 +- .../__tests__/CredentialsGateway.spec.ts | 8 +- .../adapters/useLoginController.ts | 17 +- packages/react/src/shared.tsx | 9 +- .../adapters/useCreateProfileController.ts | 4 +- .../src/wallet/adapters/WalletFactory.ts | 22 - .../src/wallet/adapters/WalletGateway.ts | 56 +- .../src/wallet/adapters/__helpers__/mocks.ts | 12 +- .../adapters/__tests__/WalletGateway.spec.ts | 77 +- .../wallet/infrastructure/WalletStorage.ts | 11 - pnpm-lock.yaml | 101 - 543 files changed, 174 insertions(+), 57871 deletions(-) delete mode 100644 packages/api-bindings-v1/.eslintignore delete mode 100644 packages/api-bindings-v1/.eslintrc.cjs delete mode 100644 packages/api-bindings-v1/.prettierignore delete mode 100644 packages/api-bindings-v1/CHANGELOG.md delete mode 100644 packages/api-bindings-v1/README.md delete mode 100644 packages/api-bindings-v1/TROUBLESHOOTING.md delete mode 100644 packages/api-bindings-v1/codegen-api.yml delete mode 100644 packages/api-bindings-v1/jest.config.ts delete mode 100644 packages/api-bindings-v1/mocks/package.json delete mode 100644 packages/api-bindings-v1/package.json delete mode 100644 packages/api-bindings-v1/src/SemVer.tsx delete mode 100644 packages/api-bindings-v1/src/__helpers__/mocks.ts delete mode 100644 packages/api-bindings-v1/src/apollo/IAccessTokenStorage.ts delete mode 100644 packages/api-bindings-v1/src/apollo/IGraphQLClient.ts delete mode 100644 packages/api-bindings-v1/src/apollo/SafeApolloClient.ts delete mode 100644 packages/api-bindings-v1/src/apollo/__helpers__/mocks.ts delete mode 100644 packages/api-bindings-v1/src/apollo/__tests__/SafeApolloClient.spec.ts delete mode 100644 packages/api-bindings-v1/src/apollo/__tests__/links.spec.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/__helpers__/mocks.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/__tests__/ApolloCache.spec.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createAttributeTypePolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createExploreProfileFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createExplorePublicationsFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createFeedFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createLensCache.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createMediaSetTypePolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createMediaTypePolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createNftImageTypePolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createNotificationsFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createProfileFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createProfileFollowersFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createProfileFollowingFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createProfilePublicationRevenueFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createProfilePublicationsForSaleFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createProfileTypePolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createProfilesFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createPublicationsFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createPublicationsProfileBookmarks.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createRevenueAggregateTypePolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createSearchFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createSnapshotCache.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/createWhoReactedPublicationFieldPolicy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/decryptionCriteria.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/index.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/publication.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/session.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/transactions.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/__tests__/matchers.spec.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/index.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/matchers.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/__helpers__/mocks.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/__tests__/cursorBasedPagination.spec.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/__tests__/extractUrls.spec.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/__tests__/firstMatch.spec.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/cursorBasedPagination.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/extractUrls.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/firstMatch.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/noCachedField.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/notNormalizedType.ts delete mode 100644 packages/api-bindings-v1/src/apollo/cache/utils/observedBy.ts delete mode 100644 packages/api-bindings-v1/src/apollo/errors.tsx delete mode 100644 packages/api-bindings-v1/src/apollo/index.ts delete mode 100644 packages/api-bindings-v1/src/apollo/isGraphQLValidationError.ts delete mode 100644 packages/api-bindings-v1/src/apollo/links.ts delete mode 100644 packages/api-bindings-v1/src/constants.ts delete mode 100644 packages/api-bindings-v1/src/index.ts delete mode 100644 packages/api-bindings-v1/src/lens/CollectPolicy.ts delete mode 100644 packages/api-bindings-v1/src/lens/ContentEncryptionKey.ts delete mode 100644 packages/api-bindings-v1/src/lens/ContentInsight.ts delete mode 100644 packages/api-bindings-v1/src/lens/Cursor.ts delete mode 100644 packages/api-bindings-v1/src/lens/FollowPolicy.ts delete mode 100644 packages/api-bindings-v1/src/lens/FollowStatus.ts delete mode 100644 packages/api-bindings-v1/src/lens/ImageSizeTransform.ts delete mode 100644 packages/api-bindings-v1/src/lens/ProfileAttributeReader.ts delete mode 100644 packages/api-bindings-v1/src/lens/ProfileAttributes.ts delete mode 100644 packages/api-bindings-v1/src/lens/ReferencePolicy.ts delete mode 100644 packages/api-bindings-v1/src/lens/__helpers__/fragments.ts delete mode 100644 packages/api-bindings-v1/src/lens/__helpers__/index.ts delete mode 100644 packages/api-bindings-v1/src/lens/__helpers__/mutations.ts delete mode 100644 packages/api-bindings-v1/src/lens/__helpers__/queries.ts delete mode 100644 packages/api-bindings-v1/src/lens/auth.graphql delete mode 100644 packages/api-bindings-v1/src/lens/client.graphql delete mode 100644 packages/api-bindings-v1/src/lens/collect-typed-data.graphql delete mode 100644 packages/api-bindings-v1/src/lens/comment.graphql delete mode 100644 packages/api-bindings-v1/src/lens/common.graphql delete mode 100644 packages/api-bindings-v1/src/lens/currencies.graphql delete mode 100644 packages/api-bindings-v1/src/lens/feed.graphql delete mode 100644 packages/api-bindings-v1/src/lens/follow-typed-data.graphql delete mode 100644 packages/api-bindings-v1/src/lens/gated.graphql delete mode 100644 packages/api-bindings-v1/src/lens/generated.ts delete mode 100644 packages/api-bindings-v1/src/lens/index.ts delete mode 100644 packages/api-bindings-v1/src/lens/mirror.graphql delete mode 100644 packages/api-bindings-v1/src/lens/modules.graphql delete mode 100644 packages/api-bindings-v1/src/lens/notification.graphql delete mode 100644 packages/api-bindings-v1/src/lens/post.graphql delete mode 100644 packages/api-bindings-v1/src/lens/profile-dispatcher.graphql delete mode 100644 packages/api-bindings-v1/src/lens/profile-guardian.graphql delete mode 100644 packages/api-bindings-v1/src/lens/profile.graphql delete mode 100644 packages/api-bindings-v1/src/lens/profiles-followers-following.graphql delete mode 100644 packages/api-bindings-v1/src/lens/proxy-actions.graphql delete mode 100644 packages/api-bindings-v1/src/lens/publication.graphql delete mode 100644 packages/api-bindings-v1/src/lens/publications.graphql delete mode 100644 packages/api-bindings-v1/src/lens/reactions.graphql delete mode 100644 packages/api-bindings-v1/src/lens/report-publication.graphql delete mode 100644 packages/api-bindings-v1/src/lens/revenue.graphql delete mode 100644 packages/api-bindings-v1/src/lens/search.graphql delete mode 100644 packages/api-bindings-v1/src/lens/snapshot.ts delete mode 100644 packages/api-bindings-v1/src/lens/sources.ts delete mode 100644 packages/api-bindings-v1/src/lens/transactions.graphql delete mode 100644 packages/api-bindings-v1/src/lens/unfollow-typed-data.graphql delete mode 100644 packages/api-bindings-v1/src/lens/utils/__tests__/isValidHandle.spec.ts delete mode 100644 packages/api-bindings-v1/src/lens/utils/__tests__/publication.spec.ts delete mode 100644 packages/api-bindings-v1/src/lens/utils/amount.ts delete mode 100644 packages/api-bindings-v1/src/lens/utils/index.ts delete mode 100644 packages/api-bindings-v1/src/lens/utils/isValidHandle.ts delete mode 100644 packages/api-bindings-v1/src/lens/utils/omitTypename.ts delete mode 100644 packages/api-bindings-v1/src/lens/utils/profile.ts delete mode 100644 packages/api-bindings-v1/src/lens/utils/publication.ts delete mode 100644 packages/api-bindings-v1/src/lens/utils/types.ts delete mode 100644 packages/api-bindings-v1/src/metadata.ts delete mode 100644 packages/api-bindings-v1/src/mocks.ts delete mode 100644 packages/api-bindings-v1/src/snapshot/__helpers__/fragments.ts delete mode 100644 packages/api-bindings-v1/src/snapshot/__helpers__/index.ts delete mode 100644 packages/api-bindings-v1/src/snapshot/__helpers__/queries.ts delete mode 100644 packages/api-bindings-v1/src/snapshot/generated.ts delete mode 100644 packages/api-bindings-v1/src/snapshot/index.ts delete mode 100644 packages/api-bindings-v1/src/snapshot/proposals.graphql delete mode 100644 packages/api-bindings-v1/tsconfig.json delete mode 100644 packages/api-bindings-v1/tsdoc.json delete mode 100644 packages/domain/src/use-cases/wallets/IWalletFactory.ts create mode 100644 packages/domain/src/use-cases/wallets/IWalletGateway.ts delete mode 100644 packages/react-v1/.eslintignore delete mode 100644 packages/react-v1/.eslintrc.cjs delete mode 100644 packages/react-v1/.prettierignore delete mode 100644 packages/react-v1/CHANGELOG.md delete mode 100644 packages/react-v1/README.md delete mode 100644 packages/react-v1/jest.config.ts delete mode 100644 packages/react-v1/package.json delete mode 100644 packages/react-v1/src/ConsoleLogger.ts delete mode 100644 packages/react-v1/src/ErrorHandler.ts delete mode 100644 packages/react-v1/src/LensProvider.tsx delete mode 100644 packages/react-v1/src/NotFoundError.ts delete mode 100644 packages/react-v1/src/__helpers__/jest.setup.ts delete mode 100644 packages/react-v1/src/__helpers__/testing-library.tsx delete mode 100644 packages/react-v1/src/__tests__/config.spec.ts delete mode 100644 packages/react-v1/src/chains.ts delete mode 100644 packages/react-v1/src/config.ts delete mode 100644 packages/react-v1/src/deprecated.ts delete mode 100644 packages/react-v1/src/environments.ts delete mode 100644 packages/react-v1/src/experimental/index.ts delete mode 100644 packages/react-v1/src/experimental/useAccessToken.ts delete mode 100644 packages/react-v1/src/experimental/useApolloClient.ts delete mode 100644 packages/react-v1/src/feed/FeedEventItemType.ts delete mode 100644 packages/react-v1/src/feed/__tests__/useFeed.spec.ts delete mode 100644 packages/react-v1/src/feed/index.ts delete mode 100644 packages/react-v1/src/feed/useFeed.ts delete mode 100644 packages/react-v1/src/helpers/__tests__/operations.spec.ts delete mode 100644 packages/react-v1/src/helpers/__tests__/reads.spec.ts delete mode 100644 packages/react-v1/src/helpers/arguments.ts delete mode 100644 packages/react-v1/src/helpers/operations.ts delete mode 100644 packages/react-v1/src/helpers/reads.ts delete mode 100644 packages/react-v1/src/inbox/adapters/DisableConversationsGateway.ts delete mode 100644 packages/react-v1/src/inbox/index.ts delete mode 100644 packages/react-v1/src/inbox/infrastructure/InboxKeyStorage.ts delete mode 100644 packages/react-v1/src/index.ts delete mode 100644 packages/react-v1/src/lifecycle/__tests__/useCurrentSession.spec.ts delete mode 100644 packages/react-v1/src/lifecycle/adapters/SessionPresenter.ts delete mode 100644 packages/react-v1/src/lifecycle/adapters/__tests__/SessionPresenter.spec.ts delete mode 100644 packages/react-v1/src/lifecycle/adapters/useBootstrapController.ts delete mode 100644 packages/react-v1/src/lifecycle/index.ts delete mode 100644 packages/react-v1/src/lifecycle/useCurrentSession.ts delete mode 100644 packages/react-v1/src/mediaTransforms.ts delete mode 100644 packages/react-v1/src/modules/__tests__/useCurrencies.spec.ts delete mode 100644 packages/react-v1/src/modules/__tests__/useEnabledModules.spec.ts delete mode 100644 packages/react-v1/src/modules/index.ts delete mode 100644 packages/react-v1/src/modules/useCurrencies.ts delete mode 100644 packages/react-v1/src/modules/useEnabledModules.ts delete mode 100644 packages/react-v1/src/notifications/index.ts delete mode 100644 packages/react-v1/src/notifications/useNotifications.ts delete mode 100644 packages/react-v1/src/notifications/useUnreadNotificationCount.ts delete mode 100644 packages/react-v1/src/polls/adapters/SnapshotVoteFactory.ts delete mode 100644 packages/react-v1/src/polls/adapters/SnapshotVoteRelayer.ts delete mode 100644 packages/react-v1/src/polls/adapters/__helpers__/mocks.ts delete mode 100644 packages/react-v1/src/polls/adapters/__tests__/SnapshotVoteFactory.spec.ts delete mode 100644 packages/react-v1/src/polls/adapters/__tests__/SnapshotVoteRelayer.spec.ts delete mode 100644 packages/react-v1/src/polls/adapters/types.ts delete mode 100644 packages/react-v1/src/polls/adapters/useVotePollController.ts delete mode 100644 packages/react-v1/src/polls/index.ts delete mode 100644 packages/react-v1/src/polls/usePollDetails.ts delete mode 100644 packages/react-v1/src/polls/usePollVote.ts delete mode 100644 packages/react-v1/src/profile/__tests__/useActiveProfile.spec.ts delete mode 100644 packages/react-v1/src/profile/__tests__/useExploreProfiles.spec.ts delete mode 100644 packages/react-v1/src/profile/__tests__/useMutualFollowers.spec.ts delete mode 100644 packages/react-v1/src/profile/__tests__/useProfile.spec.ts delete mode 100644 packages/react-v1/src/profile/__tests__/useProfiles.spec.ts delete mode 100644 packages/react-v1/src/profile/__tests__/useProfilesOwnedBy.spec.ts delete mode 100644 packages/react-v1/src/profile/__tests__/useProfilesOwnedByMe.spec.ts delete mode 100644 packages/react-v1/src/profile/__tests__/useProfilesToFollow.spec.ts delete mode 100644 packages/react-v1/src/profile/__tests__/useSearchProfiles.spec.ts delete mode 100644 packages/react-v1/src/profile/adapters/ActiveProfileGateway.ts delete mode 100644 packages/react-v1/src/profile/adapters/CreateProfilePresenter.ts delete mode 100644 packages/react-v1/src/profile/adapters/ProfileGateway.ts delete mode 100644 packages/react-v1/src/profile/adapters/ProfileTransactionGateway.ts delete mode 100644 packages/react-v1/src/profile/adapters/__tests__/ActiveProfileGateway.spec.ts delete mode 100644 packages/react-v1/src/profile/adapters/__tests__/CreateProfilePresenter.spec.ts delete mode 100644 packages/react-v1/src/profile/adapters/__tests__/ProfileGateway.spec.ts delete mode 100644 packages/react-v1/src/profile/adapters/__tests__/ProfileTransactionGateway.spec.ts delete mode 100644 packages/react-v1/src/profile/adapters/useCreateProfileController.ts delete mode 100644 packages/react-v1/src/profile/adapters/useSwitchActiveProfileController.ts delete mode 100644 packages/react-v1/src/profile/index.ts delete mode 100644 packages/react-v1/src/profile/infrastructure/ActiveProfileStorage.ts delete mode 100644 packages/react-v1/src/profile/useActiveProfile.ts delete mode 100644 packages/react-v1/src/profile/useActiveProfileSwitch.ts delete mode 100644 packages/react-v1/src/profile/useCollectedPublications.ts delete mode 100644 packages/react-v1/src/profile/useCreateProfile.ts delete mode 100644 packages/react-v1/src/profile/useExploreProfiles.ts delete mode 100644 packages/react-v1/src/profile/useMutualFollowers.ts delete mode 100644 packages/react-v1/src/profile/useProfile.ts delete mode 100644 packages/react-v1/src/profile/useProfileFollowers.ts delete mode 100644 packages/react-v1/src/profile/useProfileFollowing.ts delete mode 100644 packages/react-v1/src/profile/useProfileGuardian.ts delete mode 100644 packages/react-v1/src/profile/useProfiles.ts delete mode 100644 packages/react-v1/src/profile/useProfilesOwnedBy.ts delete mode 100644 packages/react-v1/src/profile/useProfilesOwnedByMe.ts delete mode 100644 packages/react-v1/src/profile/useProfilesToFollow.ts delete mode 100644 packages/react-v1/src/profile/useSearchProfiles.ts delete mode 100644 packages/react-v1/src/publication/__tests__/filters.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useBookmarkToggle.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useEncryptedPublication.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useExplorePublications.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useMyBookmarks.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useNotInterested.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useProfilePublicationsForSale.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/usePublication.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/usePublications.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useReaction.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useSearchPublications.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useWhoCollectedPublication.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useWhoMirroredPublication.spec.ts delete mode 100644 packages/react-v1/src/publication/__tests__/useWhoReacted.spec.ts delete mode 100644 packages/react-v1/src/publication/adapters/BookmarksGateway.ts delete mode 100644 packages/react-v1/src/publication/adapters/BookmarksPresenter.ts delete mode 100644 packages/react-v1/src/publication/adapters/HidePublicationGateway.ts delete mode 100644 packages/react-v1/src/publication/adapters/HidePublicationPresenter.ts delete mode 100644 packages/react-v1/src/publication/adapters/NotInterestedGateway.ts delete mode 100644 packages/react-v1/src/publication/adapters/NotInterestedPresenter.ts delete mode 100644 packages/react-v1/src/publication/adapters/ReactionGateway.ts delete mode 100644 packages/react-v1/src/publication/adapters/ReactionPresenter.ts delete mode 100644 packages/react-v1/src/publication/adapters/ReportPublicationGateway.ts delete mode 100644 packages/react-v1/src/publication/adapters/__helpers__/mocks.ts delete mode 100644 packages/react-v1/src/publication/adapters/__tests__/HidePublicationGateway.spec.ts delete mode 100644 packages/react-v1/src/publication/adapters/__tests__/HidePublicationPresenter.spec.ts delete mode 100644 packages/react-v1/src/publication/adapters/__tests__/ReactionGateway.spec.ts delete mode 100644 packages/react-v1/src/publication/adapters/__tests__/ReactionPresenter.spec.ts delete mode 100644 packages/react-v1/src/publication/adapters/__tests__/ReportPublicationGateway.spec.ts delete mode 100644 packages/react-v1/src/publication/adapters/useBookmarkToggleController.ts delete mode 100644 packages/react-v1/src/publication/adapters/useHidePublicationController.ts delete mode 100644 packages/react-v1/src/publication/adapters/useNotInterestedController.ts delete mode 100644 packages/react-v1/src/publication/adapters/useReactionController.ts delete mode 100644 packages/react-v1/src/publication/adapters/useReportPublicationController.ts delete mode 100644 packages/react-v1/src/publication/filters.ts delete mode 100644 packages/react-v1/src/publication/index.ts delete mode 100644 packages/react-v1/src/publication/useBookmarkToggle.ts delete mode 100644 packages/react-v1/src/publication/useComments.ts delete mode 100644 packages/react-v1/src/publication/useEncryptedPublication.ts delete mode 100644 packages/react-v1/src/publication/useExplorePublications.ts delete mode 100644 packages/react-v1/src/publication/useHidePublication.ts delete mode 100644 packages/react-v1/src/publication/useMyBookmarks.ts delete mode 100644 packages/react-v1/src/publication/useNotInterested.ts delete mode 100644 packages/react-v1/src/publication/useProfilePublicationsForSale.ts delete mode 100644 packages/react-v1/src/publication/usePublication.ts delete mode 100644 packages/react-v1/src/publication/usePublications.ts delete mode 100644 packages/react-v1/src/publication/useReaction.ts delete mode 100644 packages/react-v1/src/publication/useReportPublication.ts delete mode 100644 packages/react-v1/src/publication/useSearchPublications.ts delete mode 100644 packages/react-v1/src/publication/useWhoCollectedPublication.ts delete mode 100644 packages/react-v1/src/publication/useWhoMirroredPublication.ts delete mode 100644 packages/react-v1/src/publication/useWhoReacted.ts delete mode 100644 packages/react-v1/src/revenue/__tests__/useProfileFollowRevenue.spec.ts delete mode 100644 packages/react-v1/src/revenue/__tests__/useProfilePublicationRevenue.spec.ts delete mode 100644 packages/react-v1/src/revenue/__tests__/usePublicationRevenue.spec.ts delete mode 100644 packages/react-v1/src/revenue/index.ts delete mode 100644 packages/react-v1/src/revenue/useProfileFollowRevenue.ts delete mode 100644 packages/react-v1/src/revenue/useProfilePublicationRevenue.ts delete mode 100644 packages/react-v1/src/revenue/usePublicationRevenue.ts delete mode 100644 packages/react-v1/src/shared.tsx delete mode 100644 packages/react-v1/src/sources.ts delete mode 100644 packages/react-v1/src/transactions/adapters/ApproveTransactionGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/AsyncTransactionResult.ts delete mode 100644 packages/react-v1/src/transactions/adapters/CollectPublicationGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/CreateCommentController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/CreatePostController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/CreatePostPresenter.ts delete mode 100644 packages/react-v1/src/transactions/adapters/DispatcherConfigCallGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/FollowPolicyCallGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/FollowProfilesGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/IMetadataUploader.ts delete mode 100644 packages/react-v1/src/transactions/adapters/IProfileCacheManager.ts delete mode 100644 packages/react-v1/src/transactions/adapters/ITransactionFactory.ts delete mode 100644 packages/react-v1/src/transactions/adapters/IUpdatePublicationCacheManager.ts delete mode 100644 packages/react-v1/src/transactions/adapters/MetadataUploadHandler.ts delete mode 100644 packages/react-v1/src/transactions/adapters/OffChainRelayer.ts delete mode 100644 packages/react-v1/src/transactions/adapters/OnChainRelayer.ts delete mode 100644 packages/react-v1/src/transactions/adapters/PendingTransactionGateway/ISerializableTransactionFactory.ts delete mode 100644 packages/react-v1/src/transactions/adapters/PendingTransactionGateway/PendingTransactionGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/PendingTransactionGateway/__tests__/PendingTransactionGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/PendingTransactionGateway/index.ts delete mode 100644 packages/react-v1/src/transactions/adapters/ProfileImageCallGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/ProfileMetadataCallGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/__tests__/ProfileMetadataCallGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/__tests__/createProfileMetadata.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/createProfileMetadata.ts delete mode 100644 packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/index.ts delete mode 100644 packages/react-v1/src/transactions/adapters/PromiseResultPresenter.tsx delete mode 100644 packages/react-v1/src/transactions/adapters/ProxyReceipt.ts delete mode 100644 packages/react-v1/src/transactions/adapters/PublicationCacheManager.ts delete mode 100644 packages/react-v1/src/transactions/adapters/SelfFundedProtocolCallGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/SelfFundedProtocolTransactionRequest.ts delete mode 100644 packages/react-v1/src/transactions/adapters/TransactionQueuePresenter.tsx delete mode 100644 packages/react-v1/src/transactions/adapters/TransactionResultPresenter.ts delete mode 100644 packages/react-v1/src/transactions/adapters/UnfollowProfileCallGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__helpers__/mocks.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/ApproveTransactionGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/CollectPublicationGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/CreatePostPresenter.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/DispatcherConfigCallGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/FollowPolicyCallGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/FollowProfilesGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/OffChainRelayer.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/OnChainRelayer.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/ProfileImageCallGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/PromiseResultPresenter.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/PublicationCacheManager.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/SelfFundedProtocolCallGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/TransactionQueuePresenter.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/__tests__/UnfollowProfileCallGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainCommentGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainMirrorGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainPostGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainCommentGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainMirrorGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainPostGateway.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainCommentGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainMirrorGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainPostGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainCommentGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainMirrorGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainPostGateway.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/resolveCollectModuleParams.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/resolveReferenceModuleParams.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/resolveCollectModuleParams.ts delete mode 100644 packages/react-v1/src/transactions/adapters/publication-call-gateways/resolveReferenceModuleParams.ts delete mode 100644 packages/react-v1/src/transactions/adapters/relayer.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/CollectPublicationResponder.tsx delete mode 100644 packages/react-v1/src/transactions/adapters/responders/CreateMirrorResponder.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/CreatePostResponder.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/CreateProfileResponder.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/FollowProfilesResponder.tsx delete mode 100644 packages/react-v1/src/transactions/adapters/responders/NoopResponder.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/UnfollowProfileResponder.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/UpdateDispatcherConfigResponder.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/UpdateFollowPolicyResponder.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/UpdateProfileImageResponder.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/UpdateProfileMetadataResponder.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/__tests__/CollectPublicationResponder.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/__tests__/CreateMirrorResponder.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/__tests__/CreatePostResponder.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/__tests__/FollowProfilesResponder.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/__tests__/UnfollowProfileResponder.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateDispatcherConfigResponder.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateFollowPolicyResponder.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateProfileImageResponder.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateProfileMetadataResponder.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/schemas/__tests__/Erc20Amount.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/schemas/__tests__/formatters.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/schemas/__tests__/validators.spec.ts delete mode 100644 packages/react-v1/src/transactions/adapters/schemas/common.ts delete mode 100644 packages/react-v1/src/transactions/adapters/schemas/erc20.ts delete mode 100644 packages/react-v1/src/transactions/adapters/schemas/formatters.ts delete mode 100644 packages/react-v1/src/transactions/adapters/schemas/profiles.ts delete mode 100644 packages/react-v1/src/transactions/adapters/schemas/publications.ts delete mode 100644 packages/react-v1/src/transactions/adapters/schemas/transactions.ts delete mode 100644 packages/react-v1/src/transactions/adapters/schemas/validators.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useApproveModuleController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useCollectController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useCreateCommentController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useCreateEncryptedCommentController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useCreateEncryptedPostController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useCreateMirrorController.tsx delete mode 100644 packages/react-v1/src/transactions/adapters/useCreatePostController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useFollowController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/usePayTransactionController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useUnfollowController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useUpdateDispatcherConfigController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useUpdateFollowPolicyController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useUpdateProfileDetailsController.ts delete mode 100644 packages/react-v1/src/transactions/adapters/useUpdateProfileImageController.ts delete mode 100644 packages/react-v1/src/transactions/index.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/AccessConditionBuilderFactory.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/Eip1559GasPriceEstimator.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/EncryptedPublicationMetadataUploader.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/MetadataUploaderErrorMiddleware.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/ProfileCacheManager.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/PublicationIdPredictor.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/PublicationMetadataUploader.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/TransactionFactory.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/TransactionObserver.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/TransactionStorage.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__helpers__/mocks.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__tests__/AccessConditionBuilderFactory.spec.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__tests__/Eip1559GasPriceEstimator.spec.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__tests__/EncryptedPublicationMetadataUploader.spec.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__tests__/MetadataUploaderErrorMiddleware.spec.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__tests__/ProfileCacheManager.spec.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__tests__/PublicationIdPredictor.spec.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__tests__/PublicationMetadataUploader.spec.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__tests__/TransactionFactory.spec.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__tests__/TransactionObserver.spec.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/__tests__/createPublicationMetadata.spec.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/createGatedClient.ts delete mode 100644 packages/react-v1/src/transactions/infrastructure/createPublicationMetadata.ts delete mode 100644 packages/react-v1/src/transactions/useApproveModule.ts delete mode 100644 packages/react-v1/src/transactions/useClearRecentPosts.ts delete mode 100644 packages/react-v1/src/transactions/useCollect.ts delete mode 100644 packages/react-v1/src/transactions/useCreateComment.ts delete mode 100644 packages/react-v1/src/transactions/useCreateEncryptedComment.ts delete mode 100644 packages/react-v1/src/transactions/useCreateEncryptedPost.ts delete mode 100644 packages/react-v1/src/transactions/useCreateMirror.ts delete mode 100644 packages/react-v1/src/transactions/useCreatePost.ts delete mode 100644 packages/react-v1/src/transactions/useFollow.ts delete mode 100644 packages/react-v1/src/transactions/useRecentPosts.ts delete mode 100644 packages/react-v1/src/transactions/useRecentTransactions.ts delete mode 100644 packages/react-v1/src/transactions/useSelfFundedFallback.ts delete mode 100644 packages/react-v1/src/transactions/useUnfollow.ts delete mode 100644 packages/react-v1/src/transactions/useUpdateDispatcherConfig.ts delete mode 100644 packages/react-v1/src/transactions/useUpdateFollowPolicy.ts delete mode 100644 packages/react-v1/src/transactions/useUpdateProfileDetails.ts delete mode 100644 packages/react-v1/src/transactions/useUpdateProfileImage.ts delete mode 100644 packages/react-v1/src/utils.ts delete mode 100644 packages/react-v1/src/wallet/adapters/BalanceGateway.ts delete mode 100644 packages/react-v1/src/wallet/adapters/ConcreteWallet.ts delete mode 100644 packages/react-v1/src/wallet/adapters/Credentials.ts delete mode 100644 packages/react-v1/src/wallet/adapters/CredentialsExpiryController.ts delete mode 100644 packages/react-v1/src/wallet/adapters/CredentialsFactory.ts delete mode 100644 packages/react-v1/src/wallet/adapters/CredentialsGateway.ts delete mode 100644 packages/react-v1/src/wallet/adapters/IProviderFactory.ts delete mode 100644 packages/react-v1/src/wallet/adapters/TokenGateway.ts delete mode 100644 packages/react-v1/src/wallet/adapters/WalletFactory.ts delete mode 100644 packages/react-v1/src/wallet/adapters/WalletGateway.ts delete mode 100644 packages/react-v1/src/wallet/adapters/WalletLoginPresenter.ts delete mode 100644 packages/react-v1/src/wallet/adapters/__helpers__/mocks.ts delete mode 100644 packages/react-v1/src/wallet/adapters/__tests__/ConcreteWallet.spec.ts delete mode 100644 packages/react-v1/src/wallet/adapters/__tests__/Credentials.spec.ts delete mode 100644 packages/react-v1/src/wallet/adapters/__tests__/CredentialsFactory.spec.ts delete mode 100644 packages/react-v1/src/wallet/adapters/__tests__/CredentialsGateway.spec.ts delete mode 100644 packages/react-v1/src/wallet/adapters/__tests__/WalletGateway.spec.ts delete mode 100644 packages/react-v1/src/wallet/adapters/__tests__/WalletLoginPresenter.spec.ts delete mode 100644 packages/react-v1/src/wallet/adapters/errors.ts delete mode 100644 packages/react-v1/src/wallet/adapters/useWalletLoginController.ts delete mode 100644 packages/react-v1/src/wallet/adapters/useWalletLogoutController.ts delete mode 100644 packages/react-v1/src/wallet/index.ts delete mode 100644 packages/react-v1/src/wallet/infrastructure/AccessTokenStorage.ts delete mode 100644 packages/react-v1/src/wallet/infrastructure/AuthApi.ts delete mode 100644 packages/react-v1/src/wallet/infrastructure/CredentialsStorage.ts delete mode 100644 packages/react-v1/src/wallet/infrastructure/NotificationStorage.ts delete mode 100644 packages/react-v1/src/wallet/infrastructure/ProviderFactory.ts delete mode 100644 packages/react-v1/src/wallet/infrastructure/SignerFactory.ts delete mode 100644 packages/react-v1/src/wallet/infrastructure/WalletStorage.ts delete mode 100644 packages/react-v1/src/wallet/infrastructure/__helpers__/mocks.ts delete mode 100644 packages/react-v1/src/wallet/infrastructure/__tests__/ProviderFactory.spec.ts delete mode 100644 packages/react-v1/src/wallet/infrastructure/__tests__/SignerFactory.spec.ts delete mode 100644 packages/react-v1/src/wallet/useActiveWallet.ts delete mode 100644 packages/react-v1/src/wallet/useActiveWalletSigner.ts delete mode 100644 packages/react-v1/src/wallet/useWalletLogin.ts delete mode 100644 packages/react-v1/src/wallet/useWalletLogout.ts delete mode 100644 packages/react-v1/tsconfig.json delete mode 100644 packages/react-v1/tsdoc.json delete mode 100644 packages/react-web-v1/.eslintignore delete mode 100644 packages/react-web-v1/.eslintrc.cjs delete mode 100644 packages/react-web-v1/.prettierignore delete mode 100644 packages/react-web-v1/CHANGELOG.md delete mode 100644 packages/react-web-v1/README.md delete mode 100644 packages/react-web-v1/inbox/package.json delete mode 100644 packages/react-web-v1/jest.config.ts delete mode 100644 packages/react-web-v1/package.json delete mode 100644 packages/react-web-v1/src/LensProvider.tsx delete mode 100644 packages/react-web-v1/src/__helpers__/jest.setup.ts delete mode 100644 packages/react-web-v1/src/__tests__/storage.spec.ts delete mode 100644 packages/react-web-v1/src/globals.ts delete mode 100644 packages/react-web-v1/src/inbox/adapters/SignerAdapter.ts delete mode 100644 packages/react-web-v1/src/inbox/helpers/__tests__/conversationIdUtils.spec.ts delete mode 100644 packages/react-web-v1/src/inbox/helpers/conversationIdUtils.ts delete mode 100644 packages/react-web-v1/src/inbox/helpers/createUniqueConversationId.ts delete mode 100644 packages/react-web-v1/src/inbox/helpers/index.ts delete mode 100644 packages/react-web-v1/src/inbox/helpers/notEmpty.ts delete mode 100644 packages/react-web-v1/src/inbox/index.ts delete mode 100644 packages/react-web-v1/src/inbox/types.ts delete mode 100644 packages/react-web-v1/src/inbox/useEnhanceConversation.ts delete mode 100644 packages/react-web-v1/src/inbox/useEnhanceConversations.ts delete mode 100644 packages/react-web-v1/src/inbox/useStartLensConversation.ts delete mode 100644 packages/react-web-v1/src/inbox/useXmtpClient.ts delete mode 100644 packages/react-web-v1/src/index.ts delete mode 100644 packages/react-web-v1/src/storage.ts delete mode 100644 packages/react-web-v1/src/useBrowserEncryptionConfig.ts delete mode 100644 packages/react-web-v1/src/useCreateEncryptedComment.ts delete mode 100644 packages/react-web-v1/src/useCreateEncryptedPost.ts delete mode 100644 packages/react-web-v1/src/useEncryptedPublication.ts delete mode 100644 packages/react-web-v1/tsconfig.json delete mode 100644 packages/react-web-v1/tsdoc.json rename packages/react/src/authentication/adapters/{Credentials.ts => JwtCredentials.ts} (84%) delete mode 100644 packages/react/src/wallet/adapters/WalletFactory.ts delete mode 100644 packages/react/src/wallet/infrastructure/WalletStorage.ts diff --git a/packages/api-bindings-v1/.eslintignore b/packages/api-bindings-v1/.eslintignore deleted file mode 100644 index 45161a327c..0000000000 --- a/packages/api-bindings-v1/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -dist -*.cjs diff --git a/packages/api-bindings-v1/.eslintrc.cjs b/packages/api-bindings-v1/.eslintrc.cjs deleted file mode 100644 index ae6e4eb86e..0000000000 --- a/packages/api-bindings-v1/.eslintrc.cjs +++ /dev/null @@ -1,22 +0,0 @@ -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - parserOptions: { - project: './tsconfig.json', - }, - extends: ['@lens-protocol/eslint-config'], - rules: { - 'no-restricted-imports': [ - 'error', - { - paths: [ - { - name: '@apollo/client', - importNames: ['createHttpLink', 'HttpLink'], - message: 'Please terminating links from src/apollo/links.ts.', - }, - ], - }, - ], - }, -}; diff --git a/packages/api-bindings-v1/.prettierignore b/packages/api-bindings-v1/.prettierignore deleted file mode 100644 index 3f6fff7b2b..0000000000 --- a/packages/api-bindings-v1/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -dist -coverage \ No newline at end of file diff --git a/packages/api-bindings-v1/CHANGELOG.md b/packages/api-bindings-v1/CHANGELOG.md deleted file mode 100644 index fe4ef8fab9..0000000000 --- a/packages/api-bindings-v1/CHANGELOG.md +++ /dev/null @@ -1,415 +0,0 @@ -# @lens-protocol/api-bindings - -## 0.10.1 - -### Patch Changes - -- 5f251069: **Fixed** `usePublications` to refetch on `publicationIds` change -- dfb15e1a: **Fixed** 1.3.1-next.0 release packages bundles -- ebc2e7e5: **Added** `publicationsId` to `usePublications` args -- Updated dependencies [48dd0860] - - @lens-protocol/domain@0.10.1 - -## 0.10.1-next.3 - -### Patch Changes - -- Updated dependencies [48dd0860] - - @lens-protocol/domain@0.10.1-next.0 - -## 0.10.1-next.2 - -### Patch Changes - -- 5f251069: **Fixed** `usePublications` to refetch on `publicationIds` change - -## 0.10.1-next.1 - -### Patch Changes - -- dfb15e1a: **Fixed** 1.3.1-next.0 release packages bundles - -## 0.10.1-next.0 - -### Patch Changes - -- ebc2e7e5: **Added** `publicationsId` to `usePublications` args - -## 0.10.0 - -### Minor Changes - -- de401a59: **Added** support for optimized and transformed media inside publication and profile MediaSet -- e8dc3cd8: fixes collect/mirror count bug -- 3b67207b: **Added** `appId` to `Comment` and `Post` - -### Patch Changes - -- 40fce6ff: **Added** support for bookmarks: list, add, and remove from a Profile private list of publications -- ad797714: **Added** `useNotInterested` hook -- 773c2ed8: **Fixes** issues with `profileIds` not used to evaluate cache hits. Affecting `usePublications` and `useProfiles`. -- c2a91ef4: **Added** `Profile.invitedBy` field -- b7609fcb: **Fixed** `useNotification` to include `highSignalFilter` filter -- 636ff014: **Added** `profileIds` to `usePublications` hook -- 773c2ed8: **Added** missing `commentsOfOrdering` and `commentsRankingFilter` to `useComments` hook -- 19ed489e: **Added** `beforeCount` to all paginated hooks and refetch data on re-render of `usePublication` and `useProfile` hooks. -- 0f75f79d: **Added** experimental `useCurrentSession` hook - **Fixed** issue with `Profile` entity being leaked by the `useWalletLogin` hook - **Fixed** bug preventing logout on expired credentials detected at startup type -- d5efd895: **Fixed** crash caused by token-gated mismatch of publication author access condition" -- 773c2ed8: **Added** ability to override `sources` in `useExplorePublications` hook and support to `noRandomize` param. -- 773c2ed8: **Added** `name` support to non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` -- 125ec30c: **Fixed** `usePollDetails` to be robust to flagged or misconfigured Snapshot Proposals -- 6eaaaf22: **Added** `Profile.followNftAddress` field -- 4c4505d2: **Added** support for Profile Guardian -- Updated dependencies [40fce6ff] -- Updated dependencies [ad797714] -- Updated dependencies [3ffab7b9] -- Updated dependencies [0f75f79d] -- Updated dependencies [773c2ed8] -- Updated dependencies [433760f3] -- Updated dependencies [fc31f146] -- Updated dependencies [9428efeb] -- Updated dependencies [bdbc71d5] -- Updated dependencies [5943a0f0] - - @lens-protocol/domain@0.10.0 - - @lens-protocol/shared-kernel@0.10.0 - -## 0.10.0-next.8 - -### Patch Changes - -- Updated dependencies [bdbc71d5] - - @lens-protocol/shared-kernel@0.10.0-next.2 - - @lens-protocol/domain@0.10.0-next.7 - -## 0.10.0-next.7 - -### Patch Changes - -- Updated dependencies - - @lens-protocol/shared-kernel@0.10.0-next.1 - - @lens-protocol/domain@0.10.0-next.6 - -## 0.10.0-next.6 - -### Patch Changes - -- 773c2ed8: **Fixes** issues with `profileIds` not used to evaluate cache hits. Affecting `usePublications` and `useProfiles`. -- 773c2ed8: **Added** missing `commentsOfOrdering` and `commentsRankingFilter` to `useComments` hook -- 773c2ed8: **Added** ability to override `sources` in `useExplorePublications` hook and support to `noRandomize` param. -- 773c2ed8: **Added** `name` support to non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` -- Updated dependencies [773c2ed8] - - @lens-protocol/domain@0.10.0-next.5 - -## 0.10.0-next.5 - -### Patch Changes - -- 19ed489e: **Added** `beforeCount` to all paginated hooks and refetch data on re-render of `usePublication` and `useProfile` hooks. -- 6eaaaf22: **Added** `Profile.followNftAddress` field -- Updated dependencies [3ffab7b9] - - @lens-protocol/domain@0.10.0-next.4 - -## 0.10.0-next.4 - -### Minor Changes - -- e8dc3cd8: fixes collect/mirror count bug - -### Patch Changes - -- b7609fcb: **Fixed** `useNotification` to include `highSignalFilter` filter -- Updated dependencies [433760f3] -- Updated dependencies [fc31f146] - - @lens-protocol/domain@0.10.0-next.3 - - @lens-protocol/shared-kernel@0.10.0-next.0 - -## 0.10.0-next.3 - -### Patch Changes - -- Updated dependencies [9428efeb] - - @lens-protocol/domain@0.9.1-next.2 - -## 0.10.0-next.2 - -### Minor Changes - -- de401a59: **Added** support for optimized and transformed media inside publication and profile MediaSet -- 3b67207b: **Added** `appId` to `Comment` and `Post` - -### Patch Changes - -- 40fce6ff: **Added** support for bookmarks: list, add, and remove from a Profile private list of publications -- ad797714: **Added** `useNotInterested` hook -- 636ff014: **Added** `profileIds` to `usePublications` hook -- 125ec30c: **Fixed** `usePollDetails` to be robust to flagged or misconfigured Snapshot Proposals -- Updated dependencies [40fce6ff] -- Updated dependencies [ad797714] - - @lens-protocol/domain@0.9.1-next.1 - -## 0.9.2-next.1 - -### Patch Changes - -- d5efd895: **Fixed** crash caused by token-gated mismatch of publication author access condition" - -## 0.9.1 - -### Patch Changes - -- 06a30a2c: **Fixed** crash caused by token-gated mismatch of publication author access condition" - -## 0.9.1-next.0 - -### Patch Changes - -- c2a91ef4: **Added** `Profile.invitedBy` field -- 0f75f79d: **Added** experimental `useCurrentSession` hook - **Fixed** issue with `Profile` entity being leaked by the `useWalletLogin` hook - **Fixed** bug preventing logout on expired credentials detected at startup type -- 4c4505d2: **Added** support for Profile Guardian -- Updated dependencies [0f75f79d] - - @lens-protocol/domain@0.9.1-next.0 - -## 0.9.0 - -### Minor Changes - -- 225f0fa7: **Added** `usePollDetail` and `usePollVote` hooks - -### Patch Changes - -- 3025d56a: allow self funded fallback for proxy actions -- a899553c: **Fixed** missing cache item that causes logged out flow to not work as expected -- e4be6c07: **Updated** min Lens API supported version. -- 97ecba69: **Fixed** cache redirects for Publication and Profile -- Updated dependencies [55211083] -- Updated dependencies [3025d56a] -- Updated dependencies [1d99413a] -- Updated dependencies [225f0fa7] -- Updated dependencies [ea0b40e3] -- Updated dependencies [422c627e] - - @lens-protocol/domain@0.9.0 - - @lens-protocol/shared-kernel@0.9.0 - -## 0.9.0-next.2 - -### Patch Changes - -- a899553c: **Fixed** missing cache item that causes logged out flow to not work as expected -- Updated dependencies [ea0b40e3] - - @lens-protocol/domain@0.9.0-next.2 - -## 0.8.1 - -### Patch Changes - -- 58217985: **Fixed** missing cache item that causes logged out flow to not work as expected - -## 0.9.0-next.1 - -### Minor Changes - -- 225f0fa7: **Added** `usePollDetail` and `usePollVote` hooks - -### Patch Changes - -- 3025d56a: allow self funded fallback for proxy actions -- 97ecba69: **Fixed** cache redirects for Publication and Profile -- Updated dependencies [3025d56a] -- Updated dependencies [225f0fa7] -- Updated dependencies [422c627e] - - @lens-protocol/domain@0.9.0-next.1 - - @lens-protocol/shared-kernel@0.9.0-next.0 - -## 0.8.1-next.0 - -### Patch Changes - -- Updated dependencies [55211083] - - @lens-protocol/domain@0.8.1-next.0 - -## 0.8.0 - -### Minor Changes - -- 03a8ad5: **Deprecated** publication's `isOptimisticMirroredByMe` property, introduced `isMirroredByMe` -- 513373d: **Enhanced** publication's `hasCollectedByMe` to replace deprecated `hasOptimisticCollectedByMe` property -- 98c6547: **Added:** support to fetch results before the current results set -- c416a2e: **Added:** self-fund protocol calls when subsidized approaches fails -- c416a2e: **Fixed:** ensures correct chain when signing typed data -- c416a2e: **Fixed:** network switch in wagmi bindings -- ef1d7e2: **Added:** Momoka support to React hooks -- 5c5bfb2: **Added:** support for SimpleCollectModule - -### Patch Changes - -- 37bf8e8: Do not fallback to `undefined` with unsupported collect module in collect policy -- 04647bb: **Fixed** issue preventing query hook from detecting active profile changes -- Updated dependencies [c416a2e] -- Updated dependencies [ef1d7e2] -- Updated dependencies [b738abb] -- Updated dependencies [5c5bfb2] -- Updated dependencies [71196cf] - - @lens-protocol/shared-kernel@0.8.0 - - @lens-protocol/domain@0.8.0 - -## 0.8.0-next.4 - -### Patch Changes - -- 37bf8e8: Do not fallback to `undefined` with unsupported collect module in collect policy - -## 0.8.0-next.3 - -### Minor Changes - -- 5c5bfb2: Added support for SimpleCollectModule - -### Patch Changes - -- Updated dependencies [b738abb] -- Updated dependencies [5c5bfb2] - - @lens-protocol/shared-kernel@0.8.0-next.1 - - @lens-protocol/domain@0.8.0-next.3 - -## 0.8.0-next.2 - -### Minor Changes - -- ef1d7e2: Added Momoka support to React hooks - -### Patch Changes - -- Updated dependencies [ef1d7e2] - - @lens-protocol/domain@0.8.0-next.2 - -## 0.8.0-next.1 - -### Minor Changes - -- 03a8ad5: Deprecated publication's `isOptimisticMirroredByMe` property, introduced `isMirroredByMe` - -### Patch Changes - -- Updated dependencies [71196cf] - - @lens-protocol/domain@0.8.0-next.1 - -## 0.8.0-next.0 - -### Minor Changes - -- 513373d3: Enhanced publication's hasCollectedByMe to replace deprecated hasOptimisticCollectedByMe property -- c416a2ea: - - **Added:** self-fund protocol calls when subsidized approaches fails - - **Fixed:** ensures correct chain when signing typed data - - **Fixed:** network switch in wagmi bindings - -### Patch Changes - -- 04647bbe: **Fixed** issue preventing query hook from detecting active profile changes -- Updated dependencies [c416a2ea] - - @lens-protocol/shared-kernel@0.8.0-next.0 - - @lens-protocol/domain@0.8.0-next.0 - -## 0.7.1 - -### Patch Changes - -- 425daba: **Fixed** 1.0.0 release packages bundles -- Updated dependencies [425daba] - - @lens-protocol/domain@0.7.1 - - @lens-protocol/shared-kernel@0.7.1 - -## 0.7.0 - -### Minor Changes - -- 37eaf8a: Added TSDoc, use shared tsconfig, better types - -### Patch Changes - -- 6ae90ef: Exposed collectNftAddress from publication fragments -- a4e9500: allow to define sortCriteria for useExploreProfiles -- Updated dependencies [37eaf8a] - - @lens-protocol/shared-kernel@0.7.0 - - @lens-protocol/domain@0.7.0 - -## 0.7.0-beta.0 - -### Minor Changes - -- dc1350d: Added TSDoc, use shared tsconfig, better types - -### Patch Changes - -- 6ae90ef: Exposed `collectNftAddress` from publication fragments -- a4e9500: allow to define `sortCriteria` for `useExploreProfiles` -- Updated dependencies [dc1350d] - - @lens-protocol/shared-kernel@0.7.0-beta.0 - - @lens-protocol/domain@0.7.0-beta.0 - -## 0.6.0 - -### Patch Changes - -- Updated dependencies [4475a27] - - @lens-protocol/domain@0.6.0 - - @lens-protocol/shared-kernel@0.6.0 - -## 0.5.1 - -### Patch Changes - -- @lens-protocol/domain@0.5.1 -- @lens-protocol/shared-kernel@0.5.1 - -## 0.5.0 - -### Patch Changes - -- @lens-protocol/domain@0.5.0 -- @lens-protocol/shared-kernel@0.5.0 - -## 0.4.1 - -### Patch Changes - -- @lens-protocol/domain@0.4.1 -- @lens-protocol/shared-kernel@0.4.1 - -## 0.4.0 - -### Patch Changes - -- @lens-protocol/domain@0.4.0 -- @lens-protocol/shared-kernel@0.4.0 - -## 0.3.0 - -### Patch Changes - -- @lens-protocol/domain@0.3.0 -- @lens-protocol/shared-kernel@0.3.0 - -## 0.2.0 - -### Patch Changes - -- Updated dependencies [c89aed9] -- Updated dependencies [a921c32] - - @lens-protocol/shared-kernel@1.0.0 - - @lens-protocol/domain@1.0.0 - -## 0.1.1 - -### Patch Changes - -- @lens-protocol/domain@0.1.1 -- @lens-protocol/shared-kernel@0.1.1 - -## 0.1.0 - -First developer preview release diff --git a/packages/api-bindings-v1/README.md b/packages/api-bindings-v1/README.md deleted file mode 100644 index b012279cb5..0000000000 --- a/packages/api-bindings-v1/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# `@lens-protocol/api-bindings` - -This package provides the tooling to interact with the Lens Protocol API. **It is not intended to be used directly.** - -**Its interface will change without notice, use it at your own risk.** - -### Important notes - -`react` and `react-dom` is required to be in `devDependencies` to avoid having duplicated `@apollo/client` due to unmatched optional `peerDependencies` between `@lens-protocol/api-bindings` and `@lens-protocol/react`. See https://github.com/pnpm/pnpm/issues/5351 for more details. diff --git a/packages/api-bindings-v1/TROUBLESHOOTING.md b/packages/api-bindings-v1/TROUBLESHOOTING.md deleted file mode 100644 index dfa62fb142..0000000000 --- a/packages/api-bindings-v1/TROUBLESHOOTING.md +++ /dev/null @@ -1,26 +0,0 @@ -## Apollo doesn't return the items from the cache forcing the new network request - -Quite likely type policies configuration is broken. - -To get the exact fields that are missing go to the `@apollo/client` `QueryManager.ts` and log the result of `readCache` method call inside `cache-first` fetch policy switch -(make sure you modify the file that gets imported by the bundler). - -```ts -// ... - -switch (fetchPolicy) { - default: case "cache-first": { - const diff = readCache(); - - console.log(diff) // should have a `missing` properly - - if (diff.complete) { - return [ - resultsFromCache(diff, queryInfo.markReady()), - ]; - } - -// .. -``` - -Run the app and the exact missing fields should be logged into the console. diff --git a/packages/api-bindings-v1/codegen-api.yml b/packages/api-bindings-v1/codegen-api.yml deleted file mode 100644 index f962760720..0000000000 --- a/packages/api-bindings-v1/codegen-api.yml +++ /dev/null @@ -1,137 +0,0 @@ -overwrite: true -hooks: - afterAllFileWrite: - - prettier --write - - eslint --fix - -watch: false -config: - gqlImport: graphql-tag - avoidOptionals: - field: true - -generates: - src/lens/generated.ts: - config: - defaultScalarType: unknown - scalars: - Attach: string - BroadcastId: string - BlockchainData: string - ChainId: number - ClientErc20Amount: ClientErc20Amount - CollectModuleData: string - CollectPolicy: CollectPolicy - ContentEncryptionKey: ContentEncryptionKey - ContentInsight: ContentInsight - ContractAddress: string - Cursor: Cursor - DataAvailabilityId: string - DateTime: string - DecryptionCriteria: DecryptionCriteria - EncryptedValueScalar: string - EthereumAddress: EthereumAddress - FollowModuleData: string - FollowPolicy: FollowPolicy - FollowStatus: FollowStatus - Handle: string - ImageSizeTransform: ImageSizeTransform - InternalPublicationId: PublicationId - Jwt: string - LimitScalar: number - Locale: string - Markdown: string - Media: string - MimeType: string - NftOwnershipId: string - Nonce: number - NotificationId: string - PendingPublicationId: string - ProfileAttributes: ProfileAttributes - ProfileId: ProfileId - ProfileInterest: string - ProxyActionId: string - PublicationId: string - PublicationUrl: Url - ReferenceModuleData: string - ReferencePolicy: ReferencePolicy - Search: string - Signature: string - Sources: AppId - String: string - TokenId: string - TxHash: string - TxId: string - Url: Url - Void: void - schema: - - https://api-mumbai.lens.dev/graphql - - src/lens/client.graphql - documents: - - src/lens/*.graphql - plugins: - - 'typescript': - onlyOperationTypes: true # scalars and enums - - add: - content: [ - '/** Code generated. DO NOT EDIT. */', - '/* eslint-disable import/no-default-export */', # generatedTypes default export - '/* eslint-disable @typescript-eslint/ban-types */', # needed by unions with {} - '/* eslint-disable @typescript-eslint/no-explicit-any */', # see extensive use of FieldPolicy | FieldReadFunction - '/* eslint-disable @typescript-eslint/naming-convention */', # interface PossibleTypesResultData not starting with I - '/* eslint-disable no-restricted-imports */', # import * from @apollo/client - '/* eslint-disable tsdoc/syntax */', - "import type { AppId, DecryptionCriteria, ProfileId, PublicationId } from '@lens-protocol/domain/entities';", - "import type { CollectPolicy } from './CollectPolicy';", - "import type { ContentEncryptionKey } from './ContentEncryptionKey';", - "import type { ContentInsight } from './ContentInsight';", - "import type { Cursor } from './Cursor';", - "import type { Erc20Amount as ClientErc20Amount, EthereumAddress, Url } from '@lens-protocol/shared-kernel';", - "import type { FollowPolicy } from './FollowPolicy';", - "import type { FollowStatus } from './FollowStatus';", - "import type { ImageSizeTransform } from './ImageSizeTransform';", - "import type { ProfileAttributes } from './ProfileAttributes';", - "import type { ReferencePolicy } from './ReferencePolicy';", - ] - - 'typescript-operations': - skipTypename: true - immutableTypes: false - inlineFragmentTypes: combine - omitOperationSuffix: true - operationResultSuffix: 'Data' - - 'typescript-react-apollo': - pureMagicComment: true # keep - omitOperationSuffix: true # MUST goes with typescript-operations.omitOperationSuffix - operationResultSuffix: 'Data' # goes with typescript-operations.operationResultSuffix - fragmentVariablePrefix: Fragment # because FragmentDoc suffix is removed by omitOperationSuffix we need to add a prefix to differentiate fragment types from fragment documents - - 'typescript-apollo-client-helpers' - - 'fragment-matcher' - - src/snapshot/generated.ts: - config: - strictScalars: true - scalars: - Any: unknown - schema: https://hub.snapshot.org/graphql - documents: - - src/snapshot/*.graphql - plugins: - - 'typescript': - onlyOperationTypes: true # scalars and enums - - add: - content: [ - '/** Code generated. DO NOT EDIT. */', - '/* eslint-disable import/no-default-export */', # generatedTypes default export - '/* eslint-disable no-restricted-imports */', # import * from @apollo/client - ] - - 'typescript-operations': - skipTypename: true - immutableTypes: false - inlineFragmentTypes: combine - omitOperationSuffix: true - operationResultSuffix: 'Data' - - 'typescript-react-apollo': - pureMagicComment: true # keep - omitOperationSuffix: true # MUST goes with typescript-operations.omitOperationSuffix - operationResultSuffix: 'Data' # goes with typescript-operations.operationResultSuffix - fragmentVariablePrefix: Fragment # because FragmentDoc suffix is removed by omitOperationSuffix we need to add a prefix to differentiate fragment types from fragment documents diff --git a/packages/api-bindings-v1/jest.config.ts b/packages/api-bindings-v1/jest.config.ts deleted file mode 100644 index 092d73e160..0000000000 --- a/packages/api-bindings-v1/jest.config.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default { - preset: 'ts-jest/presets/js-with-ts', - testEnvironment: 'node', - testPathIgnorePatterns: ['/node_modules/', '/dist/'], -}; diff --git a/packages/api-bindings-v1/mocks/package.json b/packages/api-bindings-v1/mocks/package.json deleted file mode 100644 index 1e64a4ddb1..0000000000 --- a/packages/api-bindings-v1/mocks/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "type": "module", - "main": "dist/lens-protocol-api-bindings-mocks.cjs.js", - "module": "dist/lens-protocol-api-bindings-mocks.esm.js" -} diff --git a/packages/api-bindings-v1/package.json b/packages/api-bindings-v1/package.json deleted file mode 100644 index af75264755..0000000000 --- a/packages/api-bindings-v1/package.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "name": "api-bindings-v1", - "version": "0.10.1", - "private": true, - "description": "Graphql fragments, react hooks, typescript types of lens API.", - "repository": { - "directory": "packages/api-bindings-v1", - "type": "git", - "url": "git://github.com/lens-protocol/lens-sdk.git" - }, - "main": "dist/lens-protocol-api-bindings.cjs.js", - "module": "dist/lens-protocol-api-bindings.esm.js", - "exports": { - ".": { - "module": "./dist/lens-protocol-api-bindings.esm.js", - "default": "./dist/lens-protocol-api-bindings.cjs.js" - }, - "./mocks": { - "module": "./mocks/dist/lens-protocol-api-bindings-mocks.esm.js", - "default": "./mocks/dist/lens-protocol-api-bindings-mocks.cjs.js" - }, - "./package.json": "./package.json" - }, - "sideEffects": false, - "files": [ - "dist/**/*", - "mocks" - ], - "scripts": { - "build": "exit 0", - "test": "exit 0", - "eslint:fix": "pnpm run eslint --fix", - "eslint": "eslint src", - "lint": "exit 0", - "lint:fix": "pnpm run prettier:fix && pnpm run eslint:fix && pnpm run tsc", - "prettier:fix": "prettier --write .", - "prettier": "prettier --check .", - "tsc": "tsc --noEmit", - "gql-codegen": "graphql-codegen --config codegen-api.yml" - }, - "license": "MIT", - "dependencies": { - "@apollo/client": "^3.8.7", - "@lens-protocol/domain": "workspace:*", - "@lens-protocol/shared-kernel": "workspace:*", - "graphql": "^16.8.1", - "graphql-tag": "^2.12.6", - "tslib": "^2.6.2" - }, - "devDependencies": { - "@babel/core": "^7.23.3", - "@babel/preset-env": "^7.23.3", - "@babel/preset-typescript": "^7.23.3", - "@faker-js/faker": "^7.6.0", - "@graphql-codegen/add": "^4.0.1", - "@graphql-codegen/cli": "^3.3.1", - "@graphql-codegen/fragment-matcher": "^4.0.1", - "@graphql-codegen/introspection": "^3.0.1", - "@graphql-codegen/typescript": "^3.0.4", - "@graphql-codegen/typescript-apollo-client-helpers": "^2.2.6", - "@graphql-codegen/typescript-operations": "^3.0.4", - "@graphql-codegen/typescript-react-apollo": "^3.3.7", - "@lens-protocol/eslint-config": "workspace:*", - "@lens-protocol/prettier-config": "workspace:*", - "@lens-protocol/tsconfig": "workspace:*", - "@types/jest": "^29.5.10", - "@types/node": "^18.18.12", - "babel-plugin-graphql-tag": "^3.3.0", - "eslint": "^8.54.0", - "jest": "^29.7.0", - "jest-mock-extended": "^3.0.5", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "ts-jest": "^29.1.1", - "typescript": "5.2.2" - }, - "peerDependencies": { - "@faker-js/faker": "^7.6.0", - "react": "^18.2.0" - }, - "peerDependenciesMeta": { - "@faker-js/faker": { - "optional": true - } - }, - "prettier": "@lens-protocol/prettier-config", - "babel": { - "presets": [ - "@babel/preset-env", - "@babel/preset-typescript" - ] - } -} diff --git a/packages/api-bindings-v1/src/SemVer.tsx b/packages/api-bindings-v1/src/SemVer.tsx deleted file mode 100644 index 80f514969c..0000000000 --- a/packages/api-bindings-v1/src/SemVer.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { Brand } from '@lens-protocol/shared-kernel'; - -export type SemVer = Brand; - -export function semVer(value: string): SemVer { - // for now just asserts the type, in future it will enforce a format - return value as SemVer; -} diff --git a/packages/api-bindings-v1/src/__helpers__/mocks.ts b/packages/api-bindings-v1/src/__helpers__/mocks.ts deleted file mode 100644 index c8fc373611..0000000000 --- a/packages/api-bindings-v1/src/__helpers__/mocks.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { faker } from '@faker-js/faker'; - -import { PublicationMainFocus } from '../lens'; -import { PublicationMetadata } from '../metadata'; - -export function mockPublicationMetadata( - overrides?: Partial, -): PublicationMetadata { - return { - version: '2.0.0', - metadata_id: faker.datatype.uuid(), - content: faker.lorem.paragraph(), - locale: 'en', - attributes: [], - name: 'Test publication', - mainContentFocus: PublicationMainFocus.TextOnly, - ...overrides, - }; -} diff --git a/packages/api-bindings-v1/src/apollo/IAccessTokenStorage.ts b/packages/api-bindings-v1/src/apollo/IAccessTokenStorage.ts deleted file mode 100644 index 2f190c30f0..0000000000 --- a/packages/api-bindings-v1/src/apollo/IAccessTokenStorage.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IAccessTokenStorage { - getAccessToken(): string | null; - refreshToken(): Promise; -} diff --git a/packages/api-bindings-v1/src/apollo/IGraphQLClient.ts b/packages/api-bindings-v1/src/apollo/IGraphQLClient.ts deleted file mode 100644 index 4f5d766ccd..0000000000 --- a/packages/api-bindings-v1/src/apollo/IGraphQLClient.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { - ApolloCache, - ApolloQueryResult, - DefaultContext, - FetchResult, - MutationOptions, - NormalizedCacheObject, - Observable, - OperationVariables, - QueryOptions, -} from '@apollo/client'; -import { invariant } from '@lens-protocol/shared-kernel'; - -export type GraphQLClientQueryResult = Omit< - ApolloQueryResult, - 'error' | 'errors' -> & { - data: TData; -}; - -export type GraphQLClientMutationResult = Omit< - FetchResult, - 'error' | 'errors' -> & { - data: TData; -}; - -export function assertGraphQLClientQueryResult( - result: ApolloQueryResult, - operationName: string, -): asserts result is GraphQLClientQueryResult { - invariant(result.data, `No data received for query: ${operationName}`); -} - -export function assertGraphQLClientMutationResult( - result: FetchResult, - operationName: string, -): asserts result is GraphQLClientMutationResult { - invariant(result.data, `No data received for mutation: ${operationName}`); -} - -export interface IGraphQLClient { - query( - options: QueryOptions, - ): Promise>; - - mutate( - options: MutationOptions>, - ): Promise>; - - poll( - options: QueryOptions, - ): Observable; -} diff --git a/packages/api-bindings-v1/src/apollo/SafeApolloClient.ts b/packages/api-bindings-v1/src/apollo/SafeApolloClient.ts deleted file mode 100644 index 723a0f83ad..0000000000 --- a/packages/api-bindings-v1/src/apollo/SafeApolloClient.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { - ApolloCache, - ApolloClient, - ApolloLink, - DefaultContext, - MutationOptions, - NormalizedCacheObject, - Observable, - OperationVariables, - QueryOptions, -} from '@apollo/client'; -import { getOperationName } from '@apollo/client/utilities'; -import { assertError, invariant } from '@lens-protocol/shared-kernel'; - -import { SemVer } from '../SemVer'; -import { - assertGraphQLClientMutationResult, - assertGraphQLClientQueryResult, - GraphQLClientMutationResult, - GraphQLClientQueryResult, - IGraphQLClient, -} from './IGraphQLClient'; -import { UnspecifiedError, ValidationError } from './errors'; -import { isGraphQLValidationError } from './isGraphQLValidationError'; - -const clientName = 'lens-sdk'; -const defaultPollingInterval = 3000; - -function resolveError(error: unknown) { - assertError(error); - - if (isGraphQLValidationError(error)) { - return new ValidationError(error); - } - return new UnspecifiedError(error); -} - -function isTerminating(link: ApolloLink): boolean { - return link.request.length <= 1; -} - -export type SafeApolloClientOptions = { - cache: ApolloCache; - /** - * @defaultValue false - */ - connectToDevTools?: boolean; - pollingInterval?: number; - version?: SemVer; - link: ApolloLink; -}; - -export class SafeApolloClient - extends ApolloClient - implements IGraphQLClient -{ - private pollingInterval: number; - - constructor({ - cache, - link, - pollingInterval = defaultPollingInterval, - version, - connectToDevTools = false, - }: SafeApolloClientOptions) { - invariant( - isTerminating(link), - 'The link passed to SafeApolloClient must be a terminating link.', - ); - - super({ - cache, - defaultOptions: { - query: { - errorPolicy: 'none', - }, - mutate: { - errorPolicy: 'none', - }, - watchQuery: { - errorPolicy: 'none', - }, - }, - link, - name: clientName, - version, - connectToDevTools, - }); - this.pollingInterval = pollingInterval; - } - - async query( - options: QueryOptions, - ): Promise> { - try { - const result = await super.query(options); - - assertGraphQLClientQueryResult(result, getOperationName(options.query) ?? 'unknown'); - - return result; - } catch (error) { - throw resolveError(error); - } - } - - async mutate( - options: MutationOptions>, - ): Promise> { - try { - const result = await super.mutate(options); - - assertGraphQLClientMutationResult(result, getOperationName(options.mutation) ?? 'unknown'); - - return result; - } catch (error) { - throw resolveError(error); - } - } - - poll( - options: QueryOptions, - ): Observable { - const observable = super.watchQuery(options); - - observable.startPolling(this.pollingInterval); - - return new Observable((observer) => - observable.subscribe({ - next({ data }) { - observer.next(data); - }, - error(err) { - observer.error(resolveError(err)); - }, - complete() { - observer.complete(); - }, - }), - ); - } -} diff --git a/packages/api-bindings-v1/src/apollo/__helpers__/mocks.ts b/packages/api-bindings-v1/src/apollo/__helpers__/mocks.ts deleted file mode 100644 index 1e56f3dcba..0000000000 --- a/packages/api-bindings-v1/src/apollo/__helpers__/mocks.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { NormalizedCacheObject } from '@apollo/client'; -import { MockedResponse, mockSingleLink } from '@apollo/client/testing'; -import { DocumentNode, ExecutionResult, GraphQLError } from 'graphql'; - -import { SafeApolloClient } from '../SafeApolloClient'; -import { createLensCache, createSnapshotCache } from '../cache'; -import { ApolloServerErrorCode } from '../isGraphQLValidationError'; - -export function mockLensApolloClient( - mocks: ReadonlyArray> = [], -): SafeApolloClient { - return new SafeApolloClient({ - cache: createLensCache(), - - link: mockSingleLink(...mocks).setOnError((error) => { - throw error; - }), - - pollingInterval: 1, // FAST - }); -} - -export function mockSnapshotApolloClient( - mocks: ReadonlyArray>, -): SafeApolloClient { - return new SafeApolloClient({ - cache: createSnapshotCache(), - - link: mockSingleLink(...mocks).setOnError((error) => { - throw error; - }), - - pollingInterval: 1, // FAST - }); -} - -export function createGraphQLError({ - code, - message = 'No pings please!', -}: { - code: string; - message: string; -}): GraphQLError { - return new GraphQLError(message, { - extensions: { - code, - }, - }); -} - -export function createGraphQLValidationError(message = 'No pings please!'): GraphQLError { - return createGraphQLError({ - message, - code: ApolloServerErrorCode.GRAPHQL_VALIDATION_FAILED, - }); -} - -export function mockValidationErrorResponse(document: DocumentNode): MockedResponse { - return { - request: { - query: document, - }, - result: { - errors: [createGraphQLValidationError()], - }, - }; -} - -export function mockGenericSuccessResponse(document: DocumentNode, data: T): MockedResponse { - return { - request: { - query: document, - }, - result: { data }, - }; -} - -export function mockGenericErrorResponse(document: DocumentNode): MockedResponse { - return { - request: { - query: document, - }, - result: { - errors: [ - createGraphQLError({ - message: 'No pings please!', - code: ApolloServerErrorCode.INTERNAL_SERVER_ERROR, - }), - ], - }, - }; -} - -export function createHttpJsonResponse( - status: number, - body: ExecutionResult, - headers: Record = {}, -): Response { - return new Response(JSON.stringify(body), { - status, - headers: { - ...headers, - 'Content-Type': 'application/json', - }, - }); -} - -export function createUnauthenticatedHttpResponse() { - return createHttpJsonResponse(401, { - data: null, - errors: [ - createGraphQLError({ - message: 'Authentication required', - code: 'UNAUTHENTICATED', - }), - ], - }); -} diff --git a/packages/api-bindings-v1/src/apollo/__tests__/SafeApolloClient.spec.ts b/packages/api-bindings-v1/src/apollo/__tests__/SafeApolloClient.spec.ts deleted file mode 100644 index e05ed3efe1..0000000000 --- a/packages/api-bindings-v1/src/apollo/__tests__/SafeApolloClient.spec.ts +++ /dev/null @@ -1,184 +0,0 @@ -// eslint-disable-next-line no-restricted-imports -import { createHttpLink, gql, InMemoryCache, Observable } from '@apollo/client'; -import { mockSingleLink } from '@apollo/client/testing'; -import { GraphQLError } from 'graphql'; - -import { SafeApolloClient } from '../SafeApolloClient'; -import { - mockValidationErrorResponse, - mockGenericErrorResponse, - mockGenericSuccessResponse, - createUnauthenticatedHttpResponse, -} from '../__helpers__/mocks'; -import { UnspecifiedError, ValidationError } from '../errors'; - -const query = gql` - query Ping { - ping - } -`; - -function observableToPromise(observable: Observable): Promise { - return new Promise((resolve, reject) => { - const subscription = observable.subscribe({ - next: (data) => { - subscription.unsubscribe(); - resolve(data); - }, - error: reject, - }); - }); -} - -describe(`Given an instance of the ${SafeApolloClient.name}`, () => { - describe(`when invoking the "${SafeApolloClient.prototype.query.name}" method`, () => { - it(`should throw a ${ValidationError.name} in case of ${GraphQLError.name} with GRAPHQL_VALIDATION_FAILED code`, async () => { - const client = new SafeApolloClient({ - cache: new InMemoryCache(), - - link: mockSingleLink(mockValidationErrorResponse(query)).setOnError((error) => { - throw error; - }), - }); - - return expect(() => client.query({ query })).rejects.toThrow(ValidationError); - }); - - it(`should throw an ${UnspecifiedError.name} in case of ${GraphQLError.name}`, async () => { - const client = new SafeApolloClient({ - cache: new InMemoryCache(), - - link: mockSingleLink(mockGenericErrorResponse(query)).setOnError((error) => { - throw error; - }), - }); - - return expect(() => client.query({ query })).rejects.toThrow(UnspecifiedError); - }); - - it(`should throw an ${UnspecifiedError.name} in case of ServerError (a specific type of NetworkError)`, async () => { - const fetch = jest.fn().mockResolvedValue(createUnauthenticatedHttpResponse()); - const client = new SafeApolloClient({ - cache: new InMemoryCache(), - - link: createHttpLink({ - fetch, - uri: 'http://localhost:4000/graphql', - }), - }); - - return expect(() => client.query({ query })).rejects.toThrow(UnspecifiedError); - }); - }); - - describe(`when invoking the "${SafeApolloClient.prototype.mutate.name}" method`, () => { - const mutation = gql` - mutation Ping { - ping - } - `; - - it(`should throw a ${ValidationError.name} in case of ${GraphQLError.name} with GRAPHQL_VALIDATION_FAILED code`, async () => { - const client = new SafeApolloClient({ - cache: new InMemoryCache(), - - link: mockSingleLink(mockValidationErrorResponse(mutation)).setOnError((error) => { - throw error; - }), - }); - - return expect(() => client.mutate({ mutation })).rejects.toThrow(ValidationError); - }); - - it(`should throw an ${UnspecifiedError.name} in case of ${GraphQLError.name}`, async () => { - const client = new SafeApolloClient({ - cache: new InMemoryCache(), - - link: mockSingleLink(mockGenericErrorResponse(mutation)).setOnError((error) => { - throw error; - }), - }); - - return expect(() => client.mutate({ mutation })).rejects.toThrow(UnspecifiedError); - }); - - it(`should throw an ${UnspecifiedError.name} in case of ServerError (a specific type of NetworkError)`, async () => { - const fetch = jest.fn().mockResolvedValue(createUnauthenticatedHttpResponse()); - const client = new SafeApolloClient({ - cache: new InMemoryCache(), - - link: createHttpLink({ - fetch, - uri: 'http://localhost:4000/graphql', - }), - }); - - return expect(() => client.mutate({ mutation })).rejects.toThrow(UnspecifiedError); - }); - }); - - describe(`when invoking the "${SafeApolloClient.prototype.poll.name}" method`, () => { - it(`should emit the fetched data`, async () => { - const client = new SafeApolloClient({ - cache: new InMemoryCache(), - - link: mockSingleLink( - mockGenericSuccessResponse(query, { ping: false }), - mockGenericSuccessResponse(query, { ping: true }), - ).setOnError((error) => { - throw error; - }), - }); - - const observable = client.poll({ query }); - - return expect(observableToPromise(observable)).resolves.toMatchObject({ - ping: expect.any(Boolean), - }); - }); - - it(`should emit a ${ValidationError.name} in case of ${GraphQLError.name} with GRAPHQL_VALIDATION_FAILED code`, async () => { - const client = new SafeApolloClient({ - cache: new InMemoryCache(), - - link: mockSingleLink(mockValidationErrorResponse(query)).setOnError((error) => { - throw error; - }), - }); - - const observable = client.poll({ query }); - - return expect(observableToPromise(observable)).rejects.toThrow(ValidationError); - }); - - it(`should emit an ${UnspecifiedError.name} in case of ${GraphQLError.name}`, async () => { - const client = new SafeApolloClient({ - cache: new InMemoryCache(), - - link: mockSingleLink(mockGenericErrorResponse(query)).setOnError((error) => { - throw error; - }), - }); - - const observable = client.poll({ query }); - - return expect(observableToPromise(observable)).rejects.toThrow(UnspecifiedError); - }); - - it(`should emit an ${UnspecifiedError.name} in case of ServerError (a specific type of NetworkError)`, async () => { - const fetch = jest.fn().mockResolvedValue(createUnauthenticatedHttpResponse()); - const client = new SafeApolloClient({ - cache: new InMemoryCache(), - - link: createHttpLink({ - fetch, - uri: 'http://localhost:4000/graphql', - }), - }); - - const observable = client.poll({ query }); - - return expect(observableToPromise(observable)).rejects.toThrow(UnspecifiedError); - }); - }); -}); diff --git a/packages/api-bindings-v1/src/apollo/__tests__/links.spec.ts b/packages/api-bindings-v1/src/apollo/__tests__/links.spec.ts deleted file mode 100644 index 802450e242..0000000000 --- a/packages/api-bindings-v1/src/apollo/__tests__/links.spec.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { ApolloClient, gql, InMemoryCache } from '@apollo/client'; -import { ILogger } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; - -import { semVer } from '../../SemVer'; -import { createHttpJsonResponse } from '../__helpers__/mocks'; -import { createLensLink } from '../links'; - -const query = gql` - query Ping { - ping - } -`; - -describe(`Given an instance of the ${ApolloClient.name}`, () => { - describe('wired with our custom LensLink', () => { - const supportedVersion = semVer('2.0.0'); - - describe(`when the response 'x-api-version' is ahead by a major version or more compared to the SDK supported range`, () => { - it(`should use the ILogger to log a warning that the Lens API version is likely not supported by the current Lens SDK client`, async () => { - const logger = mock(); - const response = createHttpJsonResponse( - 200, - { - data: { ping: null }, - }, - { 'x-api-version': semVer('3.0.0') }, - ); - const client = new ApolloClient({ - cache: new InMemoryCache(), - link: createLensLink({ - fetch: jest.fn().mockResolvedValue(response), - logger, - uri: 'http://localhost:4000/graphql', - supportedVersion, - }), - }); - - await client.query({ query }); - - expect(logger.warn).toHaveBeenCalled(); - }); - }); - - describe(`when the response 'x-api-version' is older than the SDK supported range`, () => { - it(`should use the ILogger to log an that there is a significant incompatibility between the Lens SDK client used and the Lens API version`, async () => { - const logger = mock(); - const response = createHttpJsonResponse( - 200, - { - data: { ping: null }, - }, - { 'x-api-version': semVer('1.0.0') }, - ); - const client = new ApolloClient({ - cache: new InMemoryCache(), - link: createLensLink({ - fetch: jest.fn().mockResolvedValue(response), - logger, - uri: 'http://localhost:4000/graphql', - supportedVersion, - }), - }); - - await client.query({ query }); - - expect(logger.error).toHaveBeenCalled(); - }); - }); - - describe(`when the response 'x-api-version' is ahead ONLY by minor versions compared to the SDK supported range`, () => { - it(`should use the ILogger to log an that there is a significant incompatibility between the Lens SDK client used and the Lens API version`, async () => { - const logger = mock(); - const response = createHttpJsonResponse( - 200, - { - data: { ping: null }, - }, - { 'x-api-version': semVer('2.1.0') }, - ); - const client = new ApolloClient({ - cache: new InMemoryCache(), - link: createLensLink({ - fetch: jest.fn().mockResolvedValue(response), - logger, - uri: 'http://localhost:4000/graphql', - supportedVersion, - }), - }); - - await client.query({ query }); - - expect(logger.info).toHaveBeenCalled(); - }); - }); - }); -}); diff --git a/packages/api-bindings-v1/src/apollo/cache/__helpers__/mocks.ts b/packages/api-bindings-v1/src/apollo/cache/__helpers__/mocks.ts deleted file mode 100644 index 0d0418d798..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/__helpers__/mocks.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { ApolloCache, NormalizedCacheObject, ReactiveVar } from '@apollo/client'; -import { faker } from '@faker-js/faker'; -import { mockCreatePostRequest, mockWalletData } from '@lens-protocol/domain/mocks'; -import { ProfileIdentifier, WalletData } from '@lens-protocol/domain/use-cases/lifecycle'; -import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; - -import { createLensCache } from '../createLensCache'; -import { - authenticatedProfile, - authenticatedWallet, - notAuthenticated, - updateSession, -} from '../session'; -import { TransactionState, TxStatus } from '../transactions'; - -export type MockCacheConfiguration = { - activeWalletVar?: ReactiveVar; -}; - -export function mockLensCache(): ApolloCache { - return createLensCache(); -} - -export function mockTransactionState( - partial: Partial>, -): TransactionState { - return { - id: faker.datatype.uuid(), - status: TxStatus.BROADCASTING, - request: mockCreatePostRequest() as T, - ...partial, - }; -} - -export function simulateAuthenticatedWallet(wallet = mockWalletData()) { - updateSession(authenticatedWallet(wallet)); -} - -export function simulateAuthenticatedProfile( - profile: ProfileIdentifier, - wallet = mockWalletData(), -) { - updateSession(authenticatedProfile(wallet, profile)); -} - -export function simulateNotAuthenticated() { - updateSession(notAuthenticated()); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/__tests__/ApolloCache.spec.ts b/packages/api-bindings-v1/src/apollo/cache/__tests__/ApolloCache.spec.ts deleted file mode 100644 index 613cf0a2fd..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/__tests__/ApolloCache.spec.ts +++ /dev/null @@ -1,643 +0,0 @@ -import { ApolloCache, DocumentNode } from '@apollo/client'; -import { empty } from '@apollo/client/link/core'; -import { DecryptionCriteriaType } from '@lens-protocol/domain/entities'; -import { - mockCreateMirrorRequest, - mockFreeCollectRequest, - mockProfile, - mockPublicationId, - mockUnconstrainedFollowRequest, - mockUnfollowRequest, - mockWalletData, -} from '@lens-protocol/domain/mocks'; -import { CollectPolicyType } from '@lens-protocol/domain/use-cases/publications'; -import { never } from '@lens-protocol/shared-kernel'; - -import { - CollectState, - ContentInsightType, - ContentPublication, - Profile, - FragmentComment, - FragmentPost, - FragmentProfile, - GetPublicationData, - GetPublicationVariables, - GetPublicationDocument, - GetProfileData, - GetProfileVariables, - GetProfileDocument, -} from '../../../lens'; -import { - mockAndAccessCondition, - mockAttributeFragment, - mockCollectConditionAccessCondition, - mockCommentFragment, - mockEncryptionParamsOutputFragment, - mockEoaOwnershipAccessCondition, - mockErc20OwnershipAccessCondition, - mockFollowConditionAccessCondition, - mockFreeCollectModuleSettings, - mockMetadataOutputFragment, - mockNftOwnershipAccessCondition, - mockOrAccessCondition, - mockTransactionState, - mockPostFragment, - mockProfileFragment, - mockProfileOwnershipAccessCondition, - mockPublicationStatsFragment, - mockSnapshotPollUrl, - simulateAuthenticatedProfile, - simulateAuthenticatedWallet, -} from '../../../mocks'; -import { SafeApolloClient } from '../../SafeApolloClient'; -import { createLensCache } from '../createLensCache'; -import { erc20Amount } from '../decryptionCriteria'; -import { resetSession } from '../session'; -import { recentTransactionsVar } from '../transactions'; -import { snapshotPoll } from '../utils/ContentInsight'; - -const typeToFragmentMap: Record = { - Post: FragmentPost, - Comment: FragmentComment, -}; - -function setupApolloCache() { - const cache = createLensCache({ contentMatchers: [snapshotPoll] }); - - return { - writePublication(publication: ContentPublication) { - cache.writeFragment({ - id: cache.identify(publication), - fragment: typeToFragmentMap[publication.__typename], - fragmentName: publication.__typename, - data: publication, - }); - }, - - readPublication(publication: ContentPublication) { - return ( - cache.readFragment({ - id: cache.identify(publication), - fragment: typeToFragmentMap[publication.__typename], - fragmentName: publication.__typename, - }) ?? never('cannot read publication') - ); - }, - - writeProfileFragment(profile: Profile) { - cache.writeFragment({ - data: profile, - fragment: FragmentProfile, - fragmentName: 'Profile', - }); - }, - - readProfileFragment(profile: Profile) { - return ( - cache.readFragment({ - fragment: FragmentProfile, - fragmentName: 'Profile', - id: cache.identify(profile), - }) ?? never('cannot read profile') - ); - }, - - get client() { - return new SafeApolloClient({ - cache, - link: empty(), - }); - }, - }; -} - -describe(`Given an instance of the ${ApolloCache.name}`, () => { - describe.each([ - { - typename: 'Post', - mockPublicationFragment: mockPostFragment, - }, - { - typename: 'Comment', - mockPublicationFragment: mockCommentFragment, - }, - ])('and a cached $typename', ({ mockPublicationFragment, typename }) => { - describe(`when reading the same ${typename} via the "publication" query`, () => { - const publication = mockPublicationFragment(); - const { client, writePublication } = setupApolloCache(); - - beforeAll(() => { - writePublication(publication); - }); - - it('should perform a cache redirect and avoid a extra network request', async () => { - const { data } = await client.query({ - query: GetPublicationDocument, - variables: { request: { publicationId: publication.id }, sources: [] }, - }); - - expect(data.result).toMatchObject(publication); - }); - }); - - describe('when reading "contentInsights"', () => { - it('should detect Snapshot URLs in the content and return the SnapshotPoll', () => { - const publication = mockPostFragment({ - profile: mockProfileFragment(), - metadata: mockMetadataOutputFragment({ - content: `Hey what do you think of: ${mockSnapshotPollUrl()}`, - }), - }); - - const { writePublication, readPublication } = setupApolloCache(); - writePublication(publication); - const read = readPublication(publication); - - expect(read.contentInsight).toMatchObject({ - type: ContentInsightType.SNAPSHOT_POLL, - proposalId: expect.any(String), - spaceId: expect.any(String), - url: expect.any(String), - }); - }); - }); - - describe('when reading "collectPolicy"', () => { - it('should support "CollectPolicy" for free collect', () => { - const publication = mockPublicationFragment({ - profile: mockProfileFragment(), - collectModule: mockFreeCollectModuleSettings(), - collectPolicy: undefined, - stats: mockPublicationStatsFragment(), - }); - - const { writePublication, readPublication } = setupApolloCache(); - writePublication(publication); - const read = readPublication(publication); - - expect(read.collectPolicy).toMatchObject({ - type: CollectPolicyType.FREE, - state: CollectState.CAN_BE_COLLECTED, - followerOnly: false, - }); - }); - - it('should support "CollectPolicy" for not follower profile, free collect with followerOnly flag', () => { - const publication = mockPublicationFragment({ - profile: mockProfileFragment({ - isFollowedByMe: false, - }), - collectModule: mockFreeCollectModuleSettings({ followerOnly: true }), - collectPolicy: undefined, - stats: mockPublicationStatsFragment(), - }); - - const { writePublication, readPublication } = setupApolloCache(); - writePublication(publication); - const read = readPublication(publication); - - expect(read.collectPolicy).toMatchObject({ - type: CollectPolicyType.FREE, - state: CollectState.NOT_A_FOLLOWER, - followerOnly: true, - }); - }); - - it('should support "CollectPolicy" for a follower profile, free collect with followerOnly flag', () => { - const publication = mockPublicationFragment({ - profile: mockProfileFragment({ - isFollowedByMe: true, - }), - collectModule: mockFreeCollectModuleSettings({ followerOnly: true }), - collectPolicy: undefined, - stats: mockPublicationStatsFragment(), - }); - - const { writePublication, readPublication } = setupApolloCache(); - writePublication(publication); - const read = readPublication(publication); - - expect(read.collectPolicy).toMatchObject({ - type: CollectPolicyType.FREE, - state: CollectState.CAN_BE_COLLECTED, - followerOnly: true, - }); - }); - }); - - describe('and an active profile is defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - afterAll(() => { - resetSession(); - }); - - describe('when reading "hasCollectedByMe" while an active profile is defined', () => { - it('should return "true" if a a collect transaction for the same publication is pending', () => { - const publication = mockPublicationFragment({ - profile: mockProfileFragment(), - hasCollectedByMe: false, - }); - - recentTransactionsVar([ - mockTransactionState({ - request: mockFreeCollectRequest({ - profileId: activeProfile.id, - publicationId: publication.id, - }), - }), - ]); - - const { writePublication, readPublication } = setupApolloCache(); - writePublication(publication); - const read = readPublication(publication); - - expect(read.hasCollectedByMe).toBe(true); - }); - }); - - describe('when reading "isMirroredByMe" while an active profile is defined', () => { - it('should return "true" if a mirror transaction for the same publication is pending', () => { - const publication = mockPublicationFragment({ - profile: mockProfileFragment(), - mirrors: [], - isMirroredByMe: false, - }); - - recentTransactionsVar([ - mockTransactionState({ - request: mockCreateMirrorRequest({ - profileId: activeProfile.id, - publicationId: publication.id, - }), - }), - ]); - - const { writePublication, readPublication } = setupApolloCache(); - writePublication(publication); - const read = readPublication(publication); - - expect(read.isMirroredByMe).toBe(true); - }); - }); - }); - - describe('when reading "decryptionCriteria"', () => { - it('should return "null" if not token-gated', () => { - const publication = mockPublicationFragment({ - isGated: false, - }); - const { writePublication, readPublication } = setupApolloCache(); - writePublication(publication); - - const read = readPublication(publication); - - expect(read.decryptionCriteria).toBe(null); - }); - - const author = mockProfileFragment(); - - const nftCondition = mockNftOwnershipAccessCondition(); - const erc20Condition = mockErc20OwnershipAccessCondition(); - const eoaCondition = mockEoaOwnershipAccessCondition(); - const profileCondition = mockProfileOwnershipAccessCondition(); - const followCondition = mockFollowConditionAccessCondition(); - const collectCondition = mockCollectConditionAccessCondition(); - const collectThisCondition = mockCollectConditionAccessCondition({ - publicationId: mockPublicationId(), - thisPublication: true, - }); - - it.each([ - { - description: 'NFT Ownership access condition', - criterion: nftCondition, - expectations: { - type: DecryptionCriteriaType.NFT_OWNERSHIP, - contractAddress: nftCondition.nft?.contractAddress ?? never(), - chainId: nftCondition.nft?.chainID ?? never(), - contractType: nftCondition.nft?.contractType ?? never(), - tokenIds: nftCondition.nft?.tokenIds ?? never(), - }, - }, - { - description: 'ERC20 Ownership access condition', - criterion: erc20Condition, - expectations: { - type: DecryptionCriteriaType.ERC20_OWNERSHIP, - amount: erc20Amount({ from: erc20Condition.token ?? never() }), - condition: erc20Condition.token?.condition ?? never(), - }, - }, - { - description: 'Address Ownership access condition', - criterion: eoaCondition, - expectations: { - type: DecryptionCriteriaType.ADDRESS_OWNERSHIP, - address: eoaCondition.eoa?.address ?? never(), - }, - }, - { - description: 'Profile Ownership access condition', - criterion: profileCondition, - expectations: { - type: DecryptionCriteriaType.PROFILE_OWNERSHIP, - profileId: profileCondition.profile?.profileId ?? never(), - }, - }, - { - description: 'Follow access condition', - criterion: followCondition, - expectations: { - type: DecryptionCriteriaType.FOLLOW_PROFILE, - profileId: followCondition.follow?.profileId ?? never(), - }, - }, - { - description: 'Collect access condition', - criterion: collectCondition, - expectations: { - type: DecryptionCriteriaType.COLLECT_PUBLICATION, - publicationId: collectCondition.collect?.publicationId ?? never(), - }, - }, - { - description: 'Collect access condition', - criterion: collectThisCondition, - expectations: { - type: DecryptionCriteriaType.COLLECT_THIS_PUBLICATION, - }, - }, - { - description: '2+ criteria in AND condition', - criterion: mockAndAccessCondition([followCondition, collectCondition]), - expectations: { - type: DecryptionCriteriaType.AND, - and: [ - { - type: DecryptionCriteriaType.FOLLOW_PROFILE, - profileId: followCondition.follow?.profileId ?? never(), - }, - { - type: DecryptionCriteriaType.COLLECT_PUBLICATION, - publicationId: collectCondition.collect?.publicationId ?? never(), - }, - ], - }, - }, - { - description: '2+ criteria in OR condition', - criterion: mockOrAccessCondition([followCondition, collectCondition]), - expectations: { - type: DecryptionCriteriaType.OR, - or: [ - { - type: DecryptionCriteriaType.FOLLOW_PROFILE, - profileId: followCondition.follow?.profileId ?? never(), - }, - { - type: DecryptionCriteriaType.COLLECT_PUBLICATION, - publicationId: collectCondition.collect?.publicationId ?? never(), - }, - ], - }, - }, - ])('should return "DecryptionCriteria" for $description', ({ criterion, expectations }) => { - const metadata = mockMetadataOutputFragment({ - encryptionParams: mockEncryptionParamsOutputFragment({ - ownerId: author.id, - others: [criterion], - }), - }); - const publication = mockPublicationFragment({ - isGated: true, - metadata, - profile: author, - }); - - const { writePublication, readPublication } = setupApolloCache(); - writePublication(publication); - - const read = readPublication(publication); - - expect(read.decryptionCriteria).toEqual(expectations); - }); - }); - }); - - describe('and a cached Profile', () => { - describe('when reading its "attributes"', () => { - const date = new Date(); - const profile = mockProfileFragment({ - __attributes: [ - mockAttributeFragment({ - key: 'validDate', - value: date.toISOString(), - }), - mockAttributeFragment({ - key: 'invalidDate', - value: 'invalid', - }), - mockAttributeFragment({ - key: 'validNumber', - value: '42', - }), - mockAttributeFragment({ - key: 'invalidNumber', - value: '', - }), - mockAttributeFragment({ - key: 'string', - value: 'NY', - }), - mockAttributeFragment({ - key: 'validBoolean', - value: 'true', - }), - mockAttributeFragment({ - key: 'invalidBoolean', - value: '1', - }), - ], - }); - const { writeProfileFragment, readProfileFragment } = setupApolloCache(); - - writeProfileFragment(profile); - - const read = readProfileFragment(profile); - - it('should allow to access date attributes as Date instances', () => { - expect(read.attributes.validDate?.toDate()).toEqual(date); - }); - - it('should allow to access date attributes as string', () => { - expect(read.attributes.validDate?.toString()).toEqual(date.toISOString()); - }); - - it('should return "null" if attempting to access date attributes as Number', () => { - expect(read.attributes.validDate?.toNumber()).toEqual(null); - }); - - it('should return "null" if parsing a date attribute fails', () => { - expect(read.attributes.invalidDate?.toDate()).toBe(null); - }); - - it('should allow to access number attributes as Number', () => { - expect(read.attributes.validNumber?.toNumber()).toEqual(42); - }); - - it('should allow to access number attributes as String', () => { - expect(read.attributes.validNumber?.toString()).toEqual('42'); - }); - - it('should return "null" if parsing a number attribute fails', () => { - expect(read.attributes.invalidNumber?.toNumber()).toBe(null); - }); - - it('should allow to access boolean attributes as Boolean', () => { - expect(read.attributes.validBoolean?.toBoolean()).toBe(true); - }); - - it('should return "null" if parsing a boolean attribute fails', () => { - expect(read.attributes.invalidBoolean?.toBoolean()).toBe(null); - }); - - it('should allow to access string attributes as String', () => { - expect(read.attributes.string?.toString()).toEqual('NY'); - }); - }); - - describe(`when reading the same Profile via the "profile" query`, () => { - const profile = mockProfileFragment(); - const { client, writeProfileFragment } = setupApolloCache(); - - beforeAll(() => { - writeProfileFragment(profile); - }); - - it('should perform a cache redirect and avoid a extra network request', async () => { - const { data } = await client.query({ - query: GetProfileDocument, - variables: { request: { profileId: profile.id } }, - }); - - expect(data.result).toMatchObject(profile); - }); - - it('should attempt a cache redirect even if queried by its handle', async () => { - const { data } = await client.query({ - query: GetProfileDocument, - variables: { request: { handle: profile.handle } }, - }); - - expect(data.result).toMatchObject(profile); - }); - }); - - describe('and a Session is defined', () => { - const wallet = mockWalletData(); - const { writeProfileFragment, readProfileFragment } = setupApolloCache(); - - beforeAll(() => { - simulateAuthenticatedWallet(wallet); - }); - - describe('when the profile is followed by the one specified as the "observerId"', () => { - const profile = mockProfileFragment({ - isFollowedByMe: true, - }); - - beforeEach(() => { - writeProfileFragment(profile); - }); - - it(`should have the expected "followStatus" - - isFollowedByMe=true - - canFollow=false - - canUnfollow=true`, () => { - const { followStatus } = readProfileFragment(profile); - - expect(followStatus).toMatchObject({ - isFollowedByMe: true, - canFollow: false, - canUnfollow: true, - }); - }); - - describe('but there is a pending unfollow transaction for the given profile', () => { - it(`should have the expected "followStatus" - - isFollowedByMe=false - - canFollow=false - - canUnfollow=false`, () => { - recentTransactionsVar([ - mockTransactionState({ - request: mockUnfollowRequest({ - profileId: profile.id, - }), - }), - ]); - - const { followStatus } = readProfileFragment(profile); - - expect(followStatus).toMatchObject({ - isFollowedByMe: false, - canFollow: false, - canUnfollow: false, - }); - }); - }); - }); - - describe('when the profile is NOT followed by the one specified as the "observerId"', () => { - const profile = mockProfileFragment({ - isFollowedByMe: false, - }); - - beforeEach(() => { - writeProfileFragment(profile); - }); - - it(`should have the expected "followStatus" - - isFollowedByMe=false - - canFollow=true - - canUnfollow=false`, () => { - const { followStatus } = readProfileFragment(profile); - - expect(followStatus).toMatchObject({ - isFollowedByMe: false, - canFollow: true, - canUnfollow: false, - }); - }); - - describe('but there is a pending follow transaction for the given profile', () => { - it(`should have the expected "followStatus" - - isFollowedByMe=true - - canFollow=false - - canUnfollow=false`, () => { - recentTransactionsVar([ - mockTransactionState({ - request: mockUnconstrainedFollowRequest({ - profileId: profile.id, - followerAddress: wallet.address, - }), - }), - ]); - const { followStatus } = readProfileFragment(profile); - - expect(followStatus).toMatchObject({ - isFollowedByMe: true, - canFollow: false, - canUnfollow: false, - }); - }); - }); - }); - }); - }); -}); diff --git a/packages/api-bindings-v1/src/apollo/cache/createAttributeTypePolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createAttributeTypePolicy.ts deleted file mode 100644 index e417297011..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createAttributeTypePolicy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { StrictTypedTypePolicies } from '../../lens'; - -export const createAttributeTypePolicy = (): StrictTypedTypePolicies['Attribute'] => ({ - keyFields: false, -}); diff --git a/packages/api-bindings-v1/src/apollo/cache/createExploreProfileFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createExploreProfileFieldPolicy.ts deleted file mode 100644 index 2cf42c9fe4..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createExploreProfileFieldPolicy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createExploreProfilesFieldPolicy() { - return cursorBasedPagination([['request', ['sortCriteria']], '$observerId', '$sources']); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createExplorePublicationsFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createExplorePublicationsFieldPolicy.ts deleted file mode 100644 index 5cd9998150..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createExplorePublicationsFieldPolicy.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createExplorePublicationsFieldPolicy() { - return cursorBasedPagination([ - [ - 'request', - [ - 'excludeProfileIds', - 'metadata', - 'publicationTypes', - 'sortCriteria', - 'sources', - 'timestamp', - 'noRandomize', - ], - ], - '$observerId', - ]); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createFeedFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createFeedFieldPolicy.ts deleted file mode 100644 index d2144ebdc8..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createFeedFieldPolicy.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createFeedFieldPolicy() { - return cursorBasedPagination([ - ['request', ['profileId', 'feedEventItemTypes', 'sources', 'metadata']], - '$observerId', - ]); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createLensCache.ts b/packages/api-bindings-v1/src/apollo/cache/createLensCache.ts deleted file mode 100644 index fa9f02761c..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createLensCache.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { - ApolloCache, - FieldPolicy, - InMemoryCache, - NormalizedCacheObject, - TypePolicy, -} from '@apollo/client'; - -import generatedIntrospection, { StrictTypedTypePolicies } from '../../lens/generated'; -import { createAttributeTypePolicy } from './createAttributeTypePolicy'; -import { createExploreProfilesFieldPolicy } from './createExploreProfileFieldPolicy'; -import { createExplorePublicationsFieldPolicy } from './createExplorePublicationsFieldPolicy'; -import { createFeedFieldPolicy } from './createFeedFieldPolicy'; -import { createMediaSetTypePolicy } from './createMediaSetTypePolicy'; -import { createMediaTypePolicy } from './createMediaTypePolicy'; -import { createNftImageTypePolicy } from './createNftImageTypePolicy'; -import { createNotificationsFieldPolicy } from './createNotificationsFieldPolicy'; -import { createProfileFieldPolicy } from './createProfileFieldPolicy'; -import { createProfileFollowersFieldPolicy } from './createProfileFollowersFieldPolicy'; -import { createProfileFollowingFieldPolicy } from './createProfileFollowingFieldPolicy'; -import { createProfilePublicationRevenueFieldPolicy } from './createProfilePublicationRevenueFieldPolicy'; -import { createProfilePublicationsForSaleFieldPolicy } from './createProfilePublicationsForSaleFieldPolicy'; -import { createProfileTypePolicy } from './createProfileTypePolicy'; -import { createProfilesFieldPolicy } from './createProfilesFieldPolicy'; -import { createPublicationsFieldPolicy } from './createPublicationsFieldPolicy'; -import { createPublicationsProfileBookmarks } from './createPublicationsProfileBookmarks'; -import { createRevenueAggregateTypePolicy } from './createRevenueAggregateTypePolicy'; -import { createSearchFieldPolicy } from './createSearchFieldPolicy'; -import { createWhoReactedPublicationFieldPolicy } from './createWhoReactedPublicationFieldPolicy'; -import { - createCommentTypePolicy, - createPublicationTypePolicy, - createPostTypePolicy, - createPublicationFieldPolicy, -} from './publication'; -import { ContentInsightMatcher } from './utils/ContentInsight'; -import { noCachedField } from './utils/noCachedField'; -import { notNormalizedType } from './utils/notNormalizedType'; - -type TypePoliciesArgs = { - /** - * A list of ContentInsightMatcher used to extract insights from publication metadata content - */ - contentMatchers?: ContentInsightMatcher[]; -}; - -type InheritedTypePolicies = { - Publication: TypePolicy; -}; - -function createTypePolicies({ - contentMatchers = [], -}: TypePoliciesArgs): StrictTypedTypePolicies & InheritedTypePolicies { - return { - Profile: createProfileTypePolicy(), - - // Comment, Mirror, and Post type policies inherit from Publication type policy - Publication: createPublicationTypePolicy(), - Comment: createCommentTypePolicy({ contentMatchers }), - Post: createPostTypePolicy({ contentMatchers }), - - FeedItem: notNormalizedType(), - - MetadataOutput: notNormalizedType(), - PublicationStats: notNormalizedType({ - fields: { - commentsTotal: noCachedField(), - }, - }), - ProfileStats: notNormalizedType({ - fields: { - commentsTotal: noCachedField(), - postsTotal: noCachedField(), - mirrorsTotal: noCachedField(), - }, - }), - - AccessConditionOutput: notNormalizedType(), - EncryptionParamsOutput: notNormalizedType(), - - Attribute: createAttributeTypePolicy(), - MediaSet: createMediaSetTypePolicy(), - NftImage: createNftImageTypePolicy(), - Media: createMediaTypePolicy(), - - RevenueAggregate: createRevenueAggregateTypePolicy(), - - // ensures that no matter what fields we add to it in the future, it will NOT be normalized - PaginatedResultInfo: notNormalizedType(), - - Query: { - fields: { - feed: createFeedFieldPolicy(), - exploreProfiles: createExploreProfilesFieldPolicy(), - explorePublications: createExplorePublicationsFieldPolicy(), - notifications: createNotificationsFieldPolicy(), - profile: createProfileFieldPolicy() as FieldPolicy, - profiles: createProfilesFieldPolicy(), - profilePublicationsForSale: createProfilePublicationsForSaleFieldPolicy(), - publications: createPublicationsFieldPolicy(), - publication: createPublicationFieldPolicy() as FieldPolicy, - search: createSearchFieldPolicy(), - whoReactedPublication: createWhoReactedPublicationFieldPolicy(), - followers: createProfileFollowersFieldPolicy(), - following: createProfileFollowingFieldPolicy(), - profilePublicationRevenue: createProfilePublicationRevenueFieldPolicy(), - publicationsProfileBookmarks: createPublicationsProfileBookmarks(), - }, - }, - }; -} - -export function createLensCache(args: TypePoliciesArgs = {}): ApolloCache { - return new InMemoryCache({ - possibleTypes: generatedIntrospection.possibleTypes, - typePolicies: createTypePolicies(args), - }); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createMediaSetTypePolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createMediaSetTypePolicy.ts deleted file mode 100644 index eb5c72eceb..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createMediaSetTypePolicy.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { StrictTypedTypePolicies } from '../../lens'; - -export const createMediaSetTypePolicy = (): StrictTypedTypePolicies['MediaSet'] => ({ - keyFields: false, - fields: { - transformed: { - keyArgs: false, - }, - }, -}); diff --git a/packages/api-bindings-v1/src/apollo/cache/createMediaTypePolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createMediaTypePolicy.ts deleted file mode 100644 index 83f8ac1d6a..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createMediaTypePolicy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { StrictTypedTypePolicies } from '../../lens'; - -export const createMediaTypePolicy = (): StrictTypedTypePolicies['Media'] => ({ - keyFields: false, -}); diff --git a/packages/api-bindings-v1/src/apollo/cache/createNftImageTypePolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createNftImageTypePolicy.ts deleted file mode 100644 index 93ef0ab4f5..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createNftImageTypePolicy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { StrictTypedTypePolicies } from '../../lens'; - -export const createNftImageTypePolicy = (): StrictTypedTypePolicies['NftImage'] => ({ - keyFields: false, -}); diff --git a/packages/api-bindings-v1/src/apollo/cache/createNotificationsFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createNotificationsFieldPolicy.ts deleted file mode 100644 index 8f1e15609f..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createNotificationsFieldPolicy.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createNotificationsFieldPolicy() { - return cursorBasedPagination([ - ['request', ['profileId', 'sources', 'notificationTypes']], - '$observerId', - ]); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createProfileFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createProfileFieldPolicy.ts deleted file mode 100644 index 8a391b1d6c..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createProfileFieldPolicy.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { - defaultDataIdFromObject, - FieldFunctionOptions, - FieldPolicy, - Reference, - StoreObject, -} from '@apollo/client'; -import { never } from '@lens-protocol/shared-kernel'; - -import { Profile, SingleProfileQueryRequest } from '../../lens'; - -function isProfile(value: StoreObject | undefined): value is Profile { - return value?.__typename === 'Profile'; -} - -const identifierPattern = - defaultDataIdFromObject({ __typename: 'Profile', id: '0x[a-fA-F0-9]{2,}' }) ?? never(); -const identifierMatcher = new RegExp(`^${identifierPattern}$`); - -export function createProfileFieldPolicy(): FieldPolicy< - Profile, - Profile, - Reference, - FieldFunctionOptions<{ request: SingleProfileQueryRequest }> -> { - return { - keyArgs: [['request', ['profileId', 'handle']], '$observerId', '$sources'], - - read(_, { args, toReference, cache }) { - if (args?.request.profileId) { - return toReference({ - __typename: 'Profile', - id: args.request.profileId, - }); - } - - const normalizedCacheObject = cache.extract(true); - - for (const key in normalizedCacheObject) { - const value = normalizedCacheObject[key]; - - if ( - identifierMatcher.test(key) && - isProfile(value) && - value.handle === args?.request.handle - ) { - return toReference(value); - } - } - return; - }, - }; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createProfileFollowersFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createProfileFollowersFieldPolicy.ts deleted file mode 100644 index 061433fadf..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createProfileFollowersFieldPolicy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createProfileFollowersFieldPolicy() { - return cursorBasedPagination([['request', ['profileId']], '$observerId', '$sources']); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createProfileFollowingFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createProfileFollowingFieldPolicy.ts deleted file mode 100644 index a4ecd8cfad..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createProfileFollowingFieldPolicy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createProfileFollowingFieldPolicy() { - return cursorBasedPagination([['request', ['address']], '$observerId', '$sources']); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createProfilePublicationRevenueFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createProfilePublicationRevenueFieldPolicy.ts deleted file mode 100644 index 7f82c5cdca..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createProfilePublicationRevenueFieldPolicy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createProfilePublicationRevenueFieldPolicy() { - return cursorBasedPagination([['request', ['profileId', 'types', 'sources']], '$observerId']); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createProfilePublicationsForSaleFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createProfilePublicationsForSaleFieldPolicy.ts deleted file mode 100644 index 234c560500..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createProfilePublicationsForSaleFieldPolicy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createProfilePublicationsForSaleFieldPolicy() { - return cursorBasedPagination([['request', ['profileId', 'sources']], '$observerId']); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createProfileTypePolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createProfileTypePolicy.ts deleted file mode 100644 index a02833980a..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createProfileTypePolicy.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { FieldFunctionOptions } from '@apollo/client'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { FollowPolicyType } from '@lens-protocol/domain/use-cases/profile'; -import { never } from '@lens-protocol/shared-kernel'; - -import { - erc20Amount, - FollowPolicy, - FollowModule, - FollowStatus, - ProfileAttributeReader, - ProfileAttributes, - StrictTypedTypePolicies, - ProfileCoverSet, - Attribute, - ProfilePictureSet, -} from '../../lens'; -import { getSession } from './session'; -import { - getAllPendingTransactions, - isFollowTransactionFor, - isUnfollowTransactionFor, -} from './transactions'; -import { observedBy } from './utils/observedBy'; - -function resolveFollowPolicy({ followModule }: { followModule: FollowModule }): FollowPolicy { - if (followModule === null) { - return { - type: FollowPolicyType.ANYONE, - }; - } - - switch (followModule.__typename) { - case 'FeeFollowModuleSettings': - return { - type: FollowPolicyType.CHARGE, - amount: erc20Amount({ from: followModule.amount }), - recipient: followModule.recipient, - contractAddress: followModule.contractAddress, - }; - case 'ProfileFollowModuleSettings': - return { - type: FollowPolicyType.ONLY_PROFILE_OWNERS, - contractAddress: followModule.contractAddress, - }; - case 'RevertFollowModuleSettings': - return { - type: FollowPolicyType.NO_ONE, - contractAddress: followModule.contractAddress, - }; - case 'UnknownFollowModuleSettings': - return { - type: FollowPolicyType.UNKNOWN, - contractAddress: followModule.contractAddress, - }; - } -} - -export function createProfileTypePolicy(): StrictTypedTypePolicies['Profile'] { - return { - fields: { - isFollowing: { - keyArgs: false, - }, - - isFollowedByMe: { - keyArgs: false, - - merge(_, incoming: boolean) { - return incoming; - }, - }, - - followStatus: { - read(_, { readField }) { - const session = getSession(); - - if (!session || session.isNotAuthenticated()) { - return null; - } - - const profileId = (readField('id') as ProfileId) ?? never('Cannot read profile id'); - const isFollowedByMe = - (readField('isFollowedByMe') as boolean) ?? never('Cannot read profile isFollowedByMe'); - - const isFollowTransactionForThisProfile = isFollowTransactionFor({ - profileId, - followerAddress: session.wallet.address, - }); - const isUnfollowTransactionForThisProfile = isUnfollowTransactionFor({ - profileId, - }); - - return getAllPendingTransactions().reduce( - (status, transaction) => { - if (isFollowTransactionForThisProfile(transaction)) { - return { - isFollowedByMe: true, - canFollow: false, - canUnfollow: false, - }; - } - - if (isUnfollowTransactionForThisProfile(transaction)) { - return { - isFollowedByMe: false, - canFollow: false, - canUnfollow: false, - }; - } - - return status; - }, - { - isFollowedByMe, - canFollow: !isFollowedByMe, - canUnfollow: isFollowedByMe, - } as FollowStatus, - ); - }, - }, - - followPolicy(existing: FollowPolicy | undefined, { readField }: FieldFunctionOptions) { - if (existing) return existing; - - return resolveFollowPolicy({ - followModule: readField('followModule') as FollowModule, - }); - }, - - picture: { - merge(_, incoming: ProfilePictureSet) { - return incoming; - }, - }, - - coverPicture: { - merge(_, incoming: ProfileCoverSet) { - return incoming; - }, - }, - - attributes: { - merge(_, incoming: Attribute) { - return incoming; - }, - }, - - attributesMap(_, { readField }) { - const attributes = readField('attributes') as Attribute[]; - - return (attributes ?? []).reduce((acc, attribute) => { - acc[attribute.key] = new ProfileAttributeReader(attribute); - return acc; - }, {} as ProfileAttributes); - }, - - ownedByMe(_: boolean | undefined, { readField }) { - const session = getSession(); - - if (!session || session.isNotAuthenticated()) { - return false; - } - - return readField('ownedBy') === session.wallet.address; - }, - - observedBy, - }, - }; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createProfilesFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createProfilesFieldPolicy.ts deleted file mode 100644 index 9551206bab..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createProfilesFieldPolicy.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createProfilesFieldPolicy() { - return cursorBasedPagination([ - ['request', ['ownedBy', 'handles', 'profileIds', 'whoMirroredPublicationId']], - '$observerId', - '$sources', - ]); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createPublicationsFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createPublicationsFieldPolicy.ts deleted file mode 100644 index 216bd3a4f0..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createPublicationsFieldPolicy.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createPublicationsFieldPolicy() { - return cursorBasedPagination([ - [ - 'request', - [ - 'profileId', - 'profileIds', - 'collectedBy', - 'publicationTypes', - 'commentsOf', - 'commentsOfOrdering', - 'commentsRankingFilter', - 'sources', - 'metadata', - 'publicationIds', - ], - ], - '$observerId', - ]); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createPublicationsProfileBookmarks.ts b/packages/api-bindings-v1/src/apollo/cache/createPublicationsProfileBookmarks.ts deleted file mode 100644 index f64608265f..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createPublicationsProfileBookmarks.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createPublicationsProfileBookmarks() { - return cursorBasedPagination([['request', ['profileId', 'metadata', 'sources']], '$observerId']); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createRevenueAggregateTypePolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createRevenueAggregateTypePolicy.ts deleted file mode 100644 index 11cb3d1d47..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createRevenueAggregateTypePolicy.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { never } from '@lens-protocol/shared-kernel'; - -import { erc20Amount, Erc20AmountFields, StrictTypedTypePolicies } from '../../lens'; - -export function createRevenueAggregateTypePolicy(): StrictTypedTypePolicies['RevenueAggregate'] { - return { - fields: { - totalAmount(_, { readField }) { - const total = - (readField('total') as Erc20AmountFields) ?? never('RevenueAggregate total is null'); - return erc20Amount({ from: total }); - }, - }, - }; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createSearchFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createSearchFieldPolicy.ts deleted file mode 100644 index b13a562264..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createSearchFieldPolicy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createSearchFieldPolicy() { - return cursorBasedPagination([['request', ['query', 'type', 'sources']], '$observerId']); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createSnapshotCache.ts b/packages/api-bindings-v1/src/apollo/cache/createSnapshotCache.ts deleted file mode 100644 index 5edcd51d07..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createSnapshotCache.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ApolloCache, InMemoryCache, NormalizedCacheObject } from '@apollo/client'; - -export function createSnapshotCache(): ApolloCache { - return new InMemoryCache(); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/createWhoReactedPublicationFieldPolicy.ts b/packages/api-bindings-v1/src/apollo/cache/createWhoReactedPublicationFieldPolicy.ts deleted file mode 100644 index 2ad376d0ce..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/createWhoReactedPublicationFieldPolicy.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { cursorBasedPagination } from './utils/cursorBasedPagination'; - -export function createWhoReactedPublicationFieldPolicy() { - return cursorBasedPagination([['request', ['publicationId']], '$observerId', '$sources']); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/decryptionCriteria.ts b/packages/api-bindings-v1/src/apollo/cache/decryptionCriteria.ts deleted file mode 100644 index 8b1e5d3ee7..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/decryptionCriteria.ts +++ /dev/null @@ -1,259 +0,0 @@ -import { FieldReadFunction } from '@apollo/client'; -import { - AddressOwnershipCriterion, - AndCriterion, - AnyCriterion, - CollectPublicationCriterion, - CollectThisPublicationCriterion, - DecryptionCriteriaType, - Erc20ComparisonOperator, - Erc20OwnershipCriterion, - FollowProfileCriterion, - NftContractType, - NftOwnershipCriterion, - OrCriterion, - ProfileId, - ProfileOwnershipCriterion, - SimpleCriterion, -} from '@lens-protocol/domain/entities'; -import { - Amount, - assertJustOne, - ChainType, - erc20, - hasAtLeastOne, - hasJustOne, - hasTwoOrMore, - invariant, - isNonNullable, - never, - TwoAtLeastArray, - assertNever, -} from '@lens-protocol/shared-kernel'; - -import { - AndConditionOutput, - CollectConditionOutput, - ContractType, - EoaOwnershipOutput, - Erc20OwnershipOutput, - FollowConditionOutput, - Maybe, - NftOwnershipOutput, - OrConditionOutput, - ProfileOwnershipOutput, - AnyConditionOutput, - ScalarOperator, - LeafConditionOutput, - Profile, - MetadataOutput, -} from '../../lens'; - -function allButPublicationAuthor(authorId: ProfileId) { - return (criterion: AnyConditionOutput): boolean => { - return criterion.profile?.profileId !== authorId; - }; -} - -function toNftContractType(contractType: ContractType): NftContractType | null { - switch (contractType) { - case ContractType.Erc721: - return NftContractType.Erc721; - case ContractType.Erc1155: - return NftContractType.Erc1155; - } - return null; -} - -function nftOwnershipCriterion({ - chainID, - contractAddress, - contractType, - tokenIds, -}: NftOwnershipOutput): NftOwnershipCriterion | null { - const supportedNftContractType = toNftContractType(contractType); - - if (!supportedNftContractType) { - return null; - } - - switch (supportedNftContractType) { - case NftContractType.Erc721: - return { - type: DecryptionCriteriaType.NFT_OWNERSHIP, - chainId: chainID, - contractAddress: contractAddress, - contractType: supportedNftContractType, - tokenIds: tokenIds ?? undefined, - }; - case NftContractType.Erc1155: - if (tokenIds && hasAtLeastOne(tokenIds)) { - return { - type: DecryptionCriteriaType.NFT_OWNERSHIP, - chainId: chainID, - contractAddress: contractAddress, - contractType: supportedNftContractType, - tokenIds: tokenIds, - }; - } - - return null; - default: - assertNever(supportedNftContractType, 'NFT contract type is not supported'); - } -} - -export function erc20Amount({ from }: { from: Erc20OwnershipOutput }) { - const asset = erc20({ - chainType: ChainType.POLYGON, // temporary while BE works on returning an Erc20Amount node - address: from.contractAddress, - decimals: from.decimals, - name: from.name, - symbol: from.symbol, - }); - return Amount.erc20(asset, from.amount); -} - -function toErc20Comp(operator: ScalarOperator): Erc20ComparisonOperator { - return operator as string as Erc20ComparisonOperator; -} - -function erc20OwnershipCriterion(condition: Erc20OwnershipOutput): Erc20OwnershipCriterion { - return { - type: DecryptionCriteriaType.ERC20_OWNERSHIP, - amount: erc20Amount({ from: condition }), - condition: toErc20Comp(condition.condition), - }; -} - -function addressOwnershipCriterion(condition: EoaOwnershipOutput): AddressOwnershipCriterion { - return { - type: DecryptionCriteriaType.ADDRESS_OWNERSHIP, - address: condition.address, - }; -} - -function profileOwnershipCriterion(condition: ProfileOwnershipOutput): ProfileOwnershipCriterion { - return { - type: DecryptionCriteriaType.PROFILE_OWNERSHIP, - profileId: condition.profileId, - }; -} - -function followProfile(condition: FollowConditionOutput): FollowProfileCriterion { - return { - type: DecryptionCriteriaType.FOLLOW_PROFILE, - profileId: condition.profileId, - }; -} - -function collectPublication( - condition: CollectConditionOutput, -): CollectPublicationCriterion | CollectThisPublicationCriterion { - if (condition.thisPublication) { - return { - type: DecryptionCriteriaType.COLLECT_THIS_PUBLICATION, - }; - } - return { - type: DecryptionCriteriaType.COLLECT_PUBLICATION, - publicationId: condition.publicationId ?? never('Expected publicationId to be defined'), - }; -} - -function sanitize({ __typename, ...accessCondition }: Partial) { - const conditions = Object.values(accessCondition).filter(isNonNullable); - assertJustOne(conditions); - return conditions[0]; -} - -function resolveSimpleCriterion(accessCondition: LeafConditionOutput): SimpleCriterion | null { - const condition = sanitize(accessCondition); - - switch (condition.__typename) { - case 'EoaOwnershipOutput': - return addressOwnershipCriterion(condition); - case 'Erc20OwnershipOutput': - return erc20OwnershipCriterion(condition); - case 'NftOwnershipOutput': - return nftOwnershipCriterion(condition); - case 'ProfileOwnershipOutput': - return profileOwnershipCriterion(condition); - case 'FollowConditionOutput': - return followProfile(condition); - case 'CollectConditionOutput': - return collectPublication(condition); - } - return null; -} - -function andCondition({ - criteria, -}: AndConditionOutput): AndCriterion> | null { - const conditions = criteria - .map((condition) => resolveSimpleCriterion(condition)) - .filter(isNonNullable); - - if (!hasTwoOrMore(conditions)) return null; - - return { - type: DecryptionCriteriaType.AND, - and: conditions, - }; -} - -function orCondition({ - criteria, -}: OrConditionOutput): OrCriterion> | null { - const conditions = criteria - .map((condition) => resolveSimpleCriterion(condition)) - .filter(isNonNullable); - - if (!hasTwoOrMore(conditions)) return null; - - return { - type: DecryptionCriteriaType.OR, - or: conditions, - }; -} - -function resolveRootCriterion(accessCondition: AnyConditionOutput): Maybe { - const condition = sanitize(accessCondition); - - switch (condition.__typename) { - case 'AndConditionOutput': - return andCondition(condition); - case 'OrConditionOutput': - return orCondition(condition); - } - - return resolveSimpleCriterion(accessCondition); -} - -export const decryptionCriteria: FieldReadFunction = (_, { canRead, readField }) => { - const isGated = readField('isGated') ?? never(); - - if (!isGated) return null; - - // we MUST be careful with these assertions as they rely on intrinsic knowledge of the schema - const author = (readField('profile') as Profile) ?? never(); - const metadata = (readField('metadata') as MetadataOutput) ?? never(); - - if (!metadata.encryptionParams || !metadata.encryptionParams.accessCondition.or) { - return null; - } - - invariant(canRead(author), 'Expected to be able to read publication author'); - - const authorId = readField('id', author) as ProfileId; - - const criteria = metadata.encryptionParams.accessCondition.or.criteria.filter( - allButPublicationAuthor(authorId), - ); - - if (hasJustOne(criteria)) { - return resolveRootCriterion(criteria[0]); - } - - return null; -}; diff --git a/packages/api-bindings-v1/src/apollo/cache/index.ts b/packages/api-bindings-v1/src/apollo/cache/index.ts deleted file mode 100644 index 10146c5cac..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './createLensCache'; -export * from './createSnapshotCache'; diff --git a/packages/api-bindings-v1/src/apollo/cache/publication.ts b/packages/api-bindings-v1/src/apollo/cache/publication.ts deleted file mode 100644 index ad78afee31..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/publication.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { - FieldFunctionOptions, - FieldPolicy, - FieldReadFunction, - Reference, - StoreObject, -} from '@apollo/client'; -import { PublicationId } from '@lens-protocol/domain/entities'; -import { ReferencePolicyType } from '@lens-protocol/domain/use-cases/publications'; -import { EthereumAddress } from '@lens-protocol/shared-kernel'; - -import { - AnyPublication, - CollectModule, - CollectPolicy, - ContentInsight, - ContentInsightType, - MetadataOutput, - PublicationQueryRequest, - PublicationStats, - ReferenceModule, - ReferencePolicy, - resolveCollectPolicy, - Wallet, -} from '../../lens'; -import { decryptionCriteria } from './decryptionCriteria'; -import { SessionType, getSession } from './session'; -import { - getAllPendingTransactions, - isCollectTransactionFor, - isMirrorTransactionFor, -} from './transactions'; -import { ContentInsightMatcher } from './utils/ContentInsight'; -import { extractUrls } from './utils/extractUrls'; -import { firstMatch } from './utils/firstMatch'; -import { noCachedField } from './utils/noCachedField'; -import { observedBy } from './utils/observedBy'; - -function resolveReferencePolicy(module: ReferenceModule | null): ReferencePolicy { - if (module === null) { - return { - type: ReferencePolicyType.ANYONE, - }; - } - - switch (module.__typename) { - case 'DegreesOfSeparationReferenceModuleSettings': - return { - type: ReferencePolicyType.DEGREES_OF_SEPARATION, - degreesOfSeparation: module.degreesOfSeparation, - }; - case 'FollowOnlyReferenceModuleSettings': - return { - type: ReferencePolicyType.FOLLOWERS_ONLY, - }; - case 'UnknownReferenceModuleSettings': - return { - type: ReferencePolicyType.UNKNOWN, - contractAddress: module.contractAddress, - data: module.referenceModuleReturnData, - }; - } -} - -const referencePolicy: FieldReadFunction = (existing, { readField }) => { - if (existing) return existing; - - const module = readField('referenceModule') as ReferenceModule; - - return resolveReferencePolicy(module ?? null); -}; - -const collectedBy: FieldPolicy = { - merge: (existing, incoming) => { - // workaround: try to retain the information even if the publication is updated in - // cache as part of another query that does not have the collectedBy field - return existing ?? incoming; - }, -}; - -const collectPolicy = ( - existing: CollectPolicy | undefined, - { readField }: FieldFunctionOptions, -): CollectPolicy => { - if (existing) return existing; - - const profile = readField('profile') as Reference; - const collectModule = readField('collectModule') as CollectModule; - const isAuthorFollowedByMe = readField('isFollowedByMe', profile) as boolean; - const publicationStats = readField('stats') as PublicationStats; - const collectNftAddress = (readField('collectNftAddress') as EthereumAddress) || null; - - return resolveCollectPolicy({ - collectModule, - isAuthorFollowedByMe, - publicationStats, - collectNftAddress, - }); -}; - -const hasCollectedByMe = (existing: boolean, { readField }: FieldFunctionOptions): boolean => { - // if collected already then just return, it can't be undone - if (existing === true) return existing; - - const session = getSession(); - - if (!session || session.type !== SessionType.WithProfile) return false; - - const publicationId = readField('id') as PublicationId; - - const isCollectTransactionForThisPublication = isCollectTransactionFor({ - publicationId, - profileId: session.profile.id, - }); - - const collectPendingTx = getAllPendingTransactions().find((transaction) => { - return isCollectTransactionForThisPublication(transaction); - }); - - return collectPendingTx !== undefined; -}; - -// TODO: Make sure the typing is correct and force to return the correct type without shallowing the `undefined` which means that the field is missing and breaks the cache -const isMirroredByMe = ( - existing: boolean | undefined, - { readField }: FieldFunctionOptions, -): boolean => { - if (existing === true) return existing; - - const session = getSession(); - - const publicationId = readField('id') as PublicationId; - const mirrors = readField('mirrors') as PublicationId[]; - - if (!session || session.type !== SessionType.WithProfile) return false; - - if (mirrors.length > 0) return true; - - const isMirrorTransactionForThisPublication = isMirrorTransactionFor({ - publicationId, - profileId: session.profile.id, - }); - - const mirrorPendingTxs = getAllPendingTransactions().filter((transaction) => { - return isMirrorTransactionForThisPublication(transaction); - }); - - return mirrorPendingTxs.length > 0; -}; - -/** - * @deprecated use `hasCollectedByMe` instead - */ -const hasOptimisticCollectedByMe: FieldReadFunction = (existing) => { - return existing ?? false; -}; - -/** - * @deprecated use `isMirroredByMe` instead - */ -const isOptimisticMirroredByMe: FieldReadFunction = (existing) => { - return existing ?? false; -}; - -export type ContentPublicationTypePolicyConfig = { - /** - * A list of ContentInsightMatcher used to extract insights from publication metadata content - */ - contentMatchers: ContentInsightMatcher[]; -}; - -const createContentInsightFieldPolicy: ( - arg: ContentPublicationTypePolicyConfig, -) => FieldReadFunction = - ({ contentMatchers }) => - (_, { readField }) => { - const metadata = readField('metadata') as MetadataOutput; - - if (metadata.content) { - const urls = extractUrls(metadata.content); - - const match = firstMatch(urls, contentMatchers); - - if (match) { - return match; - } - } - - return { - type: ContentInsightType.UNDETERMINED, - }; - }; - -const publicationTypename = 'Publication'; - -export function createPublicationTypePolicy() { - return { - keyFields: ({ id }: Readonly) => `${publicationTypename}:${String(id)}`, - } as const; -} - -function createContentPublicationTypePolicy(config: ContentPublicationTypePolicyConfig) { - return { - fields: { - canComment: noCachedField(), - canDecrypt: noCachedField(), - canMirror: noCachedField(), - collectedBy, - collectPolicy, - contentInsight: createContentInsightFieldPolicy(config), - decryptionCriteria, - hasCollectedByMe, - hasOptimisticCollectedByMe, - isMirroredByMe, - isOptimisticMirroredByMe, - mirrors: noCachedField(), - notInterested: noCachedField(), - bookmarked: noCachedField(), - reaction: noCachedField(), - referencePolicy, - stats: noCachedField(), - observedBy, - }, - }; -} - -export const createCommentTypePolicy = createContentPublicationTypePolicy; - -export const createPostTypePolicy = createContentPublicationTypePolicy; - -export function createPublicationFieldPolicy(): FieldPolicy< - AnyPublication, - AnyPublication, - Reference, - FieldFunctionOptions<{ request: PublicationQueryRequest }> -> { - return { - read(_, { args, toReference }) { - return toReference({ - __typename: publicationTypename, - id: args?.request.publicationId, - }); - }, - }; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/session.ts b/packages/api-bindings-v1/src/apollo/cache/session.ts deleted file mode 100644 index a814bd5019..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/session.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { makeVar, useReactiveVar } from '@apollo/client'; -import { ProfileIdentifier, WalletData } from '@lens-protocol/domain/use-cases/lifecycle'; - -export enum SessionType { - Anonymous = 'ANONYMOUS', - JustWallet = 'JUST_WALLET', - WithProfile = 'WITH_PROFILE', -} - -/** - * @experimental - */ -class NotAuthenticatedSession { - readonly type = SessionType.Anonymous; - - isAuthenticated(): this is - | AuthenticatedWalletSession - | AuthenticatedProfileSession { - return false; - } - - isNotAuthenticated(): this is NotAuthenticatedSession { - return true; - } -} - -/** - * @experimental - */ -class AuthenticatedWalletSession { - readonly type = SessionType.JustWallet; - - constructor(readonly wallet: TWallet) {} - - isAuthenticated(): this is - | AuthenticatedWalletSession - | AuthenticatedProfileSession { - return true; - } - - isNotAuthenticated(): this is NotAuthenticatedSession { - return false; - } -} - -/** - * @experimental - */ -class AuthenticatedProfileSession { - readonly type = SessionType.WithProfile; - - constructor(readonly wallet: TWallet, readonly profile: TProfile) {} - - isAuthenticated(): this is - | AuthenticatedWalletSession - | AuthenticatedProfileSession { - return true; - } - - isNotAuthenticated(): this is NotAuthenticatedSession { - return false; - } -} - -export type { NotAuthenticatedSession, AuthenticatedWalletSession, AuthenticatedProfileSession }; - -export function notAuthenticated() { - return new NotAuthenticatedSession(); -} - -export function authenticatedWallet(wallet: T) { - return new AuthenticatedWalletSession(wallet); -} - -export function authenticatedProfile< - TWallet extends WalletData, - TProfile extends ProfileIdentifier, ->(wallet: TWallet, profile: TProfile) { - return new AuthenticatedProfileSession(wallet, profile); -} - -export function authenticatedWith( - wallet: TWallet, - profile: TProfile | null, -) { - if (profile === null) { - return authenticatedWallet(wallet); - } - return authenticatedProfile(wallet, profile); -} - -/** - * @experimental - */ -export type Session = - | NotAuthenticatedSession - | AuthenticatedWalletSession - | AuthenticatedProfileSession; - -const sessionVar = makeVar | null>(null); - -export function getSession() { - return sessionVar(); -} - -export function useSessionVar() { - return useReactiveVar(sessionVar); -} - -export function resetSession() { - sessionVar(null); -} - -export function updateSession(session: Session) { - sessionVar(session); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/transactions.ts b/packages/api-bindings-v1/src/apollo/cache/transactions.ts deleted file mode 100644 index f864b846f5..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/transactions.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { makeVar, useReactiveVar } from '@apollo/client'; -import { - ProfileId, - PublicationId, - TransactionError, - TransactionErrorReason, - TransactionKind, -} from '@lens-protocol/domain/entities'; -import { FollowRequest, UnfollowRequest } from '@lens-protocol/domain/use-cases/profile'; -import { CollectRequest, CreateMirrorRequest } from '@lens-protocol/domain/use-cases/publications'; -import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; -import { DateUtils, EthereumAddress } from '@lens-protocol/shared-kernel'; - -export enum TxStatus { - /** - * @deprecated Use {@link TxStatus.PENDING} instead. It will be removed in the next major version. - */ - BROADCASTING = 'pending', - - /** - * @deprecated Use {@link TxStatus.PENDING} instead. It will be removed in the next major version. - */ - MINING = 'pending', - - /** - * A pending transaction is a transaction that is either mining or it's mined but not indexed yet. - */ - PENDING = 'pending', - - /** - * A settled transaction is a transaction that is mined and indexed. - */ - SETTLED = 'settled', - - /** - * A failed transaction is a transaction that failed to be broadcasted or it failed to be mined. - */ - FAILED = 'failed', -} - -const PENDING_STATUSES = [TxStatus.BROADCASTING, TxStatus.MINING]; - -/** - * @deprecated Use {@link TransactionState} instead. It will be removed in the next major version. - */ -export type PendingTransactionState = { - status: TxStatus.BROADCASTING | TxStatus.FAILED; - id: string; - request: T; -}; - -/** - * @deprecated Use {@link TransactionState} instead. It will be removed in the next major version. - */ -export type BroadcastedTransactionState = { - status: TxStatus.MINING | TxStatus.SETTLED | TxStatus.FAILED; - id: string; - request: T; - txHash: string; -}; - -/** - * Describe the state of a transaction and the originating request. - */ -export type TransactionState = { - status: TxStatus; - id: string; - request: T; - txHash?: string; -}; - -export const recentTransactionsVar = makeVar[]>([]); - -type TransactionStatusPredicate = ( - txState: TransactionState, -) => txState is TransactionState; - -function hasTransactionWith( - transactions: TransactionState[], - statuses: ReadonlyArray, - predicate: TransactionStatusPredicate, -) { - return transactions.some((txState) => statuses.includes(txState.status) && predicate(txState)); -} - -export function hasPendingTransactionWith( - predicate: TransactionStatusPredicate, -) { - return hasTransactionWith(recentTransactionsVar(), PENDING_STATUSES, predicate); -} - -export function hasSettledTransactionWith( - predicate: TransactionStatusPredicate, -) { - return hasTransactionWith(recentTransactionsVar(), [TxStatus.SETTLED], predicate); -} - -export function getAllPendingTransactions() { - return recentTransactionsVar().filter((txState) => PENDING_STATUSES.includes(txState.status)); -} - -function delay(waitInMs: number) { - return new Promise((resolve) => setTimeout(resolve, waitInMs)); -} - -export function useRecentTransactionsVar() { - return useReactiveVar(recentTransactionsVar); -} - -export function useHasPendingTransaction( - predicate: TransactionStatusPredicate, -) { - const transactions = useRecentTransactionsVar(); - - return hasTransactionWith(transactions, PENDING_STATUSES, predicate); -} - -const FIFTEEN_SECONDS = DateUtils.secondsToMs(30); - -export function useWaitUntilTransactionSettled(waitTimeInMs: number = FIFTEEN_SECONDS) { - return async (predicate: TransactionStatusPredicate) => { - const resolveWhenNoPendingTransactions = new Promise((resolve) => { - const resolver = (value: TransactionState[]) => { - if (hasTransactionWith(value, [TxStatus.SETTLED], predicate)) { - return resolve(); - } - return recentTransactionsVar.onNextChange(resolver); - }; - recentTransactionsVar.onNextChange(resolver); - }); - const waitForSpecifiedTime = delay(waitTimeInMs).then(() => { - throw new TransactionError(TransactionErrorReason.INDEXING_TIMEOUT); - }); - await Promise.race([resolveWhenNoPendingTransactions, waitForSpecifiedTime]); - }; -} - -export function isFollowTransactionFor({ - profileId, - followerAddress, -}: { - profileId: ProfileId; - followerAddress: EthereumAddress; -}): TransactionStatusPredicate { - return (transaction): transaction is TransactionState => - transaction.request.kind === TransactionKind.FOLLOW_PROFILES && - transaction.request.profileId === profileId && - transaction.request.followerAddress === followerAddress; -} - -export function isUnfollowTransactionFor({ - profileId, -}: { - profileId: ProfileId; -}): TransactionStatusPredicate { - return (transaction): transaction is TransactionState => - transaction.request.kind === TransactionKind.UNFOLLOW_PROFILE && - transaction.request.profileId === profileId; -} - -export function isCollectTransactionFor({ - publicationId, - profileId, -}: { - publicationId: PublicationId; - profileId: ProfileId; -}): TransactionStatusPredicate { - return (transaction): transaction is TransactionState => - transaction.request.kind === TransactionKind.COLLECT_PUBLICATION && - transaction.request.profileId === profileId && - transaction.request.publicationId === publicationId; -} - -export function isMirrorTransactionFor({ - publicationId, - profileId, -}: { - publicationId: PublicationId; - profileId: ProfileId; -}): TransactionStatusPredicate { - return (transaction): transaction is TransactionState => - transaction.request.kind === TransactionKind.MIRROR_PUBLICATION && - transaction.request.profileId === profileId && - transaction.request.publicationId === publicationId; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/__tests__/matchers.spec.ts b/packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/__tests__/matchers.spec.ts deleted file mode 100644 index 77539c6670..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/__tests__/matchers.spec.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { ContentInsightType } from '../../../../../lens'; -import { - mockSnapshotPollUrl, - mockSnapshotProposalId, - mockSnapshotSpaceId, -} from '../../../../../mocks'; -import { snapshotPoll, demoSnapshotPoll } from '../matchers'; - -const spaceId = mockSnapshotSpaceId(); -const proposalId = mockSnapshotProposalId(); - -describe(`Given the content insights matchers`, () => { - describe.each([ - { - matcher: snapshotPoll, - snapshotUrl: 'https://snapshot.org', - }, - { - matcher: demoSnapshotPoll, - snapshotUrl: 'https://demo.snapshot.org', - }, - ])(`when testing the "$matcher.name" matcher`, ({ matcher, snapshotUrl }) => { - const url = mockSnapshotPollUrl({ - baseUrl: snapshotUrl, - spaceId, - proposalId, - }); - - it('should recognize compatible snapshot URLs and return the extracted content insights', () => { - const result = matcher(url); - - expect(result).toEqual({ - type: ContentInsightType.SNAPSHOT_POLL, - spaceId, - proposalId, - url, - }); - }); - - it('should return null in case of unmatched URLs', () => { - const url = 'https://www.example.com'; - - const result = matcher(url); - - expect(result).toBe(null); - }); - }); -}); diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/index.ts b/packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/index.ts deleted file mode 100644 index 9f0cee05fa..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './matchers'; diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/matchers.ts b/packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/matchers.ts deleted file mode 100644 index 9edde87c5a..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/ContentInsight/matchers.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Url } from '@lens-protocol/shared-kernel'; - -import { - ContentInsight, - ContentInsightType, - SnapshotProposalId, - SnapshotSpaceId, -} from '../../../../lens'; -import { Matcher } from '../firstMatch'; - -export type ContentInsightMatcher = Matcher; - -const snapshotRegExp = /https:\/\/snapshot\.org\/#\/([^/]+)\/proposal\/(0x[a-fA-F0-9]+)/; - -const snapshotDemoRegExp = /https:\/\/demo\.snapshot\.org\/#\/([^/]+)\/proposal\/(0x[a-fA-F0-9]+)/; - -function snapshotUrlMatcher(pattern: RegExp, url: Url) { - const [, spaceId, proposalId] = pattern.exec(url) ?? []; - - if (spaceId && proposalId) { - return { - type: ContentInsightType.SNAPSHOT_POLL, - spaceId: spaceId as SnapshotSpaceId, - proposalId: proposalId as SnapshotProposalId, - url, - }; - } - return null; -} - -export function snapshotPoll(url: Url) { - return snapshotUrlMatcher(snapshotRegExp, url); -} - -export function demoSnapshotPoll(url: Url) { - return snapshotUrlMatcher(snapshotDemoRegExp, url); -} diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/__helpers__/mocks.ts b/packages/api-bindings-v1/src/apollo/cache/utils/__helpers__/mocks.ts deleted file mode 100644 index a73b03bb57..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/__helpers__/mocks.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { gql } from '@apollo/client'; -import { MockedResponse } from '@apollo/client/testing'; -import { faker } from '@faker-js/faker'; - -import { Cursor, CursorBasedPaginatedResult, FragmentPaginatedResultInfo } from '../../../../lens'; -import { mockPaginatedResultInfo } from '../../../../lens/__helpers__/fragments'; - -export const AnyPaginatedQueryDocument = gql` - query GetHero($cursor: String!) { - result: hero(cursor: $cursor) { - items { - name - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentPaginatedResultInfo} -`; - -type AnyPaginatedItem = { - name: string; -}; - -export type AnyPaginatedQueryVariables = { - cursor?: string; -}; - -type AnyPaginatedQueryResult = CursorBasedPaginatedResult; - -export type AnyPaginatedQueryData = { - result: AnyPaginatedQueryResult; -}; - -function mockAnyPaginatedItem(): AnyPaginatedItem { - return { - name: faker.helpers.arrayElement(['Luke Skywalker', 'Darth Vader', 'Han Solo']), - }; -} - -export function mockAnyPaginatedQueryResult({ - items = [mockAnyPaginatedItem() as T], - next = null, - prev = null, -}: - | { - items?: T[]; - next?: null; - prev?: null; - } - | { - items?: [T]; - next?: Cursor | null; - prev?: Cursor | null; - } = {}): CursorBasedPaginatedResult { - return { - items, - pageInfo: mockPaginatedResultInfo({ - next, - prev, - }), - }; -} - -export function mockAnyPaginatedQueryResponse({ - variables = {}, - result, -}: { - variables?: AnyPaginatedQueryVariables; - result: AnyPaginatedQueryResult; -}): MockedResponse { - return { - request: { - query: AnyPaginatedQueryDocument, - variables, - }, - result: { - data: { result }, - }, - }; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/__tests__/cursorBasedPagination.spec.ts b/packages/api-bindings-v1/src/apollo/cache/utils/__tests__/cursorBasedPagination.spec.ts deleted file mode 100644 index 6feefba895..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/__tests__/cursorBasedPagination.spec.ts +++ /dev/null @@ -1,274 +0,0 @@ -import { ApolloClient, InMemoryCache } from '@apollo/client'; -import { MockedResponse, mockSingleLink } from '@apollo/client/testing'; -import { InvariantError } from '@lens-protocol/shared-kernel'; - -import { mockCursor } from '../../../../mocks'; -import { - AnyPaginatedQueryData, - AnyPaginatedQueryDocument, - AnyPaginatedQueryVariables, - mockAnyPaginatedQueryResponse, - mockAnyPaginatedQueryResult, -} from '../__helpers__/mocks'; -import { cursorBasedPagination } from '../cursorBasedPagination'; - -const initialCursor = mockCursor(); -const nextCursor = mockCursor(); -const prevCursor = mockCursor(); - -function setupObservable(mocks: ReadonlyArray>) { - const cache = new InMemoryCache({ - typePolicies: { - Query: { - fields: { - hero: cursorBasedPagination([]), - }, - }, - }, - }); - - const apollo = new ApolloClient({ - cache, - link: mockSingleLink(...mocks).setOnError((error) => { - throw error; - }), - }); - - return apollo.watchQuery({ - query: AnyPaginatedQueryDocument, - }); -} - -describe(`Given a cursor-based paginated query field`, () => { - describe('and an observable query watching it', () => { - describe('when fetching the next page', () => { - it(`should: - - append incoming items to the existing ones - - update "pageInfo.prev" to results prior the first page and "pageInfo.next" to results after the new last page - - update "pageInfo.moreAfter" accordingly`, async () => { - const initialResult = mockAnyPaginatedQueryResult({ - next: nextCursor, - prev: prevCursor, - }); - const nextResult = mockAnyPaginatedQueryResult({ - next: mockCursor(), - prev: initialCursor, - }); - const observable = setupObservable([ - mockAnyPaginatedQueryResponse({ - result: initialResult, - }), - mockAnyPaginatedQueryResponse({ - variables: { cursor: nextCursor }, - result: nextResult, - }), - ]); - - await observable.result(); - - await observable.fetchMore({ - variables: { - cursor: nextCursor, - }, - }); - const { data } = await observable.result(); - - expect(data.result).toMatchObject({ - items: [...initialResult.items, ...nextResult.items], - pageInfo: { - moreAfter: true, - next: nextResult.pageInfo.next, - prev: initialResult.pageInfo.prev, - }, - }); - }); - - describe('but the incoming result is empty', () => { - it(`should: - - NOT update the "pageInfo.next" cursor - - unset the "pageInfo.moreAfter" flag`, async () => { - const initialResult = mockAnyPaginatedQueryResult({ - next: nextCursor, - prev: prevCursor, - }); - const observable = setupObservable([ - mockAnyPaginatedQueryResponse({ - result: initialResult, - }), - mockAnyPaginatedQueryResponse({ - variables: { cursor: nextCursor }, - result: mockAnyPaginatedQueryResult({ - items: [], - prev: null, - next: null, - }), - }), - ]); - - await observable.result(); - - await observable.fetchMore({ - variables: { - cursor: nextCursor, - }, - }); - const { data } = await observable.result(); - - expect(data.result).toMatchObject({ - pageInfo: { - moreAfter: false, - next: initialResult.pageInfo.next, - prev: initialResult.pageInfo.prev, - }, - }); - }); - }); - }); - - describe('when fetching the previous page', () => { - it(`should: - - prepend incoming items to the existing ones - - update the "pageInfo.prev" to results prior the new first page and "pageInfo.next" to results after the last page - - update the "pageInfo.moreAfter" accordingly`, async () => { - const initialResult = mockAnyPaginatedQueryResult({ - prev: prevCursor, - next: null, - }); - const prevResult = mockAnyPaginatedQueryResult({ - next: initialCursor, - prev: mockCursor(), - }); - const observable = setupObservable([ - mockAnyPaginatedQueryResponse({ - result: initialResult, - }), - mockAnyPaginatedQueryResponse({ - variables: { cursor: prevCursor }, - result: prevResult, - }), - ]); - - await observable.result(); - - await observable.fetchMore({ - variables: { - cursor: prevCursor, - }, - }); - const { data } = await observable.result(); - - expect(data.result).toMatchObject({ - items: [...prevResult.items, ...initialResult.items], - pageInfo: { - moreAfter: false, - next: initialResult.pageInfo.next, - prev: prevResult.pageInfo.prev, - }, - }); - }); - - describe('but the incoming result is empty', () => { - it(`should NOT update the "pageInfo.prev" cursor`, async () => { - const initialResult = mockAnyPaginatedQueryResult({ - prev: prevCursor, - next: nextCursor, - }); - const observable = setupObservable([ - mockAnyPaginatedQueryResponse({ - result: initialResult, - }), - mockAnyPaginatedQueryResponse({ - variables: { cursor: prevCursor }, - result: mockAnyPaginatedQueryResult({ - items: [], - prev: null, - next: null, - }), - }), - ]); - - await observable.result(); - - await observable.fetchMore({ - variables: { - cursor: prevCursor, - }, - }); - const { data } = await observable.result(); - - expect(data.result).toMatchObject({ - pageInfo: { - moreAfter: true, - next: initialResult.pageInfo.next, - prev: initialResult.pageInfo.prev, - }, - }); - }); - }); - }); - - describe('when fetching the initial page again', () => { - it('should replace the existing items with the incoming ones', async () => { - const initialResult = mockAnyPaginatedQueryResult({ - next: nextCursor, - }); - const nextResult = mockAnyPaginatedQueryResult({ - next: mockCursor(), - prev: initialCursor, - }); - const observable = setupObservable([ - mockAnyPaginatedQueryResponse({ - result: initialResult, - }), - mockAnyPaginatedQueryResponse({ - variables: { cursor: nextCursor }, - result: nextResult, - }), - mockAnyPaginatedQueryResponse({ - result: initialResult, - }), - ]); - - await observable.result(); - - await observable.fetchMore({ - variables: { - cursor: nextCursor, - }, - }); - - // refetch initial page - const { data } = await observable.refetch(); - - expect(data.result).toMatchObject(initialResult); - }); - }); - - describe('when the incoming items cannot be prepended or appended to the existing items', () => { - const unknownCursor = mockCursor(); - const unknownPageResponse = mockAnyPaginatedQueryResponse({ - variables: { cursor: unknownCursor }, - result: mockAnyPaginatedQueryResult(), - }); - - it(`should throw an ${InvariantError.name}`, async () => { - const observable = setupObservable([ - mockAnyPaginatedQueryResponse({ - result: mockAnyPaginatedQueryResult(), - }), - unknownPageResponse, - ]); - - await observable.result(); - - await expect(() => - observable.fetchMore({ - variables: { - cursor: unknownCursor, - }, - }), - ).rejects.toThrow(InvariantError); - }); - }); - }); -}); diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/__tests__/extractUrls.spec.ts b/packages/api-bindings-v1/src/apollo/cache/utils/__tests__/extractUrls.spec.ts deleted file mode 100644 index 115a6a2481..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/__tests__/extractUrls.spec.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { extractUrls } from '../extractUrls'; - -describe(`Given the ${extractUrls.name} helper`, () => { - describe('when called with an empty string', () => { - it('should return an empty array', () => { - const inputString = ''; - const urls = extractUrls(inputString); - expect(urls).toEqual([]); - }); - }); - - describe('when called with a string containing a single URL', () => { - it('should extract the URL from the string', () => { - const inputString = 'Check out this website: https://example.com'; - const urls = extractUrls(inputString); - expect(urls).toEqual(['https://example.com']); - }); - }); - - describe('when called with a string containing multiple URLs', () => { - it('should extract all URLs from the string', () => { - const inputString = 'Visit these websites: https://example.com and https://www.openai.com'; - const urls = extractUrls(inputString); - expect(urls).toEqual(['https://example.com', 'https://www.openai.com']); - }); - }); - - describe('when called with a string containing a URL with query parameters and fragments', () => { - it('should extract the URL with query parameters and fragments', () => { - const inputString = 'Check out this URL: https://example.com/path?param=value#fragment'; - const urls = extractUrls(inputString); - expect(urls).toEqual(['https://example.com/path?param=value#fragment']); - }); - }); - - describe('when called with a string containing URLs with different protocols', () => { - it('should extract all URLs with different protocols', () => { - const inputString = 'Visit these websites: http://example.com and ftp://ftp.example.com'; - const urls = extractUrls(inputString); - expect(urls).toEqual(['http://example.com', 'ftp://ftp.example.com']); - }); - }); -}); diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/__tests__/firstMatch.spec.ts b/packages/api-bindings-v1/src/apollo/cache/utils/__tests__/firstMatch.spec.ts deleted file mode 100644 index e2aa9bdcf0..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/__tests__/firstMatch.spec.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { firstMatch, Matcher } from '../firstMatch'; - -describe(`Given the ${firstMatch.name} helper`, () => { - describe('when called with an empty array', () => { - it('should return null', () => { - const candidates: unknown[] = []; - const matchers: Matcher[] = [(_: unknown) => true]; - - const result = firstMatch(candidates, matchers); - - expect(result).toBeNull(); - }); - }); - - describe('when called with an array of candidates and matchers', () => { - it('should return the result of the first matching matcher', () => { - const candidates = [1, 2, 3]; - const matchers: Matcher[] = [ - (value) => (value === 2 ? 'two' : null), - (value) => (value === 3 ? 'three' : null), - (value) => (value === 4 ? 'four' : null), - ]; - - const result = firstMatch(candidates, matchers); - - expect(result).toEqual('two'); - }); - - it('should return null if no matcher matches any candidate', () => { - const candidates = [1, 2, 3]; - const matchers: Matcher[] = [ - (value) => (value === 4 ? 'four' : null), - (value) => (value === 5 ? 'five' : null), - ]; - - const result = firstMatch(candidates, matchers); - - expect(result).toBeNull(); - }); - - it('should return the result of the first matching matcher even if subsequent matchers match other candidates', () => { - const candidates = [1, 2, 3]; - const matchers: Matcher[] = [ - (value) => (value === 1 ? 'one' : null), - (value) => (value === 2 ? 'two' : null), - (value) => (value === 3 ? 'three' : null), - (value) => (value === 2 ? 'another two' : null), - ]; - - const result = firstMatch(candidates, matchers); - - expect(result).toEqual('one'); - }); - }); -}); diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/cursorBasedPagination.ts b/packages/api-bindings-v1/src/apollo/cache/utils/cursorBasedPagination.ts deleted file mode 100644 index fd8ed25246..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/cursorBasedPagination.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { FieldFunctionOptions, KeySpecifier } from '@apollo/client/cache/inmemory/policies'; -import { FieldPolicy } from '@apollo/client/core'; -import { never } from '@lens-protocol/shared-kernel'; - -import { CursorBasedPaginatedResult, isCursor } from '../../../lens'; - -// Note: Copied from apollo given it's not exposed publicly -// eslint-disable-next-line @typescript-eslint/ban-types -type SafeReadonly = T extends object ? Readonly : T; - -function isEndOfTheRoad(result: TResult) { - return ( - result.pageInfo.next === null && result.pageInfo.prev === null && result.items.length === 0 - ); -} -export function cursorBasedPagination( - keyArgs: KeySpecifier, -): FieldPolicy { - return { - keyArgs, - - read(existing: SafeReadonly | undefined, { canRead }) { - if (!existing) { - return existing; - } - - const { items, pageInfo } = existing; - - // items that are not in the cache anymore (for .e.g deleted publication) - const danglingItems = items.filter((item) => !canRead(item)); - const readRes: SafeReadonly = { - ...existing, - items, - pageInfo: { - ...pageInfo, - moreAfter: existing.pageInfo.moreAfter ?? existing.pageInfo.next !== null, - // reduce total count by excluding dangling items so it won't cause a new page query - // after item was removed from the cache (for .e.g deleted publication) - totalCount: - pageInfo.totalCount !== null ? pageInfo.totalCount - danglingItems.length : null, - }, - }; - - return readRes; - }, - - merge( - existing: SafeReadonly | undefined, - incoming: SafeReadonly, - { variables = {} }: FieldFunctionOptions, - ) { - if (!isCursor(variables.cursor) || !existing) { - return incoming; - } - - const existingItems = existing.items; - const incomingItems = incoming.items; - if (variables.cursor === existing.pageInfo.prev) { - if (isEndOfTheRoad(incoming)) { - return { - ...incoming, - items: existingItems, - pageInfo: { - ...incoming.pageInfo, // future-proofing in case we add more fields to pageInfo - moreAfter: existing.pageInfo.next !== null, - next: existing.pageInfo.next, - prev: existing.pageInfo.prev, - }, - }; - } - - return { - ...incoming, - items: incomingItems.concat(existingItems), - pageInfo: { - ...incoming.pageInfo, // future-proofing in case we add more fields to pageInfo - moreAfter: existing.pageInfo.moreAfter, - next: existing.pageInfo.next, - prev: incoming.pageInfo.prev ?? existing.pageInfo.prev, - }, - }; - } - - if (variables.cursor === existing.pageInfo.next) { - if (isEndOfTheRoad(incoming)) { - return { - ...incoming, - items: existingItems, - pageInfo: { - ...incoming.pageInfo, // future-proofing in case we add more fields to pageInfo - moreAfter: false, - next: existing.pageInfo.next, - prev: existing.pageInfo.prev, - }, - }; - } - - return { - ...incoming, - items: existingItems.concat(incomingItems), - pageInfo: { - ...incoming.pageInfo, // future-proofing in case we add more fields to pageInfo - moreAfter: incoming.pageInfo.next !== null, - next: incoming.pageInfo.next, - prev: existing.pageInfo.prev, - }, - }; - } - - never('Unable to merge incoming cursor-based pagination result'); - }, - }; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/extractUrls.ts b/packages/api-bindings-v1/src/apollo/cache/utils/extractUrls.ts deleted file mode 100644 index e3f872cdcd..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/extractUrls.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Url } from '@lens-protocol/shared-kernel'; - -export function extractUrls(input: string): Url[] { - const urlRegex = /(\w+:\/\/[^\s]+)/gi; - const urls = input.match(urlRegex) || []; - return urls; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/firstMatch.ts b/packages/api-bindings-v1/src/apollo/cache/utils/firstMatch.ts deleted file mode 100644 index 778e3d34aa..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/firstMatch.ts +++ /dev/null @@ -1,18 +0,0 @@ -export type Matcher = (value: T) => R | null; - -export function firstMatch(candidates: T[], matchers: Matcher[]): R | null { - if (candidates.length === 0) { - return null; - } - - for (const candidate of candidates) { - for (const matcher of matchers) { - const result = matcher(candidate); - if (result !== null) { - return result; - } - } - } - - return null; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/noCachedField.ts b/packages/api-bindings-v1/src/apollo/cache/utils/noCachedField.ts deleted file mode 100644 index afca6a4b5a..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/noCachedField.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { FieldPolicy } from '@apollo/client'; - -export function noCachedField(): FieldPolicy { - return { - // no arguments involved in caching this edge - keyArgs: false, - }; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/notNormalizedType.ts b/packages/api-bindings-v1/src/apollo/cache/utils/notNormalizedType.ts deleted file mode 100644 index 6ea8d197e8..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/notNormalizedType.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TypePolicy } from '@apollo/client'; - -/** - * Use this to declare a type policy for an object that should not be normalized. - * Non-normalized objects are embedded within their parent object in the cache. - * - * See https://www.apollographql.com/docs/react/caching/cache-configuration/#disabling-normalization - * - * @returns a TypePolicy that does not cache the result of the field - */ -export function notNormalizedType(others?: Omit) { - return { - keyFields: false, - - ...others, - } as const; -} diff --git a/packages/api-bindings-v1/src/apollo/cache/utils/observedBy.ts b/packages/api-bindings-v1/src/apollo/cache/utils/observedBy.ts deleted file mode 100644 index d9249221a4..0000000000 --- a/packages/api-bindings-v1/src/apollo/cache/utils/observedBy.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { FieldReadFunction } from '@apollo/client'; -import { ProfileId } from '@lens-protocol/domain/entities'; - -export const observedBy: FieldReadFunction = (_, { variables }) => { - if (variables?.observerId) { - return variables.observerId as ProfileId; - } - return null; -}; diff --git a/packages/api-bindings-v1/src/apollo/errors.tsx b/packages/api-bindings-v1/src/apollo/errors.tsx deleted file mode 100644 index 842a073e80..0000000000 --- a/packages/api-bindings-v1/src/apollo/errors.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { CausedError } from '@lens-protocol/shared-kernel'; - -export class UnspecifiedError extends CausedError { - name = 'UnspecifiedError' as const; - - constructor(cause: Error) { - super(cause.message, { cause }); - } -} - -export class ValidationError extends CausedError { - name = 'ValidationError' as const; - - constructor(cause: Error) { - super('A validation error occurred', { cause }); - } -} diff --git a/packages/api-bindings-v1/src/apollo/index.ts b/packages/api-bindings-v1/src/apollo/index.ts deleted file mode 100644 index 3269f6eebe..0000000000 --- a/packages/api-bindings-v1/src/apollo/index.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { from } from '@apollo/client'; -import { ILogger } from '@lens-protocol/shared-kernel'; - -import { LENS_API_MINIMAL_SUPPORTED_VERSION } from '../constants'; -import type { IAccessTokenStorage } from './IAccessTokenStorage'; -import { SafeApolloClient } from './SafeApolloClient'; -import { createSnapshotCache } from './cache'; -import { createLensCache } from './cache/createLensCache'; -import { ContentInsightMatcher } from './cache/utils/ContentInsight'; -import { createAuthLink, createLensLink, createSnapshotLink } from './links'; - -export type { ContentInsightMatcher } from './cache/utils/ContentInsight'; -export { snapshotPoll, demoSnapshotPoll } from './cache/utils/ContentInsight'; - -export type ApolloClientConfig = { - accessTokenStorage: IAccessTokenStorage; - backendURL: string; - logger: ILogger; - pollingInterval: number; - contentMatchers: ContentInsightMatcher[]; -}; - -export function createLensApolloClient({ - accessTokenStorage, - backendURL, - logger, - pollingInterval, - contentMatchers, -}: ApolloClientConfig) { - const uri = `${backendURL}/graphql`; - - const authLink = createAuthLink(accessTokenStorage); - - const httpLink = createLensLink({ - uri, - logger, - supportedVersion: LENS_API_MINIMAL_SUPPORTED_VERSION, - }); - - return new SafeApolloClient({ - connectToDevTools: true, - cache: createLensCache({ contentMatchers }), - link: from([authLink, httpLink]), - pollingInterval, - version: LENS_API_MINIMAL_SUPPORTED_VERSION, - }); -} - -export type AuthApolloClientConfig = { - backendURL: string; - logger: ILogger; -}; - -export function createAuthApolloClient({ backendURL, logger }: AuthApolloClientConfig) { - const uri = `${backendURL}/graphql`; - - return new SafeApolloClient({ - cache: createLensCache(), - link: createLensLink({ uri, logger, supportedVersion: LENS_API_MINIMAL_SUPPORTED_VERSION }), - version: LENS_API_MINIMAL_SUPPORTED_VERSION, - }); -} - -export type SnapshotApolloClientConfig = { - backendURL: string; -}; - -export function createSnapshotApolloClient({ backendURL }: SnapshotApolloClientConfig) { - return new SafeApolloClient({ - cache: createSnapshotCache(), - link: createSnapshotLink({ - uri: `${backendURL}/graphql`, - }), - }); -} - -export type { IAccessTokenStorage }; -export type { IGraphQLClient } from './IGraphQLClient'; -export * from './errors'; -export * from './cache/transactions'; -export * from './cache/session'; -export type { SafeApolloClient }; diff --git a/packages/api-bindings-v1/src/apollo/isGraphQLValidationError.ts b/packages/api-bindings-v1/src/apollo/isGraphQLValidationError.ts deleted file mode 100644 index b0aa0a920c..0000000000 --- a/packages/api-bindings-v1/src/apollo/isGraphQLValidationError.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ApolloError } from '@apollo/client'; - -export enum ApolloServerErrorCode { - INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR', - GRAPHQL_PARSE_FAILED = 'GRAPHQL_PARSE_FAILED', - GRAPHQL_VALIDATION_FAILED = 'GRAPHQL_VALIDATION_FAILED', - PERSISTED_QUERY_NOT_FOUND = 'PERSISTED_QUERY_NOT_FOUND', - PERSISTED_QUERY_NOT_SUPPORTED = 'PERSISTED_QUERY_NOT_SUPPORTED', - BAD_USER_INPUT = 'BAD_USER_INPUT', - OPERATION_RESOLUTION_FAILURE = 'OPERATION_RESOLUTION_FAILURE', - BAD_REQUEST = 'BAD_REQUEST', -} - -export function isGraphQLValidationError(e: unknown): boolean { - if (e instanceof ApolloError) { - if ( - e.graphQLErrors[0] && - e.graphQLErrors[0].extensions && - e.graphQLErrors[0].extensions.code === ApolloServerErrorCode.GRAPHQL_VALIDATION_FAILED - ) { - return true; - } - } - - return false; -} diff --git a/packages/api-bindings-v1/src/apollo/links.ts b/packages/api-bindings-v1/src/apollo/links.ts deleted file mode 100644 index 6367dbdc62..0000000000 --- a/packages/api-bindings-v1/src/apollo/links.ts +++ /dev/null @@ -1,115 +0,0 @@ -// eslint-disable-next-line no-restricted-imports -import { from, fromPromise, HttpLink } from '@apollo/client'; -import { setContext } from '@apollo/client/link/context'; -import { onError } from '@apollo/client/link/error'; -import { maybe } from '@apollo/client/utilities'; -import { ILogger, never } from '@lens-protocol/shared-kernel'; - -import { SemVer } from '../SemVer'; -import { IAccessTokenStorage } from './IAccessTokenStorage'; - -/** - * An error code that's coming from `apollo-server-errors` `AuthenticationError` - */ -const AUTHENTICATION_ERROR_CODE = 'UNAUTHENTICATED'; - -export function createAuthLink(accessTokenStorage: IAccessTokenStorage) { - const errorLink = onError(({ graphQLErrors, operation, forward }) => { - if ( - graphQLErrors && - graphQLErrors.some((error) => error.extensions?.code === AUTHENTICATION_ERROR_CODE) - ) { - return fromPromise(accessTokenStorage.refreshToken()).flatMap(() => forward(operation)); - } - return; - }); - - const authHeaderLink = setContext(() => { - const token = accessTokenStorage.getAccessToken(); - - if (token) { - return { - headers: { - authorization: `Bearer ${token}`, - }, - }; - } - - return; - }); - - return from([errorLink, authHeaderLink]); -} - -const backupFetch = maybe(() => fetch); - -function wrapFetch( - logger: ILogger, - supportedVersion: SemVer, - fetch: WindowOrWorkerGlobalScope['fetch'], -): WindowOrWorkerGlobalScope['fetch'] { - return async (...args) => { - const response = await fetch(...args); - - if (response.status === 200) { - const apiVersion = response.headers.get('x-api-version'); - - if (apiVersion) { - if (apiVersion < supportedVersion) { - logger.error( - `The Lens API ${apiVersion} is outside of the Lens SDK support range ^${supportedVersion}`, - ); - return response; - } - - const [apiMajor, apiMinor] = apiVersion.split('.'); - const [clientMajor, clientMinor] = supportedVersion.split('.'); - - if (apiMajor && clientMajor && apiMajor > clientMajor) { - logger.warn( - `The Lens API ${apiVersion} is NOT supported by the Lens SDK support range ^${supportedVersion}. Update your Lens SDK client to the latest version.`, - ); - return response; - } - - if (apiMinor && clientMinor && apiMinor > clientMinor) { - logger.info( - `The Lens API ${apiVersion} is ahead of the Lens SDK support range ^${supportedVersion}. Check for a new version of the Lens SDK client, if available.`, - ); - return response; - } - } - } - return response; - }; -} - -export type LensLinkArgs = { - fetch?: WindowOrWorkerGlobalScope['fetch']; - logger: ILogger; - supportedVersion: SemVer; - uri: string; -}; - -export function createLensLink({ - fetch: preferredFetch, - logger, - supportedVersion, - uri, -}: LensLinkArgs) { - // see https://github.com/apollographql/apollo-client/blob/4bf773f64b78f15419f07676f434fa33e058404e/src/link/http/createHttpLink.ts#L160-L165 - const currentFetch = preferredFetch ?? maybe(() => fetch) ?? backupFetch ?? never(); - - return new HttpLink({ - uri, - fetch: wrapFetch(logger, supportedVersion, currentFetch), - }); -} - -export type SnapshotLinkArgs = { - uri: string; -}; - -export function createSnapshotLink({ uri }: SnapshotLinkArgs) { - return new HttpLink({ uri }); -} diff --git a/packages/api-bindings-v1/src/constants.ts b/packages/api-bindings-v1/src/constants.ts deleted file mode 100644 index 844bd4772e..0000000000 --- a/packages/api-bindings-v1/src/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { semVer } from './SemVer'; - -export const LENS_API_MINIMAL_SUPPORTED_VERSION = semVer('1.49'); diff --git a/packages/api-bindings-v1/src/index.ts b/packages/api-bindings-v1/src/index.ts deleted file mode 100644 index d8e09d4579..0000000000 --- a/packages/api-bindings-v1/src/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -export * from './apollo'; -export * from './lens'; -export * from './metadata'; -export { - GetSnapshotProposalDocument, - SnapshotVotingSystem, - useGetSnapshotProposal, -} from './snapshot'; -export type { - GetSnapshotProposalData, - GetSnapshotProposalVariables, - SnapshotProposal, - SnapshotVote, - SnapshotVotePower, -} from './snapshot'; diff --git a/packages/api-bindings-v1/src/lens/CollectPolicy.ts b/packages/api-bindings-v1/src/lens/CollectPolicy.ts deleted file mode 100644 index ca85b9785b..0000000000 --- a/packages/api-bindings-v1/src/lens/CollectPolicy.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { CollectPolicyType } from '@lens-protocol/domain/use-cases/publications'; -import { Erc20Amount, EthereumAddress } from '@lens-protocol/shared-kernel'; - -export enum CollectState { - CAN_BE_COLLECTED = 'CAN_BE_COLLECTED', - CANNOT_BE_COLLECTED = 'CANNOT_BE_COLLECTED', - NOT_A_FOLLOWER = 'NOT_A_FOLLOWER', - COLLECT_LIMIT_REACHED = 'COLLECT_LIMIT_REACHED', - COLLECT_TIME_EXPIRED = 'COLLECT_TIME_EXPIRED', -} - -export type FeeCollectPolicy = { - type: CollectPolicyType.CHARGE; - state: - | CollectState.CAN_BE_COLLECTED - | CollectState.NOT_A_FOLLOWER - | CollectState.COLLECT_LIMIT_REACHED - | CollectState.COLLECT_TIME_EXPIRED; - amount: Erc20Amount; - referralFee: number; - followerOnly: boolean; - collectNftAddress: EthereumAddress | null; - contractAddress: EthereumAddress; - endTimestamp: string | null; - collectLimit: number | null; -}; - -export type NoFeeCollectPolicy = { - type: CollectPolicyType.FREE; - state: - | CollectState.CAN_BE_COLLECTED - | CollectState.NOT_A_FOLLOWER - | CollectState.COLLECT_LIMIT_REACHED - | CollectState.COLLECT_TIME_EXPIRED; - followerOnly: boolean; - collectNftAddress: EthereumAddress | null; - contractAddress: EthereumAddress; - endTimestamp: string | null; - collectLimit: number | null; -}; - -/** - * @deprecated Use {@link FeeCollectPolicy} with `collectLimit` instead. - */ -export type LimitedFeeCollectPolicy = { - type: CollectPolicyType.CHARGE; - state: - | CollectState.CAN_BE_COLLECTED - | CollectState.NOT_A_FOLLOWER - | CollectState.COLLECT_LIMIT_REACHED; - amount: Erc20Amount; - referralFee: number; - followerOnly: boolean; - collectLimit: number; - collectNftAddress: EthereumAddress | null; - contractAddress: EthereumAddress; -}; - -/** - * @deprecated Use {@link FeeCollectPolicy} with `endTimestamp` instead. - */ -export type TimedFeeCollectPolicy = { - type: CollectPolicyType.CHARGE; - state: - | CollectState.CAN_BE_COLLECTED - | CollectState.NOT_A_FOLLOWER - | CollectState.COLLECT_TIME_EXPIRED; - amount: Erc20Amount; - referralFee: number; - followerOnly: boolean; - endTimestamp: string; - collectNftAddress: EthereumAddress | null; - contractAddress: EthereumAddress; -}; - -/** - * @deprecated Use {@link FeeCollectPolicy} with `collectLimit` and `endTimestamp` instead. - */ -export type LimitedTimedFeeCollectPolicy = { - type: CollectPolicyType.CHARGE; - state: - | CollectState.CAN_BE_COLLECTED - | CollectState.NOT_A_FOLLOWER - | CollectState.COLLECT_LIMIT_REACHED - | CollectState.COLLECT_TIME_EXPIRED; - amount: Erc20Amount; - referralFee: number; - followerOnly: boolean; - collectLimit: number; - endTimestamp: string; - collectNftAddress: EthereumAddress | null; - contractAddress: EthereumAddress; -}; - -export type MultirecipientFeeCollectPolicy = { - type: CollectPolicyType.CHARGE; - state: - | CollectState.CAN_BE_COLLECTED - | CollectState.NOT_A_FOLLOWER - | CollectState.COLLECT_LIMIT_REACHED - | CollectState.COLLECT_TIME_EXPIRED; - amount: Erc20Amount; - referralFee: number; - followerOnly: boolean; - collectLimit: number | null; - endTimestamp: string | null; - collectNftAddress: EthereumAddress | null; - contractAddress: EthereumAddress; -}; - -export type VaultFeeCollectPolicy = { - type: CollectPolicyType.CHARGE; - state: - | CollectState.CAN_BE_COLLECTED - | CollectState.NOT_A_FOLLOWER - | CollectState.COLLECT_LIMIT_REACHED - | CollectState.COLLECT_TIME_EXPIRED; - amount: Erc20Amount; - referralFee: number; - followerOnly: boolean; - collectLimit: number | null; - endTimestamp: string | null; - collectNftAddress: EthereumAddress | null; - contractAddress: EthereumAddress; -}; - -export type AaveFeeCollectPolicy = { - type: CollectPolicyType.CHARGE; - state: - | CollectState.CAN_BE_COLLECTED - | CollectState.NOT_A_FOLLOWER - | CollectState.COLLECT_LIMIT_REACHED - | CollectState.COLLECT_TIME_EXPIRED; - amount: Erc20Amount; - referralFee: number; - followerOnly: boolean; - collectLimit: number | null; - endTimestamp: string | null; - collectNftAddress: EthereumAddress | null; - contractAddress: EthereumAddress; -}; - -export type NoCollectPolicy = { - state: CollectState.CANNOT_BE_COLLECTED; - type: CollectPolicyType.NO_COLLECT; -}; - -export type CollectPolicy = - | FeeCollectPolicy - | NoFeeCollectPolicy - | LimitedFeeCollectPolicy - | TimedFeeCollectPolicy - | LimitedTimedFeeCollectPolicy - | MultirecipientFeeCollectPolicy - | VaultFeeCollectPolicy - | AaveFeeCollectPolicy - | NoCollectPolicy; diff --git a/packages/api-bindings-v1/src/lens/ContentEncryptionKey.ts b/packages/api-bindings-v1/src/lens/ContentEncryptionKey.ts deleted file mode 100644 index 37e260a021..0000000000 --- a/packages/api-bindings-v1/src/lens/ContentEncryptionKey.ts +++ /dev/null @@ -1,2 +0,0 @@ -// TODO this is a base16 encoded string, brand and/or type accordingly -export type ContentEncryptionKey = string; diff --git a/packages/api-bindings-v1/src/lens/ContentInsight.ts b/packages/api-bindings-v1/src/lens/ContentInsight.ts deleted file mode 100644 index 37ebdb628c..0000000000 --- a/packages/api-bindings-v1/src/lens/ContentInsight.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { PollId } from '@lens-protocol/domain/entities'; -import { Brand, Url } from '@lens-protocol/shared-kernel'; - -/** - * @internal - */ -export enum ContentInsightType { - SNAPSHOT_POLL = 'SNAPSHOT_POLL', - UNDETERMINED = 'UNDETERMINED', -} - -export type SnapshotProposalId = PollId; -export type SnapshotSpaceId = Brand; - -/** - * Opaque data structure representing a Snapshot poll details. - */ -export type SnapshotPoll = { - /** - * @internal - */ - type: ContentInsightType.SNAPSHOT_POLL; - /** - * @internal - */ - proposalId: SnapshotProposalId; - /** - * @internal - */ - spaceId: SnapshotSpaceId; - /** - * @internal - */ - url: Url; -}; - -/** - * Opaque data structure representing - */ -export type Undetermined = { - /** - * @internal - */ - type: ContentInsightType.UNDETERMINED; -}; - -/** - * Opaque data structure representing insights on the publication metadata textual content - */ -export type ContentInsight = SnapshotPoll | Undetermined; diff --git a/packages/api-bindings-v1/src/lens/Cursor.ts b/packages/api-bindings-v1/src/lens/Cursor.ts deleted file mode 100644 index 5d19327d55..0000000000 --- a/packages/api-bindings-v1/src/lens/Cursor.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Brand } from '@lens-protocol/shared-kernel'; - -export type Cursor = Brand; - -export function isCursor(value: unknown): value is Cursor { - return typeof value === 'string'; -} diff --git a/packages/api-bindings-v1/src/lens/FollowPolicy.ts b/packages/api-bindings-v1/src/lens/FollowPolicy.ts deleted file mode 100644 index 031f35f6b5..0000000000 --- a/packages/api-bindings-v1/src/lens/FollowPolicy.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { FollowPolicyType } from '@lens-protocol/domain/use-cases/profile'; -import { Erc20Amount } from '@lens-protocol/shared-kernel'; - -export type ChargeFollowPolicy = { - type: FollowPolicyType.CHARGE; - amount: Erc20Amount; - recipient: string; - contractAddress: string; -}; - -export type NoFeeFollowPolicy = { - type: FollowPolicyType.ONLY_PROFILE_OWNERS | FollowPolicyType.NO_ONE | FollowPolicyType.UNKNOWN; - contractAddress: string; -}; - -export type OpenFollowPolicy = { - type: FollowPolicyType.ANYONE; -}; - -export type FollowPolicy = ChargeFollowPolicy | NoFeeFollowPolicy | OpenFollowPolicy; diff --git a/packages/api-bindings-v1/src/lens/FollowStatus.ts b/packages/api-bindings-v1/src/lens/FollowStatus.ts deleted file mode 100644 index d75a4b1266..0000000000 --- a/packages/api-bindings-v1/src/lens/FollowStatus.ts +++ /dev/null @@ -1,31 +0,0 @@ -export type FollowStatus = { - /** - * Whether the profile is followed by the authenticated wallet - * - * Use this property to show the user if they are following a given profile. - * - * It uses aggressive optimistic update strategies to avoid waiting for the blockchain to confirm the follow request. - */ - isFollowedByMe: boolean; - - /** - * Determines if the authenticated wallet can follow the profile - * - * Use this property to enable/disable the follow functionality for a given profile. - * - * It also accounts for any pending follow/unfollow requests and avoids to accidentally send - * a follow request while a previous unfollow request is still pending. - * - */ - canFollow: boolean; - - /** - * Determines if the authenticated wallet can unfollow the profile - * - * Use this property to enable/disable the unfollow functionality for a given profile. - * - * It also accounts for any pending follow/unfollow requests and avoids to accidentally send - * an unfollow request while a previous follow request is still pending. - */ - canUnfollow: boolean; -}; diff --git a/packages/api-bindings-v1/src/lens/ImageSizeTransform.ts b/packages/api-bindings-v1/src/lens/ImageSizeTransform.ts deleted file mode 100644 index 28426c53d9..0000000000 --- a/packages/api-bindings-v1/src/lens/ImageSizeTransform.ts +++ /dev/null @@ -1,34 +0,0 @@ -export type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; - -export type Percentage = `100%` | `${Digit}${Digit}%` | `${Digit}%`; - -export type Pixel = - | `${Digit}${Digit}${Digit}${Digit}px` - | `${Digit}${Digit}${Digit}px` - | `${Digit}${Digit}px`; - -export type ImageSizeTransform = Pixel | Percentage | 'auto'; - -export type MediaTransformParams = { - /** - * Set the transformed image's width. You can use specific size in - * pixels eg. 100px, a percentage eg. 50% or set as 'auto' to be set automatically. - * - * @defaultValue 'auto' - */ - width?: ImageSizeTransform; - /** - * Set the transformed image's height. You can use specific size in - * pixels eg. 100px, a percentage eg. 50% or set as 'auto' to be set automatically. - * - * @defaultValue 'auto' - */ - height?: ImageSizeTransform; - /** - * Set if you want to keep the image's original aspect ratio. - * If explicitly set to false, the image will stretch based on the width and height values. - * - * @defaultValue true - */ - keepAspectRatio?: boolean; -}; diff --git a/packages/api-bindings-v1/src/lens/ProfileAttributeReader.ts b/packages/api-bindings-v1/src/lens/ProfileAttributeReader.ts deleted file mode 100644 index fe24000cae..0000000000 --- a/packages/api-bindings-v1/src/lens/ProfileAttributeReader.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Attribute } from './generated'; - -export class ProfileAttributeReader { - constructor(private readonly attribute: Attribute) {} - - toBoolean(): boolean | null { - const parsed: unknown = this.jsonParse(this.attribute.value); - - if (typeof parsed === 'boolean') { - return parsed; - } - return null; - } - - toDate(): Date | null { - const date = new Date(this.attribute.value); - - if (isNaN(date.getTime())) { - return null; - } - return date; - } - - toNumber(): number | null { - const parsed: unknown = this.jsonParse(this.attribute.value); - - if (typeof parsed === 'number' && isFinite(parsed)) { - return parsed; - } - return null; - } - - toString(): string { - return this.attribute.value; - } - - private jsonParse(value: string): unknown | null { - try { - return JSON.parse(value); - } catch { - return null; - } - } -} diff --git a/packages/api-bindings-v1/src/lens/ProfileAttributes.ts b/packages/api-bindings-v1/src/lens/ProfileAttributes.ts deleted file mode 100644 index 897085a44e..0000000000 --- a/packages/api-bindings-v1/src/lens/ProfileAttributes.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ProfileAttributeReader } from './ProfileAttributeReader'; - -export type ProfileAttributes = Record; diff --git a/packages/api-bindings-v1/src/lens/ReferencePolicy.ts b/packages/api-bindings-v1/src/lens/ReferencePolicy.ts deleted file mode 100644 index 9100ab634a..0000000000 --- a/packages/api-bindings-v1/src/lens/ReferencePolicy.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ReferencePolicyType } from '@lens-protocol/domain/use-cases/publications'; - -export type FollowersOnlyPolicy = { - type: ReferencePolicyType.FOLLOWERS_ONLY; -}; - -export type UnknownPolicy = { - type: ReferencePolicyType.UNKNOWN; - contractAddress: string; - data: string; -}; - -export type DegreesOfSeparationPolicy = { - type: ReferencePolicyType.DEGREES_OF_SEPARATION; - degreesOfSeparation: number; -}; - -export type AnyonePolicy = { - type: ReferencePolicyType.ANYONE; -}; - -export type ReferencePolicy = - | FollowersOnlyPolicy - | UnknownPolicy - | DegreesOfSeparationPolicy - | AnyonePolicy; diff --git a/packages/api-bindings-v1/src/lens/__helpers__/fragments.ts b/packages/api-bindings-v1/src/lens/__helpers__/fragments.ts deleted file mode 100644 index 70d608e3e5..0000000000 --- a/packages/api-bindings-v1/src/lens/__helpers__/fragments.ts +++ /dev/null @@ -1,773 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { - mockAppId, - mockProfileId, - mockPublicationId, - mockTransactionHash, -} from '@lens-protocol/domain/mocks'; -import { FollowPolicyType } from '@lens-protocol/domain/use-cases/profile'; -import { - CollectPolicyType, - ReferencePolicyType, -} from '@lens-protocol/domain/use-cases/publications'; -import { Erc20Amount } from '@lens-protocol/shared-kernel'; -import { mockDaiAmount, mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; - -import { CollectState, NoFeeCollectPolicy } from '../CollectPolicy'; -import { ContentEncryptionKey } from '../ContentEncryptionKey'; -import { FollowPolicy } from '../FollowPolicy'; -import { ProfileAttributes } from '../ProfileAttributes'; -import { - AnyConditionOutput, - Attribute, - CollectConditionOutput, - Comment, - ContractType, - DataAvailabilityPublicationResult, - EnabledModule, - EnabledModules, - EncryptedFieldsOutput, - EncryptionParamsOutput, - EncryptionProvider, - EoaOwnershipOutput, - Erc20AmountFields, - Erc20Fields, - Erc20OwnershipOutput, - FeedItem, - FollowConditionOutput, - LeafConditionOutput, - Media, - MetadataOutput, - Mirror, - ModuleInfo, - NftOwnershipOutput, - PaginatedResultInfo, - Post, - Profile, - ProfileFollowRevenue, - ProfileOwnershipOutput, - ProfileStats, - PublicationMainFocus, - PublicationRevenue, - PublicationStats, - ReactionTypes, - RelayerResult, - RelayError, - RelayErrorReasons, - RevenueAggregate, - RootConditionOutput, - ScalarOperator, - Wallet, - WhoReactedResult, -} from '../generated'; -import { - AnyPublication, - CollectModule, - erc20Amount, - ProfileCoverMedia, - ProfileOwnedByMe, - ProfilePictureMedia, -} from '../utils'; - -export function mockMediaFragment(overrides?: Partial): Media { - return { - altTag: faker.lorem.sentence(), - cover: faker.image.imageUrl(), - mimeType: 'image/jpeg', - url: faker.image.imageUrl(), - ...overrides, - __typename: 'Media', - }; -} - -export function mockProfilePictureMediaFragment( - overrides?: Partial, -): ProfilePictureMedia { - return { - original: mockMediaFragment(), - optimized: mockMediaFragment(), - thumbnail: mockMediaFragment(), - ...overrides, - __typename: 'MediaSet', - }; -} - -export function mockProfileCoverPictureMediaFragment( - overrides?: Partial, -): ProfileCoverMedia { - return { - original: mockMediaFragment(), - optimized: mockMediaFragment(), - ...overrides, - __typename: 'MediaSet', - }; -} - -export function mockAttributeFragment(overrides?: Partial): Attribute { - return { - key: 'answer', - value: '42', - displayType: 'string', - ...overrides, - __typename: 'Attribute', - }; -} - -export function mockAnyoneFollowPolicy(): FollowPolicy { - return { - type: FollowPolicyType.ANYONE, - }; -} - -export function mockWalletFragment(): Wallet { - return { - __typename: 'Wallet', - defaultProfile: mockProfileFragment(), - address: mockEthereumAddress(), - }; -} - -export function mockProfileStatsFragment(overrides?: Partial): ProfileStats { - return { - totalCollects: 0, - totalComments: 0, - totalFollowers: 0, - totalFollowing: 0, - totalMirrors: 0, - totalPosts: 0, - totalPublications: 0, - commentsCount: 0, - mirrorsCount: 0, - postsCount: 0, - ...overrides, - __typename: 'ProfileStats', - }; -} - -export function mockProfileFragment(overrides?: Partial): Profile { - const firstName = faker.name.firstName(); - const lastName = faker.name.lastName(); - - return { - id: mockProfileId(), - name: `${firstName} ${lastName}`, - bio: faker.lorem.sentence(), - handle: faker.internet.userName(firstName, lastName), - ownedBy: mockEthereumAddress(), - followNftAddress: mockEthereumAddress(), - interests: [], - picture: mockProfilePictureMediaFragment(), - coverPicture: mockProfileCoverPictureMediaFragment(), - - stats: mockProfileStatsFragment(overrides?.stats), - - dispatcher: null, - - onChainIdentity: { - proofOfHumanity: false, - ens: null, - sybilDotOrg: { - verified: false, - source: { - twitter: { - handle: null, - }, - }, - }, - worldcoin: { - isHuman: false, - }, - }, - - followModule: null, - followPolicy: mockAnyoneFollowPolicy(), - - isFollowedByMe: false, - isFollowingObserver: false, - followStatus: null, - - ownedByMe: false, - - __attributes: [], - attributes: {} as ProfileAttributes, - - invitedBy: null, - observedBy: null, - - ...overrides, - __typename: 'Profile', - }; -} - -export function mockProfileOwnedByMeFragment(overrides?: Partial): ProfileOwnedByMe { - return mockProfileFragment({ - ...overrides, - ownedByMe: true, - }) as ProfileOwnedByMe; -} - -export function mockRelayerResultFragment(txHash: string = mockTransactionHash()): RelayerResult { - return { - __typename: 'RelayerResult', - txHash, - txId: faker.datatype.uuid(), - }; -} - -export function mockRelayErrorFragment(reason: RelayErrorReasons): RelayError { - return { - __typename: 'RelayError', - reason, - }; -} - -export function mockDataAvailabilityPublicationResult(): DataAvailabilityPublicationResult { - return { - id: mockPublicationId(), - dataAvailabilityId: faker.datatype.uuid(), - __typename: 'CreateDataAvailabilityPublicationResult', - }; -} - -export function mockPublicationStatsFragment( - overrides?: Partial, -): PublicationStats { - return { - totalAmountOfMirrors: faker.datatype.number({ max: 42000, min: 0, precision: 1 }), - totalAmountOfCollects: faker.datatype.number({ max: 42000, min: 0, precision: 1 }), - totalAmountOfComments: faker.datatype.number({ max: 42000, min: 0, precision: 1 }), - totalUpvotes: faker.datatype.number({ max: 42000, min: 0, precision: 1 }), - totalDownvotes: faker.datatype.number({ max: 42000, min: 0, precision: 1 }), - commentsCount: faker.datatype.number({ max: 42000, min: 0, precision: 1 }), - totalBookmarks: faker.datatype.number({ max: 42000, min: 0, precision: 1 }), - ...overrides, - __typename: 'PublicationStats', - }; -} - -export function mockEncryptedFieldsOutputFragment( - overrides?: Partial, -): EncryptedFieldsOutput { - return { - animation_url: null, - content: null, - external_url: null, - image: null, - media: null, - ...overrides, - __typename: 'EncryptedFieldsOutput', - }; -} - -export function mockFreeCollectModuleSettings({ followerOnly = false } = {}): CollectModule { - return { - __typename: 'FreeCollectModuleSettings', - contractAddress: '0x96351D3cE872903EBf4c2D77dd625992CCFdf8c9', - followerOnly, - }; -} - -// Use this to test the handling of collect modules that are already whitelisted by backend but not yet support by sdk -export function mockNotYetKnownCollectModuleSettings(): CollectModule { - return { - __typename: 'NotYetKnownCollectModuleSettings', - } as unknown as CollectModule; -} - -export function mockMetadataOutputFragment(overrides?: Partial): MetadataOutput { - return { - animatedUrl: faker.internet.url(), - attributes: [], - content: faker.lorem.words(5), - contentWarning: null, - description: null, - encryptionParams: null, - image: faker.internet.url(), - locale: null, - mainContentFocus: PublicationMainFocus.TextOnly, - media: [], - name: faker.commerce.productName(), - tags: [], - - ...overrides, - __typename: 'MetadataOutput', - }; -} - -function mockNoFeeCollectPolicy(overrides?: Partial): NoFeeCollectPolicy { - return { - type: CollectPolicyType.FREE, - state: CollectState.CAN_BE_COLLECTED, - followerOnly: false, - collectNftAddress: mockEthereumAddress(), - contractAddress: mockEthereumAddress(), - endTimestamp: null, - collectLimit: null, - ...overrides, - }; -} - -export function mockPostFragment(overrides?: Partial>): Post { - return { - id: mockPublicationId(), - appId: mockAppId(), - createdAt: faker.datatype.datetime().toISOString(), - stats: mockPublicationStatsFragment(), - metadata: mockMetadataOutputFragment(), - profile: mockProfileFragment(), - collectedBy: null, - collectModule: mockFreeCollectModuleSettings(), - collectNftAddress: mockEthereumAddress(), - collectPolicy: mockNoFeeCollectPolicy(), - referenceModule: null, - hasCollectedByMe: false, - hasOptimisticCollectedByMe: false, - isOptimisticMirroredByMe: false, - isMirroredByMe: false, - mirrors: [], - reaction: null, - hidden: false, - notInterested: false, - bookmarked: false, - - isGated: false, - decryptionCriteria: null, - observedBy: null, - - canComment: { - result: true, - }, - canMirror: { - result: true, - }, - canObserverDecrypt: { - result: true, - reasons: null, - }, - referencePolicy: { - type: ReferencePolicyType.ANYONE, - }, - ...overrides, - __typename: 'Post', - } as Post; -} - -export function mockCommentFragment(overrides?: Partial>): Comment { - const mainPost = mockPostFragment(); - - return { - id: mockPublicationId(), - appId: mockAppId(), - stats: mockPublicationStatsFragment(), - metadata: mockMetadataOutputFragment(), - profile: mockProfileFragment(), - createdAt: faker.date.past().toISOString(), - collectedBy: null, - commentOn: mainPost, - mainPost: mainPost, - collectModule: mockFreeCollectModuleSettings(), - collectNftAddress: mockEthereumAddress(), - collectPolicy: mockNoFeeCollectPolicy(), - referenceModule: null, - hasCollectedByMe: false, - hasOptimisticCollectedByMe: false, - isOptimisticMirroredByMe: false, - isMirroredByMe: false, - mirrors: [], - reaction: null, - hidden: false, - notInterested: false, - bookmarked: false, - - isGated: false, - decryptionCriteria: null, - observedBy: null, - - canComment: { - result: true, - }, - canMirror: { - result: true, - }, - canObserverDecrypt: { - result: false, - reasons: null, - }, - referencePolicy: { - type: ReferencePolicyType.ANYONE, - }, - firstComment: null, - ...overrides, - __typename: 'Comment', - } as Comment; -} - -export function mockMirrorFragment(overrides?: Partial>): Mirror { - const mainPost = mockPostFragment(); - - return { - id: mockPublicationId(), - profile: mockProfileFragment(), - createdAt: faker.date.past().toISOString(), - mirrorOf: mainPost, - hidden: false, - ...overrides, - __typename: 'Mirror', - }; -} - -export function mockFeedItemFragment(overrides?: Partial): FeedItem { - return { - root: mockPostFragment(), - comments: null, - mirrors: [], - electedMirror: null, - reactions: [], - collects: [], - ...overrides, - __typename: 'FeedItem', - }; -} - -function mockErc20FieldsFragment( - overrides?: Partial>, -): Erc20Fields { - return { - __typename: 'Erc20', - name: 'Wrapped MATIC', - symbol: 'WMATIC', - decimals: 18, - address: mockEthereumAddress(), - ...overrides, - }; -} - -export function mockErc20AmountFieldsFragment(amount = mockDaiAmount(42)): Erc20AmountFields { - return { - __typename: 'Erc20Amount', - asset: mockErc20FieldsFragment({ - name: amount.asset.name, - symbol: amount.asset.symbol, - decimals: amount.asset.decimals, - address: amount.asset.address, - }), - value: amount.toSignificantDigits(), - }; -} - -function mockRevenueAggregateFragment(amount?: Erc20Amount): RevenueAggregate { - const total = mockErc20AmountFieldsFragment(amount); - return { - __typename: 'RevenueAggregate', - __total: total, - totalAmount: erc20Amount({ from: total }), - }; -} - -export function mockPublicationRevenueFragment({ - publication = mockPostFragment(), - amount, -}: { - publication?: AnyPublication; - amount?: Erc20Amount; -} = {}): PublicationRevenue { - return { - __typename: 'PublicationRevenue', - publication: publication, - revenue: mockRevenueAggregateFragment(amount), - }; -} - -export function mockProfileFollowRevenueFragment({ - amount, -}: { - amount?: Erc20Amount; -} = {}): ProfileFollowRevenue { - return { - __typename: 'FollowRevenueResult', - revenues: [mockRevenueAggregateFragment(amount)], - }; -} - -export function mockWhoReactedResultFragment( - overrides?: Partial>, -): WhoReactedResult { - return { - __typename: 'WhoReactedResult', - reactionId: faker.datatype.uuid(), - reaction: ReactionTypes.Upvote, - reactionAt: faker.date.past().toISOString(), - profile: mockProfileFragment(), - ...overrides, - }; -} - -export function mockModuleInfoFragment( - overrides?: Partial>, -): ModuleInfo { - return { - __typename: 'ModuleInfo', - name: faker.datatype.string(), - type: faker.datatype.string(), - ...overrides, - }; -} - -export function mockEnabledModuleFragment( - overrides?: Partial>, -): EnabledModule { - return { - __typename: 'EnabledModule', - moduleName: faker.datatype.string(), - contractAddress: mockEthereumAddress(), - inputParams: [mockModuleInfoFragment()], - redeemParams: [mockModuleInfoFragment()], - returnDataParams: [mockModuleInfoFragment()], - ...overrides, - }; -} - -export function mockEnabledModulesFragment( - overrides?: Partial>, -): EnabledModules { - return { - __typename: 'EnabledModules', - collectModules: [mockEnabledModuleFragment()], - followModules: [mockEnabledModuleFragment()], - referenceModules: [mockEnabledModuleFragment()], - ...overrides, - }; -} - -export function mockNftOwnershipAccessCondition( - overrides?: Partial, -): AnyConditionOutput { - return { - __typename: 'AccessConditionOutput', - nft: { - chainID: 1, - contractAddress: mockEthereumAddress(), - contractType: ContractType.Erc721, - tokenIds: [faker.datatype.number().toString()], - ...overrides, - __typename: 'NftOwnershipOutput', - }, - and: null, - collect: null, - eoa: null, - follow: null, - or: null, - profile: null, - token: null, - }; -} - -export function mockErc20OwnershipAccessCondition( - overrides?: Partial, -): AnyConditionOutput { - return { - __typename: 'AccessConditionOutput', - token: { - amount: '100', - chainID: 1, - condition: ScalarOperator.Equal, - contractAddress: mockEthereumAddress(), - decimals: 18, - name: 'Dai Stablecoin', - symbol: 'DAI', - ...overrides, - __typename: 'Erc20OwnershipOutput', - }, - and: null, - collect: null, - eoa: null, - follow: null, - nft: null, - or: null, - profile: null, - }; -} - -export function mockEoaOwnershipAccessCondition( - overrides?: Partial, -): AnyConditionOutput { - return { - __typename: 'AccessConditionOutput', - eoa: { - address: mockEthereumAddress(), - ...overrides, - __typename: 'EoaOwnershipOutput', - }, - and: null, - collect: null, - follow: null, - nft: null, - or: null, - profile: null, - token: null, - }; -} - -export function mockProfileOwnershipAccessCondition( - overrides?: Partial, -): AnyConditionOutput { - return { - __typename: 'AccessConditionOutput', - profile: { - profileId: mockProfileId(), - ...overrides, - __typename: 'ProfileOwnershipOutput', - }, - and: null, - collect: null, - eoa: null, - follow: null, - nft: null, - or: null, - token: null, - }; -} - -export function mockFollowConditionAccessCondition( - overrides?: Partial, -): AnyConditionOutput { - return { - __typename: 'AccessConditionOutput', - follow: { - profileId: mockProfileId(), - ...overrides, - __typename: 'FollowConditionOutput', - }, - and: null, - collect: null, - eoa: null, - nft: null, - or: null, - profile: null, - token: null, - }; -} - -export function mockCollectConditionAccessCondition( - condition: Omit = { - publicationId: mockPublicationId(), - thisPublication: null, - }, -): AnyConditionOutput { - return { - __typename: 'AccessConditionOutput', - collect: { - ...condition, - __typename: 'CollectConditionOutput', - }, - and: null, - eoa: null, - follow: null, - nft: null, - or: null, - profile: null, - token: null, - }; -} - -export function mockOrAccessCondition( - criteria: Array = [], -): AnyConditionOutput { - return { - __typename: 'AccessConditionOutput', - or: { __typename: 'OrConditionOutput', criteria }, - and: null, - collect: null, - eoa: null, - follow: null, - nft: null, - profile: null, - token: null, - }; -} - -export function mockAndAccessCondition( - criteria: Array = [], -): AnyConditionOutput { - return { - __typename: 'AccessConditionOutput', - and: { __typename: 'AndConditionOutput', criteria }, - collect: null, - eoa: null, - follow: null, - nft: null, - or: null, - profile: null, - token: null, - }; -} - -function mockPublicationOwnerAccessCondition( - overrides?: Partial, -): AnyConditionOutput { - return { - __typename: 'AccessConditionOutput', - profile: { __typename: 'ProfileOwnershipOutput', profileId: mockProfileId(), ...overrides }, - and: null, - collect: null, - eoa: null, - follow: null, - nft: null, - or: null, - token: null, - }; -} - -function mockRootConditionFragment({ - others, - ownerId, -}: { - others: AnyConditionOutput[]; - ownerId: ProfileId; -}): RootConditionOutput { - return { - __typename: 'AccessConditionOutput', - or: { - criteria: [mockPublicationOwnerAccessCondition({ profileId: ownerId }), ...others], - }, - }; -} - -export function mockEncryptionParamsOutputFragment({ - others, - ownerId, - encryptedFields = mockEncryptedFieldsOutputFragment(), - encryptionKey = '0x123', -}: { - others: AnyConditionOutput[]; - ownerId: ProfileId; - encryptedFields?: EncryptedFieldsOutput; - encryptionKey?: ContentEncryptionKey; -}): EncryptionParamsOutput { - return { - __typename: 'EncryptionParamsOutput', - accessCondition: mockRootConditionFragment({ - others, - ownerId, - }), - encryptionProvider: EncryptionProvider.LitProtocol, - encryptedFields, - providerSpecificParams: { - encryptionKey, - }, - }; -} - -export function mockPaginatedResultInfo( - overrides: Partial = {}, -): PaginatedResultInfo { - return { - __typename: 'PaginatedResultInfo', - moreAfter: false, - prev: null, - next: null, - totalCount: null, - ...overrides, - }; -} diff --git a/packages/api-bindings-v1/src/lens/__helpers__/index.ts b/packages/api-bindings-v1/src/lens/__helpers__/index.ts deleted file mode 100644 index bbce96e6c1..0000000000 --- a/packages/api-bindings-v1/src/lens/__helpers__/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './fragments'; -export * from './queries'; -export * from './mutations'; diff --git a/packages/api-bindings-v1/src/lens/__helpers__/mutations.ts b/packages/api-bindings-v1/src/lens/__helpers__/mutations.ts deleted file mode 100644 index 385f2abecd..0000000000 --- a/packages/api-bindings-v1/src/lens/__helpers__/mutations.ts +++ /dev/null @@ -1,891 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { faker } from '@faker-js/faker'; -import { Nonce } from '@lens-protocol/domain/entities'; -import { mockNonce, mockProfileId } from '@lens-protocol/domain/mocks'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; -import { GraphQLError } from 'graphql'; - -import { createGraphQLValidationError } from '../../apollo/__helpers__/mocks'; -import { - AddNotInterestedData, - AddNotInterestedDocument, - AddNotInterestedVariables, - AddReactionData, - AddReactionDocument, - AddReactionVariables, - AddToMyBookmarksDocument, - AddToMyBookmarksVariables, - BroadcastOffChainData, - BroadcastOffChainDocument, - BroadcastOffChainResult, - BroadcastOffChainVariables, - BroadcastOnChainData, - BroadcastOnChainDocument, - BroadcastOnChainResult, - BroadcastOnChainVariables, - CreateCollectTypedDataData, - CreateCommentTypedDataData, - CreateCommentTypedDataDocument, - CreateCommentTypedDataVariables, - CreateCommentViaDispatcherData, - CreateCommentViaDispatcherDocument, - CreateCommentViaDispatcherVariables, - CreateDataAvailabilityCommentTypedDataData, - CreateDataAvailabilityCommentTypedDataDocument, - CreateDataAvailabilityCommentTypedDataVariables, - CreateDataAvailabilityCommentViaDispatcherData, - CreateDataAvailabilityCommentViaDispatcherDocument, - CreateDataAvailabilityCommentViaDispatcherVariables, - CreateDataAvailabilityMirrorTypedDataData, - CreateDataAvailabilityMirrorTypedDataDocument, - CreateDataAvailabilityMirrorTypedDataVariables, - CreateDataAvailabilityMirrorViaDispatcherData, - CreateDataAvailabilityMirrorViaDispatcherDocument, - CreateDataAvailabilityMirrorViaDispatcherVariables, - CreateDataAvailabilityPostTypedDataData, - CreateDataAvailabilityPostTypedDataDocument, - CreateDataAvailabilityPostTypedDataVariables, - CreateDataAvailabilityPostViaDispatcherData, - CreateDataAvailabilityPostViaDispatcherDocument, - CreateDataAvailabilityPostViaDispatcherVariables, - CreateFollowTypedDataData, - CreateMirrorTypedDataData, - CreateMirrorTypedDataDocument, - CreateMirrorTypedDataVariables, - CreateMirrorViaDispatcherData, - CreateMirrorViaDispatcherDocument, - CreateMirrorViaDispatcherVariables, - CreatePostTypedDataData, - CreatePostTypedDataDocument, - CreatePostTypedDataVariables, - CreatePostViaDispatcherData, - CreatePostViaDispatcherDocument, - CreatePostViaDispatcherVariables, - CreateProfileData, - CreateProfileDocument, - CreateProfileVariables, - CreatePublicSetProfileMetadataUriRequest, - CreateSetDispatcherTypedDataData, - CreateSetFollowModuleTypedDataData, - CreateSetProfileImageUriTypedDataData, - CreateSetProfileImageUriTypedDataDocument, - CreateSetProfileImageUriTypedDataVariables, - CreateSetProfileImageUriViaDispatcherData, - CreateSetProfileImageUriViaDispatcherDocument, - CreateSetProfileImageUriViaDispatcherVariables, - CreateSetProfileMetadataTypedDataData, - CreateSetProfileMetadataTypedDataDocument, - CreateSetProfileMetadataViaDispatcherData, - CreateSetProfileMetadataViaDispatcherDocument, - CreateSetProfileMetadataViaDispatcherVariables, - CreateUnfollowTypedDataData, - Eip712TypedDataDomain, - HidePublicationData, - HidePublicationDocument, - HidePublicationVariables, - ProxyActionData, - ProxyActionDocument, - ProxyActionVariables, - RemoveFromMyBookmarksDocument, - RemoveFromMyBookmarksVariables, - RemoveNotInterestedData, - RemoveNotInterestedDocument, - RemoveNotInterestedVariables, - RemoveReactionData, - RemoveReactionDocument, - RemoveReactionVariables, - ReportPublicationData, - ReportPublicationDocument, - ReportPublicationVariables, -} from '../generated'; - -export function mockCreateProfileResponse({ - request, - result, -}: { - request: CreateProfileVariables['request']; - result: Required; -}): MockedResponse { - return { - request: { - query: CreateProfileDocument, - variables: { request }, - }, - result: { - data: { result }, - }, - }; -} - -function mockBroadcastOnChainData(result: Required): BroadcastOnChainData { - return { - result, - }; -} - -export function mockBroadcastOnChainResponse({ - result, - variables, -}: { - result: Required; - variables: BroadcastOnChainVariables; -}): MockedResponse { - return { - request: { - query: BroadcastOnChainDocument, - variables: variables, - }, - result: { - data: mockBroadcastOnChainData(result), - }, - }; -} - -function mockBroadcastOffChainData( - result: Required, -): BroadcastOffChainData { - return { - result, - }; -} - -export function mockBroadcastOffChainResponse({ - result, - variables, -}: { - result: Required; - variables: BroadcastOffChainVariables; -}): MockedResponse { - return { - request: { - query: BroadcastOffChainDocument, - variables: variables, - }, - result: { - data: mockBroadcastOffChainData(result), - }, - }; -} - -function mockCreateTypedDataResult( - __typename: T, - typedData: D, -) { - return { - __typename, - id: faker.datatype.uuid(), - expiresAt: faker.date.future().toISOString(), - typedData, - }; -} - -function mockEIP712TypedDataField() { - return { - __typename: 'EIP712TypedDataField', - name: 'nonce', - type: 'uint256', - }; -} - -function mockEIP712TypedDataDomain(): Eip712TypedDataDomain { - return { - __typename: 'EIP712TypedDataDomain', - name: 'Lens', - version: '1', - chainId: 0, - verifyingContract: mockEthereumAddress(), - }; -} - -export function mockCreatePostTypedDataData({ - nonce = mockNonce(), -}: { nonce?: Nonce } = {}): CreatePostTypedDataData { - return { - result: mockCreateTypedDataResult('CreatePostBroadcastItemResult', { - __typename: 'CreatePostEIP712TypedData', - types: { - __typename: 'CreatePostEIP712TypedDataTypes', - PostWithSig: [mockEIP712TypedDataField()], - }, - domain: mockEIP712TypedDataDomain(), - message: { - __typename: 'CreatePostEIP712TypedDataValue', - nonce, - deadline: 1644303500, - profileId: mockProfileId(), - contentURI: 'ipfs://QmR5V6fwKWzoa9gevmYaQ11eMQsAahsjfWPz1rCoNJjN1K.json', - collectModule: '0xd6072BB2ABc0a9d1331c7d0B83AE6C47f2Cb86A3', - collectModuleInitData: '0x', - referenceModule: '0x0000000000000000000000000000000000000000', - referenceModuleInitData: '0x', - }, - }), - }; -} - -export function mockCreateCommentTypedDataData({ - nonce = mockNonce(), -}: { nonce?: Nonce } = {}): CreateCommentTypedDataData { - return { - result: mockCreateTypedDataResult('CreateCommentBroadcastItemResult', { - __typename: 'CreateCommentEIP712TypedData', - types: { - __typename: 'CreateCommentEIP712TypedDataTypes', - CommentWithSig: [mockEIP712TypedDataField()], - }, - domain: mockEIP712TypedDataDomain(), - message: { - __typename: 'CreateCommentEIP712TypedDataValue', - profileIdPointed: mockProfileId(), - pubIdPointed: faker.datatype.hexadecimal({ length: 2 }), - nonce, - deadline: 1644303500, - profileId: mockProfileId(), - contentURI: 'ipfs://QmR5V6fwKWzoa9gevmYaQ11eMQsAahsjfWPz1rCoNJjN1K.json', - collectModule: '0xd6072BB2ABc0a9d1331c7d0B83AE6C47f2Cb86A3', - collectModuleInitData: '0x', - referenceModuleData: '0x0000000000000000000000000000000000000000', - referenceModule: '0x0000000000000000000000000000000000000000', - referenceModuleInitData: '0x', - }, - }), - }; -} - -export function mockCreateMirrorTypedDataData({ - nonce = mockNonce(), -}: { nonce?: Nonce } = {}): CreateMirrorTypedDataData { - return { - result: mockCreateTypedDataResult('CreateMirrorBroadcastItemResult', { - __typename: 'CreateMirrorEIP712TypedData', - types: { - __typename: 'CreateMirrorEIP712TypedDataTypes', - MirrorWithSig: [mockEIP712TypedDataField()], - }, - domain: mockEIP712TypedDataDomain(), - message: { - __typename: 'CreateMirrorEIP712TypedDataValue', - profileIdPointed: mockProfileId(), - pubIdPointed: faker.datatype.hexadecimal({ length: 2 }), - nonce, - deadline: 1644303500, - profileId: mockProfileId(), - referenceModuleData: '0x0000000000000000000000000000000000000000', - referenceModule: '0x0000000000000000000000000000000000000000', - referenceModuleInitData: '0x', - }, - }), - }; -} - -export function mockHidePublicationResponse(args: { - variables: HidePublicationVariables; -}): MockedResponse { - return { - request: { - query: HidePublicationDocument, - variables: args.variables, - }, - result: { - data: { hidePublication: null }, - }, - }; -} - -export function mockAddReactionResponse(args: { - variables: AddReactionVariables; -}): MockedResponse { - return { - request: { - query: AddReactionDocument, - variables: args.variables, - }, - result: { - data: { addReaction: null }, - }, - }; -} - -export function mockRemoveReactionResponse(args: { - variables: RemoveReactionVariables; -}): MockedResponse { - return { - request: { - query: RemoveReactionDocument, - variables: args.variables, - }, - result: { - data: { removeReaction: null }, - }, - }; -} - -export function mockRemoveReactionResponseWithGraphqlValidationError(args: { - variables: RemoveReactionVariables; -}): MockedResponse { - return { - request: { - query: RemoveReactionDocument, - variables: args.variables, - }, - result: { - errors: [ - createGraphQLValidationError( - `You have not reacted to this publication with action ${args.variables.reaction}}`, - ), - ], - }, - }; -} - -export function mockCreateFollowTypedDataData({ - nonce = mockNonce(), -}: { nonce?: Nonce } = {}): CreateFollowTypedDataData { - return { - result: mockCreateTypedDataResult('CreateFollowBroadcastItemResult', { - __typename: 'CreateFollowEIP712TypedData', - types: { - __typename: 'CreateFollowEIP712TypedDataTypes', - FollowWithSig: [mockEIP712TypedDataField()], - }, - domain: mockEIP712TypedDataDomain(), - message: { - __typename: 'CreateFollowEIP712TypedDataValue', - nonce, - deadline: '0', - profileIds: [mockProfileId()], - datas: [faker.datatype.hexadecimal({ length: 2 })], - }, - }), - }; -} - -export function mockCreateSetProfileMetadataTypedDataData({ - nonce = mockNonce(), -}: { nonce?: Nonce } = {}): CreateSetProfileMetadataTypedDataData { - return { - result: mockCreateTypedDataResult('CreateSetProfileMetadataURIBroadcastItemResult', { - __typename: 'CreateSetProfileMetadataURIEIP712TypedData', - types: { - __typename: 'CreateSetProfileMetadataURIEIP712TypedDataTypes', - SetProfileMetadataURIWithSig: [mockEIP712TypedDataField()], - }, - domain: mockEIP712TypedDataDomain(), - message: { - __typename: 'CreateSetProfileMetadataURIEIP712TypedDataValue', - nonce, - deadline: '0', - profileId: mockProfileId(), - metadata: faker.internet.url(), - }, - }), - }; -} - -export function mockCreateUnfollowTypedDataData({ - nonce = mockNonce(), -}: { nonce?: Nonce } = {}): CreateUnfollowTypedDataData { - return { - result: mockCreateTypedDataResult('CreateUnfollowBroadcastItemResult', { - __typename: 'CreateBurnEIP712TypedData', - types: { - __typename: 'CreateBurnEIP712TypedDataTypes', - BurnWithSig: [mockEIP712TypedDataField()], - }, - domain: mockEIP712TypedDataDomain(), - message: { - __typename: 'CreateBurnEIP712TypedDataValue', - nonce, - deadline: '0', - tokenId: faker.datatype.hexadecimal({ length: 2 }), - }, - }), - }; -} - -export function mockBroadcastProxyActionCallResponse(instructions: { - result: string; - variables: ProxyActionVariables; -}): MockedResponse { - return { - request: { - query: ProxyActionDocument, - variables: instructions.variables, - }, - result: { - data: { result: instructions.result }, - }, - }; -} - -export function createBroadcastProxyActionCallMockedError(instructions: { - errorMessage: string; - variables: ProxyActionVariables; -}): MockedResponse { - return { - request: { - query: ProxyActionDocument, - variables: instructions.variables, - }, - result: { - errors: [new GraphQLError(instructions.errorMessage)], - }, - }; -} - -export function mockCreateSetFollowModuleTypedDataData({ - nonce = mockNonce(), -}: { nonce?: Nonce } = {}): CreateSetFollowModuleTypedDataData { - return { - result: mockCreateTypedDataResult('CreateSetFollowModuleBroadcastItemResult', { - __typename: 'CreateSetFollowModuleEIP712TypedData', - types: { - __typename: 'CreateSetFollowModuleEIP712TypedDataTypes', - SetFollowModuleWithSig: [mockEIP712TypedDataField()], - }, - domain: mockEIP712TypedDataDomain(), - message: { - __typename: 'CreateSetFollowModuleEIP712TypedDataValue', - nonce, - deadline: '0', - profileId: mockProfileId(), - followModule: mockEthereumAddress(), - followModuleInitData: '0x00', - }, - }), - }; -} - -export function mockCreateSetProfileImageUriTypedDataData({ - nonce = mockNonce(), -}: { nonce?: Nonce } = {}): CreateSetProfileImageUriTypedDataData { - return { - result: mockCreateTypedDataResult('CreateSetProfileImageUriBroadcastItemResult', { - __typename: 'CreateSetProfileImageUriEIP712TypedData', - types: { - __typename: 'CreateSetProfileImageUriEIP712TypedDataTypes', - SetProfileImageURIWithSig: [mockEIP712TypedDataField()], - }, - domain: mockEIP712TypedDataDomain(), - message: { - __typename: 'CreateSetProfileImageUriEIP712TypedDataValue', - nonce, - deadline: 1644303500, - profileId: mockProfileId(), - imageURI: faker.internet.url(), - }, - }), - }; -} - -export function mockCreateSetProfileImageUriTypedDataResponse< - T extends CreateSetProfileImageUriTypedDataData, ->({ - variables, - data, -}: { - variables: CreateSetProfileImageUriTypedDataVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateSetProfileImageUriTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateSetDispatcherTypedDataData({ - nonce = mockNonce(), -}: { nonce?: Nonce } = {}): CreateSetDispatcherTypedDataData { - return { - result: mockCreateTypedDataResult('CreateSetDispatcherBroadcastItemResult', { - __typename: 'CreateSetDispatcherEIP712TypedData', - types: { - __typename: 'CreateSetDispatcherEIP712TypedDataTypes', - SetDispatcherWithSig: [mockEIP712TypedDataField()], - }, - domain: mockEIP712TypedDataDomain(), - message: { - __typename: 'CreateSetDispatcherEIP712TypedDataValue', - nonce, - deadline: '0', - profileId: mockProfileId(), - dispatcher: mockEthereumAddress(), - }, - }), - }; -} - -export function mockCreateSetProfileMetadataTypedDataResponse({ - request, - overrideSigNonce, - data = mockCreateSetProfileMetadataTypedDataData({ nonce: overrideSigNonce }), -}: { - request: CreatePublicSetProfileMetadataUriRequest; - overrideSigNonce?: Nonce; - data?: CreateSetProfileMetadataTypedDataData; -}): MockedResponse { - return { - request: { - query: CreateSetProfileMetadataTypedDataDocument, - variables: { - request, - options: overrideSigNonce ? { overrideSigNonce } : undefined, - }, - }, - result: { data }, - }; -} - -export function mockCreateSetProfileMetadataViaDispatcherResponse< - T extends CreateSetProfileMetadataViaDispatcherData, ->({ - variables, - data, -}: { - variables: CreateSetProfileMetadataViaDispatcherVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateSetProfileMetadataViaDispatcherDocument, - variables, - }, - result: { data }, - }; -} - -export function mockCreateCommentTypedDataResponse({ - variables, - data, -}: { - variables: CreateCommentTypedDataVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateCommentTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateDataAvailabilityCommentTypedDataResponse< - T extends CreateDataAvailabilityCommentTypedDataData, ->({ - variables, - data, -}: { - variables: CreateDataAvailabilityCommentTypedDataVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateDataAvailabilityCommentTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateCommentViaDispatcherResponse({ - variables, - data, -}: { - variables: CreateCommentViaDispatcherVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateCommentViaDispatcherDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateDataAvailabilityCommentViaDispatcherDataResponse< - T extends CreateDataAvailabilityCommentViaDispatcherData, ->({ - variables, - data, -}: { - variables: CreateDataAvailabilityCommentViaDispatcherVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateDataAvailabilityCommentViaDispatcherDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateMirrorTypedDataResponse({ - variables, - data, -}: { - variables: CreateMirrorTypedDataVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateMirrorTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateDataAvailabilityMirrorTypedDataResponse< - T extends CreateDataAvailabilityMirrorTypedDataData, ->({ - variables, - data, -}: { - variables: CreateDataAvailabilityMirrorTypedDataVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateDataAvailabilityMirrorTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateMirrorViaDispatcherResponse({ - variables, - data, -}: { - variables: CreateMirrorViaDispatcherVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateMirrorViaDispatcherDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateDataAvailabilityMirrorViaDispatcherDataResponse< - T extends CreateDataAvailabilityMirrorViaDispatcherData, ->({ - variables, - data, -}: { - variables: CreateDataAvailabilityMirrorViaDispatcherVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateDataAvailabilityMirrorViaDispatcherDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreatePostTypedDataResponse({ - variables, - data, -}: { - variables: CreatePostTypedDataVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreatePostTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateDataAvailabilityPostTypedDataResponse< - T extends CreateDataAvailabilityPostTypedDataData, ->({ - variables, - data, -}: { - variables: CreateDataAvailabilityPostTypedDataVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateDataAvailabilityPostTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreatePostViaDispatcherResponse({ - variables, - data, -}: { - variables: CreatePostViaDispatcherVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreatePostViaDispatcherDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateDataAvailabilityPostViaDispatcherDataResponse< - T extends CreateDataAvailabilityPostViaDispatcherData, ->({ - variables, - data, -}: { - variables: CreateDataAvailabilityPostViaDispatcherVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateDataAvailabilityPostViaDispatcherDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockSetProfileImageURIViaDispatcherResponse< - T extends CreateSetProfileImageUriViaDispatcherData, ->({ - variables, - data, -}: { - variables: CreateSetProfileImageUriViaDispatcherVariables; - data: T; -}): MockedResponse { - return { - request: { - query: CreateSetProfileImageUriViaDispatcherDocument, - variables, - }, - result: { - data, - }, - }; -} - -export function mockCreateCollectTypedDataData({ - nonce = mockNonce(), -}: { nonce?: Nonce } = {}): CreateCollectTypedDataData { - return { - result: mockCreateTypedDataResult('CreateCollectBroadcastItemResult', { - __typename: 'CreateCollectEIP712TypedData', - types: { - __typename: 'CreateCollectEIP712TypedDataTypes', - CollectWithSig: [mockEIP712TypedDataField()], - }, - domain: mockEIP712TypedDataDomain(), - message: { - __typename: 'CreateCollectEIP712TypedDataValue', - nonce, - deadline: '0', - profileId: mockProfileId(), - pubId: faker.datatype.hexadecimal({ length: 2 }), - data: faker.datatype.hexadecimal({ length: 2 }), - }, - }), - }; -} - -export function mockReportPublicationResponse(args: { - variables: ReportPublicationVariables; -}): MockedResponse { - return { - request: { - query: ReportPublicationDocument, - variables: args.variables, - }, - result: { data: { reportPublication: null } }, - }; -} - -export function mockAddNotInterestedResponse( - variables: AddNotInterestedVariables, -): MockedResponse { - return { - request: { - query: AddNotInterestedDocument, - variables, - }, - result: { data: { result: null } }, - }; -} - -export function mockRemoveNotInterestedResponse( - variables: RemoveNotInterestedVariables, -): MockedResponse { - return { - request: { - query: RemoveNotInterestedDocument, - variables, - }, - result: { data: { result: null } }, - }; -} - -export function mockAddToMyBookmarksResponse( - variables: AddToMyBookmarksVariables, -): MockedResponse { - return { - request: { - query: AddToMyBookmarksDocument, - variables, - }, - result: { data: { result: null } }, - }; -} - -export function mockRemoveFromMyBookmarksResponse( - variables: RemoveFromMyBookmarksVariables, -): MockedResponse { - return { - request: { - query: RemoveFromMyBookmarksDocument, - variables, - }, - result: { data: { result: null } }, - }; -} diff --git a/packages/api-bindings-v1/src/lens/__helpers__/queries.ts b/packages/api-bindings-v1/src/lens/__helpers__/queries.ts deleted file mode 100644 index 387c87ae13..0000000000 --- a/packages/api-bindings-v1/src/lens/__helpers__/queries.ts +++ /dev/null @@ -1,597 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { faker } from '@faker-js/faker'; -import { AppId } from '@lens-protocol/domain/entities'; -import { Erc20 } from '@lens-protocol/shared-kernel'; - -import { Cursor } from '../Cursor'; -import { - Comment, - EnabledModuleCurrenciesData, - EnabledModuleCurrenciesDocument, - EnabledModules, - EnabledModulesData, - EnabledModulesDocument, - ExploreProfilesData, - ExploreProfilesDocument, - ExploreProfilesVariables, - ExplorePublicationsData, - ExplorePublicationsDocument, - ExplorePublicationsVariables, - FeedData, - FeedDocument, - FeedItem, - FeedVariables, - GetAllProfilesData, - GetAllProfilesDocument, - GetAllProfilesVariables, - GetProfileBookmarksData, - GetProfileBookmarksDocument, - GetProfileBookmarksVariables, - GetProfileData, - GetProfileDocument, - GetProfilePublicationRevenueData, - GetProfilePublicationRevenueDocument, - GetProfilePublicationRevenueVariables, - GetProfileVariables, - GetPublicationData, - GetPublicationDocument, - GetPublicationRevenueData, - GetPublicationRevenueDocument, - GetPublicationRevenueVariables, - GetPublicationsData, - GetPublicationsDocument, - GetPublicationsVariables, - GetPublicationVariables, - HasTxHashBeenIndexedData, - HasTxHashBeenIndexedDocument, - HasTxHashBeenIndexedVariables, - Maybe, - Mirror, - MutualFollowersProfilesData, - MutualFollowersProfilesDocument, - MutualFollowersProfilesVariables, - PaginatedResultInfo, - Post, - Profile, - ProfileFollowRevenue, - ProfileFollowRevenueData, - ProfileFollowRevenueDocument, - ProfileFollowRevenueVariables, - ProfilePublicationsForSaleData, - ProfilePublicationsForSaleDocument, - ProfilePublicationsForSaleVariables, - ProfilesToFollowData, - ProfilesToFollowDocument, - ProfilesToFollowVariables, - ProxyActionError, - ProxyActionStatusData, - ProxyActionStatusDocument, - ProxyActionStatusResult, - ProxyActionStatusTypes, - ProxyActionStatusVariables, - PublicationRevenue, - SearchProfilesDocument, - SearchProfilesVariables, - SearchPublicationsDocument, - SearchPublicationsVariables, - TransactionErrorReasons, - Wallet, - WhoCollectedPublicationData, - WhoCollectedPublicationDocument, - WhoCollectedPublicationVariables, - WhoReactedPublicationData, - WhoReactedPublicationDocument, - WhoReactedPublicationVariables, - WhoReactedResult, -} from '../generated'; -import { SearchProfilesData, SearchPublicationsData } from '../index'; -import { Sources } from '../sources'; -import { AnyPublication, ContentPublication } from '../utils/publication'; -import { - mockEnabledModulesFragment, - mockPaginatedResultInfo, - mockPostFragment, - mockProfileFragment, -} from './fragments'; - -export function mockSources(): Sources { - return ['foobar' as AppId]; -} - -export function mockCursor(): Cursor { - return faker.random.alphaNumeric(10) as Cursor; -} - -export function mockProfilesToFollowResponse({ - variables, - profiles, -}: { - variables: ProfilesToFollowVariables; - profiles: Profile[]; -}): MockedResponse { - return { - request: { - query: ProfilesToFollowDocument, - variables, - }, - result: { - data: { - result: profiles, - }, - }, - }; -} - -export function mockGetProfileResponse({ - variables, - profile = mockProfileFragment(), -}: { - variables: GetProfileVariables; - profile?: Maybe; -}): MockedResponse { - return { - request: { - query: GetProfileDocument, - variables, - }, - result: { - data: { - result: profile, - }, - }, - }; -} - -function mockGetAllProfilesData(profiles: Profile[]): GetAllProfilesData { - return { - result: { - items: profiles, - pageInfo: mockPaginatedResultInfo(), - }, - }; -} - -export function mockGetAllProfilesResponse({ - variables, - profiles = [mockProfileFragment()], -}: { - variables: GetAllProfilesVariables; - profiles?: Profile[]; -}): MockedResponse { - return { - request: { - query: GetAllProfilesDocument, - variables, - }, - result: { - data: mockGetAllProfilesData(profiles), - }, - }; -} - -export function mockHasTxHashBeenIndexedData( - result: { reason: TransactionErrorReasons } | { indexed: boolean; txHash: string }, -): HasTxHashBeenIndexedData { - return { - result: - 'reason' in result - ? { - __typename: 'TransactionError', - ...result, - } - : { - __typename: 'TransactionIndexedResult', - ...result, - }, - }; -} - -export function mockHasTxHashBeenIndexedResponse({ - variables, - data, -}: { - variables: HasTxHashBeenIndexedVariables; - data: HasTxHashBeenIndexedData; -}): MockedResponse { - return { - request: { - query: HasTxHashBeenIndexedDocument, - variables, - }, - result: { - data, - }, - }; -} - -function mockProxyActionError(overrides?: Partial): ProxyActionError { - return { - __typename: 'ProxyActionError', - reason: 'UNKNOWN', - lastKnownTxId: '0x123', - ...overrides, - }; -} - -function mockProxyActionStatusResult( - overrides?: Partial, -): ProxyActionStatusResult { - return { - txHash: '0x123', - txId: '1', - status: ProxyActionStatusTypes.Minting, - ...overrides, - __typename: 'ProxyActionStatusResult', - }; -} - -export function mockProxyActionStatusResponse(instructions: { - result: { reason: string; lastKnownTxId: string } | Partial; - variables: ProxyActionStatusVariables; -}): MockedResponse { - return { - request: { - query: ProxyActionStatusDocument, - variables: instructions.variables, - }, - result: { - data: { - result: - 'reason' in instructions.result - ? mockProxyActionError(instructions.result) - : mockProxyActionStatusResult(instructions.result), - }, - }, - }; -} - -export function mockEnabledModuleCurrenciesResponse( - currencies: Erc20[], -): MockedResponse { - return { - request: { - query: EnabledModuleCurrenciesDocument, - }, - result: { - data: { - result: currencies.map((currency) => ({ - __typename: 'Erc20', - address: currency.address, - decimals: currency.decimals, - name: currency.name, - symbol: currency.symbol, - })), - }, - }, - }; -} - -export function mockWhoCollectedPublicationResponse(args: { - variables: WhoCollectedPublicationVariables; - wallets: Wallet[]; -}): MockedResponse { - return { - request: { - query: WhoCollectedPublicationDocument, - variables: args.variables, - }, - result: { - data: { - result: { - items: args.wallets, - pageInfo: mockPaginatedResultInfo({ totalCount: args.wallets.length }), - }, - }, - }, - }; -} - -export function mockMutualFollowersResponse(args: { - variables: MutualFollowersProfilesVariables; - profiles: Profile[]; -}): MockedResponse { - return { - request: { - query: MutualFollowersProfilesDocument, - variables: args.variables, - }, - result: { - data: { - result: { - items: args.profiles, - pageInfo: mockPaginatedResultInfo({ totalCount: args.profiles.length }), - }, - }, - }, - }; -} - -export function mockGetPublicationsResponse({ - variables, - publications, - info = mockPaginatedResultInfo(), -}: { - variables: GetPublicationsVariables; - publications: Array; - info?: PaginatedResultInfo; -}): MockedResponse { - return { - request: { - query: GetPublicationsDocument, - variables: variables, - }, - result: { - data: { - result: { - items: publications, - pageInfo: info, - }, - }, - }, - }; -} - -export function mockFeedResponse(args: { - variables: FeedVariables; - items: FeedItem[]; -}): MockedResponse { - return { - request: { - query: FeedDocument, - variables: args.variables, - }, - result: { - data: { - result: { - items: args.items, - pageInfo: mockPaginatedResultInfo({ totalCount: args.items.length }), - }, - }, - }, - }; -} - -export function mockExplorePublicationsResponse(args: { - variables: ExplorePublicationsVariables; - items: Array; -}): MockedResponse { - return { - request: { - query: ExplorePublicationsDocument, - variables: args.variables, - }, - result: { - data: { - result: { - items: args.items, - pageInfo: mockPaginatedResultInfo({ totalCount: args.items.length }), - }, - }, - }, - }; -} - -export function mockGetPublicationRevenueResponse(args: { - variables: GetPublicationRevenueVariables; - revenue: PublicationRevenue | null; -}): MockedResponse { - return { - request: { - query: GetPublicationRevenueDocument, - variables: args.variables, - }, - result: { - data: { - result: args.revenue, - }, - }, - }; -} - -export function mockGetProfilePublicationRevenueResponse(args: { - variables: GetProfilePublicationRevenueVariables; - items: PublicationRevenue[]; -}): MockedResponse { - return { - request: { - query: GetProfilePublicationRevenueDocument, - variables: args.variables, - }, - result: { - data: { - result: { - items: args.items, - pageInfo: mockPaginatedResultInfo({ totalCount: args.items.length }), - }, - }, - }, - }; -} - -export function mockProfilePublicationsForSaleResponse(args: { - variables: ProfilePublicationsForSaleVariables; - items: ContentPublication[]; -}): MockedResponse { - return { - request: { - query: ProfilePublicationsForSaleDocument, - variables: args.variables, - }, - result: { - data: { - result: { - items: args.items, - pageInfo: mockPaginatedResultInfo({ totalCount: args.items.length }), - }, - }, - }, - }; -} - -export function mockWhoReactedPublicationResponse(args: { - variables: WhoReactedPublicationVariables; - items: Array; -}): MockedResponse { - return { - request: { - query: WhoReactedPublicationDocument, - variables: args.variables, - }, - result: { - data: { - result: { - items: args.items, - pageInfo: mockPaginatedResultInfo({ totalCount: args.items.length }), - }, - }, - }, - }; -} - -export function mockProfileFollowRevenueResponse({ - variables, - revenues, -}: { - variables: ProfileFollowRevenueVariables; - revenues: ProfileFollowRevenue; -}): MockedResponse { - return { - request: { - query: ProfileFollowRevenueDocument, - variables, - }, - result: { - data: { - result: revenues, - }, - }, - }; -} - -export function mockSearchProfilesResponse(args: { - variables: SearchProfilesVariables; - items: Profile[]; -}): MockedResponse { - return { - request: { - query: SearchProfilesDocument, - variables: args.variables, - }, - result: { - data: { - result: { - __typename: 'ProfileSearchResult', - items: args.items, - pageInfo: mockPaginatedResultInfo({ totalCount: args.items.length }), - }, - }, - }, - }; -} - -export function mockExploreProfilesResponse(args: { - variables: ExploreProfilesVariables; - items: Array; -}): MockedResponse { - return { - request: { - query: ExploreProfilesDocument, - variables: args.variables, - }, - result: { - data: { - result: { - items: args.items, - pageInfo: mockPaginatedResultInfo({ totalCount: args.items.length }), - }, - }, - }, - }; -} - -export function mockSearchPublicationsResponse(args: { - variables: SearchPublicationsVariables; - items: Array; -}): MockedResponse { - return { - request: { - query: SearchPublicationsDocument, - variables: args.variables, - }, - result: { - data: { - result: { - __typename: 'PublicationSearchResult', - items: args.items, - pageInfo: mockPaginatedResultInfo({ totalCount: args.items.length }), - }, - }, - }, - }; -} - -function mockGetPublicationData( - publication: AnyPublication | null = mockPostFragment(), -): GetPublicationData { - return { - result: publication, - }; -} - -export function mockGetPublicationResponse({ - variables, - publication, -}: { - variables: GetPublicationVariables; - publication: AnyPublication | null; -}): MockedResponse { - return { - request: { - query: GetPublicationDocument, - variables, - }, - result: { - data: mockGetPublicationData(publication), - }, - }; -} - -export function mockEnabledModulesResponse({ - data = mockEnabledModulesFragment(), -}: { - data?: EnabledModules; -} = {}): MockedResponse { - return { - request: { - query: EnabledModulesDocument, - }, - result: { - data: { - result: data, - }, - }, - }; -} - -export function mockGetProfileBookmarksResponse({ - variables, - publications, -}: { - variables: GetProfileBookmarksVariables; - publications: ContentPublication[]; -}): MockedResponse { - return { - request: { - query: GetProfileBookmarksDocument, - variables, - }, - result: { - data: { - result: { - items: publications, - pageInfo: mockPaginatedResultInfo(), - }, - }, - }, - }; -} diff --git a/packages/api-bindings-v1/src/lens/auth.graphql b/packages/api-bindings-v1/src/lens/auth.graphql deleted file mode 100644 index 464b3f1d3d..0000000000 --- a/packages/api-bindings-v1/src/lens/auth.graphql +++ /dev/null @@ -1,19 +0,0 @@ -query AuthChallenge($address: EthereumAddress!) { - result: challenge(request: { address: $address }) { - text - } -} - -mutation AuthAuthenticate($address: EthereumAddress!, $signature: Signature!) { - result: authenticate(request: { address: $address, signature: $signature }) { - accessToken - refreshToken - } -} - -mutation AuthRefresh($refreshToken: Jwt!) { - result: refresh(request: { refreshToken: $refreshToken }) { - accessToken - refreshToken - } -} diff --git a/packages/api-bindings-v1/src/lens/client.graphql b/packages/api-bindings-v1/src/lens/client.graphql deleted file mode 100644 index f1d7e20cdb..0000000000 --- a/packages/api-bindings-v1/src/lens/client.graphql +++ /dev/null @@ -1,76 +0,0 @@ -scalar ClientErc20Amount -scalar ProfileAttributes -scalar FollowPolicy -scalar CollectPolicy -scalar ReferencePolicy -scalar FollowStatus -scalar DecryptionCriteria -scalar PendingPublicationId -scalar ContentInsight - -extend type Profile { - ownedByMe: Boolean! - attributesMap: ProfileAttributes! - followPolicy: FollowPolicy! - followStatus: FollowStatus - observedBy: ProfileId -} - -extend type Post { - """ - @deprecated use `hasCollectedByMe` instead - """ - hasOptimisticCollectedByMe: Boolean! - """ - @deprecated use `isMirroredByMe` instead - """ - isOptimisticMirroredByMe: Boolean! - isMirroredByMe: Boolean! - collectPolicy: CollectPolicy! - referencePolicy: ReferencePolicy! - - contentInsight: ContentInsight! - observedBy: ProfileId -} - -extend type Comment { - """ - @deprecated use `hasCollectedByMe` instead - """ - hasOptimisticCollectedByMe: Boolean! - """ - @deprecated use `isMirroredByMe` instead - """ - isOptimisticMirroredByMe: Boolean! - isMirroredByMe: Boolean! - collectPolicy: CollectPolicy! - referencePolicy: ReferencePolicy! - - contentInsight: ContentInsight! - observedBy: ProfileId -} - -type PendingPost { - id: PendingPublicationId! - content: String - media: [Media!] - profile: Profile! - locale: Locale! - mainContentFocus: PublicationMainFocus! -} - -extend type RevenueAggregate { - totalAmount: ClientErc20Amount! -} - -extend type Post { - decryptionCriteria: DecryptionCriteria -} - -extend type Comment { - decryptionCriteria: DecryptionCriteria -} - -extend type PaginatedResultInfo { - moreAfter: Boolean! -} diff --git a/packages/api-bindings-v1/src/lens/collect-typed-data.graphql b/packages/api-bindings-v1/src/lens/collect-typed-data.graphql deleted file mode 100644 index b032123963..0000000000 --- a/packages/api-bindings-v1/src/lens/collect-typed-data.graphql +++ /dev/null @@ -1,24 +0,0 @@ -mutation CreateCollectTypedData($request: CreateCollectRequest!, $options: TypedDataOptions) { - result: createCollectTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - CollectWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - profileId - pubId - data - } - } - } -} diff --git a/packages/api-bindings-v1/src/lens/comment.graphql b/packages/api-bindings-v1/src/lens/comment.graphql deleted file mode 100644 index 800f88591e..0000000000 --- a/packages/api-bindings-v1/src/lens/comment.graphql +++ /dev/null @@ -1,58 +0,0 @@ -fragment CreateCommentEIP712TypedData on CreateCommentEIP712TypedData { - types { - CommentWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - profileId - contentURI - profileIdPointed - pubIdPointed - collectModule - collectModuleInitData - referenceModuleData - referenceModule - referenceModuleInitData - } -} - -mutation CreateCommentTypedData($request: CreatePublicCommentRequest!, $options: TypedDataOptions) { - result: createCommentTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - ...CreateCommentEIP712TypedData - } - } -} - -mutation CreateCommentViaDispatcher($request: CreatePublicCommentRequest!) { - result: createCommentViaDispatcher(request: $request) { - ...BroadcastOnChainResult - } -} - -mutation CreateDataAvailabilityCommentTypedData($request: CreateDataAvailabilityCommentRequest!) { - result: createDataAvailabilityCommentTypedData(request: $request) { - id - expiresAt - typedData { - ...CreateCommentEIP712TypedData - } - } -} - -mutation CreateDataAvailabilityCommentViaDispatcher( - $request: CreateDataAvailabilityCommentRequest! -) { - result: createDataAvailabilityCommentViaDispatcher(request: $request) { - ...BroadcastOffChainResult - } -} diff --git a/packages/api-bindings-v1/src/lens/common.graphql b/packages/api-bindings-v1/src/lens/common.graphql deleted file mode 100644 index 208a69b079..0000000000 --- a/packages/api-bindings-v1/src/lens/common.graphql +++ /dev/null @@ -1,610 +0,0 @@ -fragment Erc20Fields on Erc20 { - __typename - name - symbol - decimals - address -} - -fragment Erc20AmountFields on Erc20Amount { - __typename - asset { - ...Erc20Fields - } - value -} - -fragment ModuleFeeAmount on ModuleFeeAmount { - __typename - asset { - ...Erc20Fields - } - value -} - -fragment AaveFeeCollectModuleSettings on AaveFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimitOptional: collectLimit - contractAddress - followerOnly - endTimestampOptional: endTimestamp - recipient - referralFee -} - -fragment Erc4626FeeCollectModuleSettings on ERC4626FeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimitOptional: collectLimit - contractAddress - followerOnly - endTimestampOptional: endTimestamp - recipient - referralFee - vault -} - -fragment MultirecipientFeeCollectModuleSettings on MultirecipientFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimitOptional: collectLimit - contractAddress - followerOnly - endTimestampOptional: endTimestamp - recipients { - recipient - split - } - referralFee -} - -fragment UnknownCollectModuleSettings on UnknownCollectModuleSettings { - __typename - contractAddress - collectModuleReturnData -} - -fragment FreeCollectModuleSettings on FreeCollectModuleSettings { - __typename - contractAddress - followerOnly -} - -fragment FeeCollectModuleSettings on FeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - contractAddress - followerOnly - recipient - referralFee -} - -fragment LimitedFeeCollectModuleSettings on LimitedFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimit - contractAddress - followerOnly - recipient - referralFee -} - -fragment LimitedTimedFeeCollectModuleSettings on LimitedTimedFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimit - contractAddress - followerOnly - endTimestamp - recipient - referralFee -} - -fragment MultirecipientFeeCollectModuleSettings on MultirecipientFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimitOptional: collectLimit - contractAddress - followerOnly - endTimestampOptional: endTimestamp - recipients { - recipient - split - } - referralFee -} - -fragment Erc4626FeeCollectModuleSettings on ERC4626FeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimitOptional: collectLimit - contractAddress - followerOnly - endTimestampOptional: endTimestamp - recipient - referralFee - vault -} - -fragment AaveFeeCollectModuleSettings on AaveFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimitOptional: collectLimit - contractAddress - followerOnly - endTimestampOptional: endTimestamp - recipient - referralFee -} - -fragment RevertCollectModuleSettings on RevertCollectModuleSettings { - __typename - contractAddress -} - -fragment TimedFeeCollectModuleSettings on TimedFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - contractAddress - followerOnly - endTimestamp - recipient - referralFee -} - -fragment SimpleCollectModuleSettings on SimpleCollectModuleSettings { - __typename - contractAddress - followerOnly - feeOptional: fee { - amount { - ...ModuleFeeAmount - } - referralFee - recipient - } - collectLimitOptional: collectLimit - endTimestampOptional: endTimestamp -} - -fragment Wallet on Wallet { - __typename - address - defaultProfile { - ...Profile - } -} - -fragment Media on Media { - __typename - altTag - cover - mimeType - url -} - -fragment PublicationMediaSet on MediaSet { - __typename - original { - ...Media - } - optimized { - ...Media - } - small: transformed(params: $mediaTransformPublicationSmall) { - ...Media - } - medium: transformed(params: $mediaTransformPublicationMedium) { - ...Media - } -} - -fragment ProfilePictureSet on MediaSet { - __typename - original { - ...Media - } - optimized { - ...Media - } - thumbnail: transformed(params: $mediaTransformProfileThumbnail) { - ...Media - } -} - -fragment ProfileCoverSet on MediaSet { - __typename - original { - ...Media - } - optimized { - ...Media - } -} - -fragment MetadataOutput on MetadataOutput { - __typename - animatedUrl - content - contentWarning - description - image - locale - mainContentFocus - name - media { - ...PublicationMediaSet - } - attributes { - ...MetadataAttributeOutput - } - encryptionParams { - ...EncryptionParamsOutput - } - tags -} - -fragment MetadataAttributeOutput on MetadataAttributeOutput { - __typename - traitType - value -} - -fragment PublicationStats on PublicationStats { - __typename - totalAmountOfMirrors - totalUpvotes - totalDownvotes - totalAmountOfCollects - totalAmountOfComments - totalBookmarks - commentsCount: commentsTotal(forSources: $sources) -} - -fragment MirrorBase on Mirror { - __typename - id - createdAt - profile { - ...Profile - } - hidden # this is currently used by HidePublication use case, keeping it for now -} - -fragment Mirror on Mirror { - __typename - ...MirrorBase - mirrorOf { - ... on Post { - ...Post - } - - ... on Comment { - ...Comment - } - } -} - -fragment FollowOnlyReferenceModuleSettings on FollowOnlyReferenceModuleSettings { - __typename - contractAddress -} - -fragment DegreesOfSeparationReferenceModuleSettings on DegreesOfSeparationReferenceModuleSettings { - __typename - contractAddress - commentsRestricted - degreesOfSeparation - mirrorsRestricted -} - -fragment UnknownReferenceModuleSettings on UnknownReferenceModuleSettings { - __typename - contractAddress - referenceModuleReturnData -} - -fragment CommentBase on Comment { - __typename - id - appId - stats { - ...PublicationStats - } - metadata { - ...MetadataOutput - } - profile { - ...Profile - } - collectedBy { - ...Wallet - } - collectModule { - ... on AaveFeeCollectModuleSettings { - ...AaveFeeCollectModuleSettings - } - - ... on ERC4626FeeCollectModuleSettings { - ...Erc4626FeeCollectModuleSettings - } - - ... on MultirecipientFeeCollectModuleSettings { - ...MultirecipientFeeCollectModuleSettings - } - - ... on UnknownCollectModuleSettings { - ...UnknownCollectModuleSettings - } - - ... on FreeCollectModuleSettings { - ...FreeCollectModuleSettings - } - - ... on FeeCollectModuleSettings { - ...FeeCollectModuleSettings - } - - ... on LimitedFeeCollectModuleSettings { - ...LimitedFeeCollectModuleSettings - } - - ... on LimitedTimedFeeCollectModuleSettings { - ...LimitedTimedFeeCollectModuleSettings - } - - ... on RevertCollectModuleSettings { - ...RevertCollectModuleSettings - } - - ... on TimedFeeCollectModuleSettings { - ...TimedFeeCollectModuleSettings - } - - ... on SimpleCollectModuleSettings { - ...SimpleCollectModuleSettings - } - } - collectNftAddress - referenceModule { - ... on FollowOnlyReferenceModuleSettings { - ...FollowOnlyReferenceModuleSettings - } - - ... on DegreesOfSeparationReferenceModuleSettings { - ...DegreesOfSeparationReferenceModuleSettings - } - - ... on UnknownReferenceModuleSettings { - ...UnknownReferenceModuleSettings - } - } - createdAt - hidden - isGated - reaction(request: { profileId: $observerId }) - hasCollectedByMe - canComment(profileId: $observerId) { - result - } - canMirror(profileId: $observerId) { - result - } - canObserverDecrypt: canDecrypt(profileId: $observerId) { - result - reasons - } - mirrors(by: $observerId) - notInterested(by: $observerId) - bookmarked(by: $observerId) - - hasOptimisticCollectedByMe @client - isOptimisticMirroredByMe @client - isMirroredByMe @client - collectPolicy @client - referencePolicy @client - decryptionCriteria @client - contentInsight @client - observedBy @client -} - -fragment PaginatedResultInfo on PaginatedResultInfo { - __typename - moreAfter @client - prev - next - totalCount -} - -fragment Comment on Comment { - __typename - ...CommentBase - commentOn { - ... on Post { - ...Post - } - - # we do not want to promote comments on mirrors, should we remove this? - ... on Mirror { - ...MirrorBase - } - - ... on Comment { - ...CommentBase - } - } - mainPost { - ... on Post { - ...Post - } - - # we do not want to promote comments on mirrors, should we remove this? - ... on Mirror { - ...MirrorBase - } - } - firstComment { - ...CommentBase - } -} - -fragment Post on Post { - __typename - id - appId - stats { - ...PublicationStats - } - metadata { - ...MetadataOutput - } - profile { - ...Profile - } - collectedBy { - ...Wallet - } - collectModule { - ... on AaveFeeCollectModuleSettings { - ...AaveFeeCollectModuleSettings - } - - ... on ERC4626FeeCollectModuleSettings { - ...Erc4626FeeCollectModuleSettings - } - - ... on MultirecipientFeeCollectModuleSettings { - ...MultirecipientFeeCollectModuleSettings - } - - ... on UnknownCollectModuleSettings { - ...UnknownCollectModuleSettings - } - - ... on FreeCollectModuleSettings { - ...FreeCollectModuleSettings - } - - ... on FeeCollectModuleSettings { - ...FeeCollectModuleSettings - } - - ... on LimitedFeeCollectModuleSettings { - ...LimitedFeeCollectModuleSettings - } - - ... on LimitedTimedFeeCollectModuleSettings { - ...LimitedTimedFeeCollectModuleSettings - } - - ... on RevertCollectModuleSettings { - ...RevertCollectModuleSettings - } - - ... on TimedFeeCollectModuleSettings { - ...TimedFeeCollectModuleSettings - } - - ... on SimpleCollectModuleSettings { - ...SimpleCollectModuleSettings - } - } - collectNftAddress - referenceModule { - ... on FollowOnlyReferenceModuleSettings { - ...FollowOnlyReferenceModuleSettings - } - - ... on DegreesOfSeparationReferenceModuleSettings { - ...DegreesOfSeparationReferenceModuleSettings - } - - ... on UnknownReferenceModuleSettings { - ...UnknownReferenceModuleSettings - } - } - createdAt - hidden - isGated - reaction(request: { profileId: $observerId }) - hasCollectedByMe - canComment(profileId: $observerId) { - result - } - canMirror(profileId: $observerId) { - result - } - canObserverDecrypt: canDecrypt(profileId: $observerId) { - result - reasons - } - mirrors(by: $observerId) - notInterested(by: $observerId) - bookmarked(by: $observerId) - - hasOptimisticCollectedByMe @client - isOptimisticMirroredByMe @client - isMirroredByMe @client - collectPolicy @client - referencePolicy @client - decryptionCriteria @client - contentInsight @client - observedBy @client -} - -fragment Publication on Publication { - ... on Comment { - ...Comment - } - - ... on Post { - ...Post - } - - ... on Mirror { - ...Mirror - } -} - -fragment PendingPost on PendingPost { - __typename - id - content - media { - ...Media - } - profile { - ...Profile - } - locale - mainContentFocus -} - -fragment EIP712TypedDataDomain on EIP712TypedDataDomain { - __typename - name - chainId - version - verifyingContract -} diff --git a/packages/api-bindings-v1/src/lens/currencies.graphql b/packages/api-bindings-v1/src/lens/currencies.graphql deleted file mode 100644 index 1078b3d8b0..0000000000 --- a/packages/api-bindings-v1/src/lens/currencies.graphql +++ /dev/null @@ -1,5 +0,0 @@ -query EnabledModuleCurrencies { - result: enabledModuleCurrencies { - ...Erc20Fields - } -} diff --git a/packages/api-bindings-v1/src/lens/feed.graphql b/packages/api-bindings-v1/src/lens/feed.graphql deleted file mode 100644 index bbf5b3bec0..0000000000 --- a/packages/api-bindings-v1/src/lens/feed.graphql +++ /dev/null @@ -1,113 +0,0 @@ -fragment ElectedMirror on ElectedMirror { - __typename - mirrorId - profile { - ...Profile - } - timestamp -} - -fragment MirrorEvent on MirrorEvent { - __typename - profile { - ...Profile - } - timestamp -} - -fragment CollectedEvent on CollectedEvent { - __typename - profile { - ...Profile - } - timestamp -} - -fragment ReactionEvent on ReactionEvent { - __typename - profile { - ...Profile - } - reaction - timestamp -} - -fragment FeedItem on FeedItem { - __typename - root { - ... on Post { - ...Post - } - - ... on Comment { - ...Comment - } - } - comments { - ...Comment - } - electedMirror { - ...ElectedMirror - } - mirrors { - ...MirrorEvent - } - collects { - ...CollectedEvent - } - reactions { - ...ReactionEvent - } -} - -query Feed( - $profileId: ProfileId! - $restrictEventTypesTo: [FeedEventItemType!] - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!]! - $metadata: PublicationMetadataFilters - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: feed( - request: { - profileId: $profileId - feedEventItemTypes: $restrictEventTypesTo - limit: $limit - cursor: $cursor - sources: $sources - metadata: $metadata - } - ) { - items { - ...FeedItem - } - - pageInfo { - ...PaginatedResultInfo - } - } -} - -query ExploreProfiles( - $sortCriteria: ProfileSortCriteria! - $limit: LimitScalar - $cursor: Cursor - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: exploreProfiles( - request: { limit: $limit, cursor: $cursor, sortCriteria: $sortCriteria } - ) { - items { - ...Profile - } - pageInfo { - ...PaginatedResultInfo - } - } -} diff --git a/packages/api-bindings-v1/src/lens/follow-typed-data.graphql b/packages/api-bindings-v1/src/lens/follow-typed-data.graphql deleted file mode 100644 index 67b954160c..0000000000 --- a/packages/api-bindings-v1/src/lens/follow-typed-data.graphql +++ /dev/null @@ -1,23 +0,0 @@ -mutation CreateFollowTypedData($request: FollowRequest!, $options: TypedDataOptions) { - result: createFollowTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - FollowWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - profileIds - datas - } - } - } -} diff --git a/packages/api-bindings-v1/src/lens/gated.graphql b/packages/api-bindings-v1/src/lens/gated.graphql deleted file mode 100644 index ff6d7d7501..0000000000 --- a/packages/api-bindings-v1/src/lens/gated.graphql +++ /dev/null @@ -1,143 +0,0 @@ -fragment NftOwnershipOutput on NftOwnershipOutput { - __typename - contractAddress - chainID - contractType - tokenIds -} - -fragment Erc20OwnershipOutput on Erc20OwnershipOutput { - __typename - amount - chainID - condition - contractAddress - decimals - name - symbol -} - -fragment EoaOwnershipOutput on EoaOwnershipOutput { - __typename - address -} - -fragment ProfileOwnershipOutput on ProfileOwnershipOutput { - __typename - profileId -} - -fragment FollowConditionOutput on FollowConditionOutput { - __typename - profileId -} - -fragment CollectConditionOutput on CollectConditionOutput { - __typename - publicationId - thisPublication -} - -fragment LeafConditionOutput on AccessConditionOutput { - __typename - nft { - ...NftOwnershipOutput - } - - token { - ...Erc20OwnershipOutput - } - - eoa { - ...EoaOwnershipOutput - } - - profile { - ...ProfileOwnershipOutput - } - - follow { - ...FollowConditionOutput - } - - collect { - ...CollectConditionOutput - } -} - -fragment OrConditionOutput on OrConditionOutput { - __typename - criteria { - ...LeafConditionOutput - } -} -fragment AndConditionOutput on AndConditionOutput { - __typename - criteria { - ...LeafConditionOutput - } -} - -fragment AnyConditionOutput on AccessConditionOutput { - __typename - ...LeafConditionOutput - - or { - ...OrConditionOutput - } - - and { - ...AndConditionOutput - } -} - -fragment RootConditionOutput on AccessConditionOutput { - __typename - or { - criteria { - ...AnyConditionOutput - } - } -} - -fragment EncryptedMedia on EncryptedMedia { - __typename - altTag - cover - mimeType - url -} - -fragment EncryptedMediaSet on EncryptedMediaSet { - __typename - original { - ...EncryptedMedia - } -} - -fragment EncryptedFieldsOutput on EncryptedFieldsOutput { - __typename - animation_url - content - external_url - image - media { - original { - ...EncryptedMedia - } - } -} - -fragment EncryptionParamsOutput on EncryptionParamsOutput { - __typename - accessCondition { - ...RootConditionOutput - } - encryptionProvider - encryptedFields { - ...EncryptedFieldsOutput - } - providerSpecificParams { - encryptionKey - } -} diff --git a/packages/api-bindings-v1/src/lens/generated.ts b/packages/api-bindings-v1/src/lens/generated.ts deleted file mode 100644 index af700b524a..0000000000 --- a/packages/api-bindings-v1/src/lens/generated.ts +++ /dev/null @@ -1,12696 +0,0 @@ -/** Code generated. DO NOT EDIT. */ -/* eslint-disable import/no-default-export */ -/* eslint-disable @typescript-eslint/ban-types */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/naming-convention */ -/* eslint-disable no-restricted-imports */ -/* eslint-disable tsdoc/syntax */ -import * as Apollo from '@apollo/client'; -import { FieldPolicy, FieldReadFunction, TypePolicies, TypePolicy } from '@apollo/client/cache'; -import type { - AppId, - DecryptionCriteria, - ProfileId, - PublicationId, -} from '@lens-protocol/domain/entities'; -import type { - Erc20Amount as ClientErc20Amount, - EthereumAddress, - Url, -} from '@lens-protocol/shared-kernel'; -import gql from 'graphql-tag'; - -import type { CollectPolicy } from './CollectPolicy'; -import type { ContentEncryptionKey } from './ContentEncryptionKey'; -import type { ContentInsight } from './ContentInsight'; -import type { Cursor } from './Cursor'; -import type { FollowPolicy } from './FollowPolicy'; -import type { FollowStatus } from './FollowStatus'; -import type { ImageSizeTransform } from './ImageSizeTransform'; -import type { ProfileAttributes } from './ProfileAttributes'; -import type { ReferencePolicy } from './ReferencePolicy'; - -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -const defaultOptions = {} as const; -/** All built-in and custom scalars, mapped to their actual values */ -export type Scalars = { - ID: string; - String: string; - Boolean: boolean; - Int: number; - Float: number; - /** Blockchain data scalar type */ - BlockchainData: string; - /** Broadcast scalar id type */ - BroadcastId: string; - /** ChainId custom scalar type */ - ChainId: number; - ClientErc20Amount: ClientErc20Amount; - /** collect module data scalar type */ - CollectModuleData: string; - CollectPolicy: CollectPolicy; - /** ContentEncryptionKey scalar type */ - ContentEncryptionKey: ContentEncryptionKey; - ContentInsight: ContentInsight; - /** Contract address custom scalar type */ - ContractAddress: string; - /** create handle custom scalar type */ - CreateHandle: unknown; - /** Cursor custom scalar type */ - Cursor: Cursor; - /** The da id */ - DataAvailabilityId: string; - /** The javascript `Date` as string. Type represents date and time as the ISO Date string. */ - DateTime: string; - DecryptionCriteria: DecryptionCriteria; - /** EncryptedValue custom scalar type */ - EncryptedValueScalar: string; - /** Ens custom scalar type */ - Ens: unknown; - /** Ethereum address custom scalar type */ - EthereumAddress: EthereumAddress; - /** follow module data scalar type */ - FollowModuleData: string; - FollowPolicy: FollowPolicy; - FollowStatus: FollowStatus; - /** handle custom scalar type */ - Handle: string; - /** handle claim id custom scalar type */ - HandleClaimIdScalar: unknown; - /** image size transform custom scalar type */ - ImageSizeTransform: ImageSizeTransform; - /** Internal publication id custom scalar type */ - InternalPublicationId: PublicationId; - /** IpfsCid scalar type */ - IpfsCid: unknown; - /** jwt custom scalar type */ - Jwt: string; - /** limit custom scalar type */ - LimitScalar: number; - /** Locale scalar type */ - Locale: string; - /** Markdown scalar type */ - Markdown: string; - /** mimetype custom scalar type */ - MimeType: string; - /** Nft gallery id type */ - NftGalleryId: unknown; - /** Nft gallery name type */ - NftGalleryName: unknown; - /** Nft ownership id type */ - NftOwnershipId: string; - /** Nonce custom scalar type */ - Nonce: number; - /** The notification id */ - NotificationId: string; - PendingPublicationId: string; - ProfileAttributes: ProfileAttributes; - /** ProfileId custom scalar type */ - ProfileId: ProfileId; - /** ProfileInterest custom scalar type */ - ProfileInterest: string; - /** proxy action scalar id type */ - ProxyActionId: string; - /** Publication id custom scalar type */ - PublicationId: string; - /** The publication tag */ - PublicationTag: unknown; - /** Publication url scalar type */ - PublicationUrl: Url; - /** The reaction id */ - ReactionId: unknown; - /** reference module data scalar type */ - ReferenceModuleData: string; - ReferencePolicy: ReferencePolicy; - /** Query search */ - Search: string; - /** Relayer signature */ - Signature: string; - /** Sources custom scalar type */ - Sources: AppId; - /** timestamp date custom scalar type */ - TimestampScalar: unknown; - /** The NFT token id */ - TokenId: string; - /** The tx hash */ - TxHash: string; - /** The tx id */ - TxId: string; - /** UnixTimestamp custom scalar type */ - UnixTimestamp: unknown; - /** Url scalar type */ - Url: Url; - /** Represents NULL values */ - Void: void; -}; - -export type AaveFeeCollectModuleParams = { - /** The collect module amount info */ - amount: ModuleFeeAmountParams; - /** The collect module limit */ - collectLimit?: InputMaybe; - /** The timestamp that this collect module will expire */ - endTimestamp?: InputMaybe; - /** Follower only */ - followerOnly: Scalars['Boolean']; - /** The collect module recipient address */ - recipient: Scalars['EthereumAddress']; - /** The collect module referral fee */ - referralFee: Scalars['Float']; -}; - -/** The access conditions for the publication */ -export type AccessConditionInput = { - /** AND condition */ - and?: InputMaybe; - /** Profile follow condition */ - collect?: InputMaybe; - /** EOA ownership condition */ - eoa?: InputMaybe; - /** Profile follow condition */ - follow?: InputMaybe; - /** NFT ownership condition */ - nft?: InputMaybe; - /** OR condition */ - or?: InputMaybe; - /** Profile ownership condition */ - profile?: InputMaybe; - /** ERC20 token ownership condition */ - token?: InputMaybe; -}; - -export type AchRequest = { - ethereumAddress: Scalars['EthereumAddress']; - freeTextHandle?: InputMaybe; - handle?: InputMaybe; - overrideAlreadyClaimed: Scalars['Boolean']; - overrideTradeMark: Scalars['Boolean']; - secret: Scalars['String']; -}; - -/** The request object to add interests to a profile */ -export type AddProfileInterestsRequest = { - /** The profile interest to add */ - interests: Array; - /** The profileId to add interests to */ - profileId: Scalars['ProfileId']; -}; - -export type AllPublicationsTagsRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; - sort: TagSortCriteria; - /** The App Id */ - source?: InputMaybe; -}; - -export type AlreadyInvitedCheckRequest = { - address: Scalars['EthereumAddress']; -}; - -export type AndConditionInput = { - /** The list of conditions to apply AND to. You can only use nested boolean conditions at the root level. */ - criteria: Array; -}; - -export type ApprovedModuleAllowanceAmountRequest = { - collectModules?: InputMaybe>; - /** The contract addresses for the module approved currencies you want to find information on about the user */ - currencies: Array; - followModules?: InputMaybe>; - referenceModules?: InputMaybe>; - unknownCollectModules?: InputMaybe>; - unknownFollowModules?: InputMaybe>; - unknownReferenceModules?: InputMaybe>; -}; - -export type BroadcastRequest = { - id: Scalars['BroadcastId']; - signature: Scalars['Signature']; -}; - -export type BurnProfileRequest = { - profileId: Scalars['ProfileId']; -}; - -/** The challenge request */ -export type ChallengeRequest = { - /** The ethereum address you want to login with */ - address: Scalars['EthereumAddress']; -}; - -export type ClaimHandleRequest = { - /** The follow module */ - followModule?: InputMaybe; - freeTextHandle?: InputMaybe; - id?: InputMaybe; -}; - -/** The claim status */ -export enum ClaimStatus { - AlreadyClaimed = 'ALREADY_CLAIMED', - ClaimFailed = 'CLAIM_FAILED', - NotClaimed = 'NOT_CLAIMED', -} - -/** Condition that signifies if address or profile has collected a publication */ -export type CollectConditionInput = { - /** The publication id that has to be collected to unlock content */ - publicationId?: InputMaybe; - /** True if the content will be unlocked for this specific publication */ - thisPublication?: InputMaybe; -}; - -export type CollectModuleParams = { - /** The collect aave fee collect module */ - aaveFeeCollectModule?: InputMaybe; - /** The collect ERC4626 fee collect module */ - erc4626FeeCollectModule?: InputMaybe; - /** The collect fee collect module */ - feeCollectModule?: InputMaybe; - /** The collect empty collect module */ - freeCollectModule?: InputMaybe; - /** The collect limited fee collect module */ - limitedFeeCollectModule?: InputMaybe; - /** The collect limited timed fee collect module */ - limitedTimedFeeCollectModule?: InputMaybe; - /** The multirecipient fee collect module */ - multirecipientFeeCollectModule?: InputMaybe; - /** The collect revert collect module */ - revertCollectModule?: InputMaybe; - /** The collect simple fee collect module */ - simpleCollectModule?: InputMaybe; - /** The collect timed fee collect module */ - timedFeeCollectModule?: InputMaybe; - /** A unknown collect module */ - unknownCollectModule?: InputMaybe; -}; - -/** The collect module types */ -export enum CollectModules { - AaveFeeCollectModule = 'AaveFeeCollectModule', - Erc4626FeeCollectModule = 'ERC4626FeeCollectModule', - FeeCollectModule = 'FeeCollectModule', - FreeCollectModule = 'FreeCollectModule', - LimitedFeeCollectModule = 'LimitedFeeCollectModule', - LimitedTimedFeeCollectModule = 'LimitedTimedFeeCollectModule', - MultirecipientFeeCollectModule = 'MultirecipientFeeCollectModule', - RevertCollectModule = 'RevertCollectModule', - SimpleCollectModule = 'SimpleCollectModule', - TimedFeeCollectModule = 'TimedFeeCollectModule', - UnknownCollectModule = 'UnknownCollectModule', -} - -export type CollectProxyAction = { - freeCollect?: InputMaybe; -}; - -/** The comment ordering types */ -export enum CommentOrderingTypes { - Desc = 'DESC', - Ranking = 'RANKING', -} - -/** The comment ranking filter types */ -export enum CommentRankingFilter { - NoneRelevant = 'NONE_RELEVANT', - Relevant = 'RELEVANT', -} - -/** The gated publication access criteria contract types */ -export enum ContractType { - Erc20 = 'ERC20', - Erc721 = 'ERC721', - Erc1155 = 'ERC1155', -} - -export type CreateCollectRequest = { - publicationId: Scalars['InternalPublicationId']; - /** The encoded data to collect with if using an unknown module */ - unknownModuleData?: InputMaybe; -}; - -export type CreateDataAvailabilityCommentRequest = { - /** Publication your commenting on */ - commentOn: Scalars['InternalPublicationId']; - /** The metadata contentURI resolver */ - contentURI: Scalars['Url']; - /** Profile id */ - from: Scalars['ProfileId']; -}; - -export type CreateDataAvailabilityMirrorRequest = { - /** Profile id which will broadcast the mirror */ - from: Scalars['ProfileId']; - /** The publication to mirror */ - mirror: Scalars['InternalPublicationId']; -}; - -export type CreateDataAvailabilityPostRequest = { - /** The metadata contentURI resolver */ - contentURI: Scalars['Url']; - /** Profile id */ - from: Scalars['ProfileId']; -}; - -export type CreateMirrorRequest = { - /** Profile id */ - profileId: Scalars['ProfileId']; - /** Publication id of what you want to mirror on remember if this is a comment it will be that as the id */ - publicationId: Scalars['InternalPublicationId']; - /** The reference module info */ - referenceModule?: InputMaybe; -}; - -export type CreateProfileRequest = { - /** The follow module */ - followModule?: InputMaybe; - /** The follow NFT URI is the NFT metadata your followers will mint when they follow you. This can be updated at all times. If you do not pass in anything it will create a super cool changing NFT which will show the last publication of your profile as the NFT which looks awesome! This means people do not have to worry about writing this logic but still have the ability to customise it for their followers */ - followNFTURI?: InputMaybe; - handle: Scalars['CreateHandle']; - /** The profile picture uri */ - profilePictureUri?: InputMaybe; -}; - -export type CreatePublicCommentRequest = { - /** The collect module */ - collectModule: CollectModuleParams; - /** The metadata contentURI resolver */ - contentURI: Scalars['Url']; - /** The criteria to access the publication data */ - gated?: InputMaybe; - /** Profile id */ - profileId: Scalars['ProfileId']; - /** Publication id of what your comments on remember if this is a comment you commented on it will be that as the id */ - publicationId: Scalars['InternalPublicationId']; - /** The reference module */ - referenceModule?: InputMaybe; -}; - -export type CreatePublicPostRequest = { - /** The collect module */ - collectModule: CollectModuleParams; - /** The metadata uploaded somewhere passing in the url to reach it */ - contentURI: Scalars['Url']; - /** The criteria to access the publication data */ - gated?: InputMaybe; - /** Profile id */ - profileId: Scalars['ProfileId']; - /** The reference module */ - referenceModule?: InputMaybe; -}; - -export type CreatePublicSetProfileMetadataUriRequest = { - /** The metadata uploaded somewhere passing in the url to reach it */ - metadata: Scalars['Url']; - /** Profile id */ - profileId: Scalars['ProfileId']; -}; - -export type CreateSetDefaultProfileRequest = { - /** Profile id */ - profileId: Scalars['ProfileId']; -}; - -export type CreateSetFollowModuleRequest = { - /** The follow module info */ - followModule: FollowModuleParams; - profileId: Scalars['ProfileId']; -}; - -export type CreateSetFollowNftUriRequest = { - /** The follow NFT URI is the NFT metadata your followers will mint when they follow you. This can be updated at all times. If you do not pass in anything it will create a super cool changing NFT which will show the last publication of your profile as the NFT which looks awesome! This means people do not have to worry about writing this logic but still have the ability to customise it for their followers */ - followNFTURI?: InputMaybe; - profileId: Scalars['ProfileId']; -}; - -export type CreateToggleFollowRequest = { - enables: Array; - profileIds: Array; -}; - -export type CurRequest = { - secret: Scalars['String']; -}; - -/** The custom filters types */ -export enum CustomFiltersTypes { - Gardeners = 'GARDENERS', -} - -export type DataAvailabilityTransactionRequest = { - /** The DA transaction id or internal publication id */ - id: Scalars['String']; -}; - -export type DataAvailabilityTransactionsRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; - profileId?: InputMaybe; -}; - -/** The reason why a profile cannot decrypt a publication */ -export enum DecryptFailReason { - CanNotDecrypt = 'CAN_NOT_DECRYPT', - CollectNotFinalisedOnChain = 'COLLECT_NOT_FINALISED_ON_CHAIN', - DoesNotFollowProfile = 'DOES_NOT_FOLLOW_PROFILE', - DoesNotOwnNft = 'DOES_NOT_OWN_NFT', - DoesNotOwnProfile = 'DOES_NOT_OWN_PROFILE', - FollowNotFinalisedOnChain = 'FOLLOW_NOT_FINALISED_ON_CHAIN', - HasNotCollectedPublication = 'HAS_NOT_COLLECTED_PUBLICATION', - MissingEncryptionParams = 'MISSING_ENCRYPTION_PARAMS', - ProfileDoesNotExist = 'PROFILE_DOES_NOT_EXIST', - UnauthorizedAddress = 'UNAUTHORIZED_ADDRESS', - UnauthorizedBalance = 'UNAUTHORIZED_BALANCE', -} - -export type DefaultProfileRequest = { - ethereumAddress: Scalars['EthereumAddress']; -}; - -export type DegreesOfSeparationReferenceModuleParams = { - /** Applied to comments */ - commentsRestricted: Scalars['Boolean']; - /** Degrees of separation */ - degreesOfSeparation: Scalars['Int']; - /** Applied to mirrors */ - mirrorsRestricted: Scalars['Boolean']; -}; - -export type DismissRecommendedProfilesRequest = { - profileIds: Array; -}; - -export type DoesFollow = { - /** The follower address remember wallets follow profiles */ - followerAddress: Scalars['EthereumAddress']; - /** The profile id */ - profileId: Scalars['ProfileId']; -}; - -export type DoesFollowRequest = { - /** The follower infos */ - followInfos: Array; -}; - -export type Erc4626FeeCollectModuleParams = { - /** The collecting cost associated with this publication. 0 for free collect. */ - amount: ModuleFeeAmountParams; - /** The maximum number of collects for this publication. Omit for no limit. */ - collectLimit?: InputMaybe; - /** The end timestamp after which collecting is impossible. Omit for no expiry. */ - endTimestamp?: InputMaybe; - /** True if only followers of publisher may collect the post. */ - followerOnly: Scalars['Boolean']; - /** The address of the recipient who will receive vault shares after depositing is completed. */ - recipient: Scalars['EthereumAddress']; - /** The referral fee associated with this publication. */ - referralFee?: InputMaybe; - /** The address of the ERC4626 vault to deposit funds to. */ - vault: Scalars['ContractAddress']; -}; - -/** The gated publication encryption provider */ -export enum EncryptionProvider { - LitProtocol = 'LIT_PROTOCOL', -} - -export type EoaOwnershipInput = { - /** The address that will have access to the content */ - address: Scalars['EthereumAddress']; -}; - -export type Erc20OwnershipInput = { - /** The amount of tokens required to access the content */ - amount: Scalars['String']; - /** The amount of tokens required to access the content */ - chainID: Scalars['ChainId']; - /** The operator to use when comparing the amount of tokens */ - condition: ScalarOperator; - /** The ERC20 token ethereum address */ - contractAddress: Scalars['ContractAddress']; - /** The amount of decimals of the ERC20 contract */ - decimals: Scalars['Float']; -}; - -export type ExploreProfilesRequest = { - cursor?: InputMaybe; - customFilters?: InputMaybe>; - limit?: InputMaybe; - sortCriteria: ProfileSortCriteria; - timestamp?: InputMaybe; -}; - -export type ExplorePublicationRequest = { - cursor?: InputMaybe; - customFilters?: InputMaybe>; - /** If you wish to exclude any results for profile ids */ - excludeProfileIds?: InputMaybe>; - limit?: InputMaybe; - metadata?: InputMaybe; - /** If you want the randomizer off (default on) */ - noRandomize?: InputMaybe; - /** The publication types you want to query */ - publicationTypes?: InputMaybe>; - sortCriteria: PublicationSortCriteria; - /** The App Id */ - sources?: InputMaybe>; - timestamp?: InputMaybe; -}; - -export type FeeCollectModuleParams = { - /** The collect module amount info */ - amount: ModuleFeeAmountParams; - /** Follower only */ - followerOnly: Scalars['Boolean']; - /** The collect module recipient address */ - recipient: Scalars['EthereumAddress']; - /** The collect module referral fee */ - referralFee: Scalars['Float']; -}; - -export type FeeFollowModuleParams = { - /** The follow module amount info */ - amount: ModuleFeeAmountParams; - /** The follow module recipient address */ - recipient: Scalars['EthereumAddress']; -}; - -export type FeeFollowModuleRedeemParams = { - /** The expected amount to pay */ - amount: ModuleFeeAmountParams; -}; - -/** The feed event item filter types */ -export enum FeedEventItemType { - CollectComment = 'COLLECT_COMMENT', - CollectPost = 'COLLECT_POST', - Comment = 'COMMENT', - Mirror = 'MIRROR', - Post = 'POST', - ReactionComment = 'REACTION_COMMENT', - ReactionPost = 'REACTION_POST', -} - -export type FeedHighlightsRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; - metadata?: InputMaybe; - /** The profile id */ - profileId: Scalars['ProfileId']; - /** The App Id */ - sources?: InputMaybe>; -}; - -export type FeedRequest = { - cursor?: InputMaybe; - /** Filter your feed to whatever you wish */ - feedEventItemTypes?: InputMaybe>; - limit?: InputMaybe; - metadata?: InputMaybe; - /** The profile id */ - profileId: Scalars['ProfileId']; - /** The App Id */ - sources?: InputMaybe>; -}; - -export type Follow = { - followModule?: InputMaybe; - profile: Scalars['ProfileId']; -}; - -export type FollowConditionInput = { - /** The profile id of the gated profile */ - profileId: Scalars['ProfileId']; -}; - -export type FollowModuleParams = { - /** The follower fee follower module */ - feeFollowModule?: InputMaybe; - /** The empty follow module */ - freeFollowModule?: InputMaybe; - /** The profile follow module */ - profileFollowModule?: InputMaybe; - /** The revert follow module */ - revertFollowModule?: InputMaybe; - /** A unknown follow module */ - unknownFollowModule?: InputMaybe; -}; - -export type FollowModuleRedeemParams = { - /** The follower fee follower module */ - feeFollowModule?: InputMaybe; - /** The profile follower module */ - profileFollowModule?: InputMaybe; - /** A unknown follow module */ - unknownFollowModule?: InputMaybe; -}; - -/** The follow module types */ -export enum FollowModules { - FeeFollowModule = 'FeeFollowModule', - ProfileFollowModule = 'ProfileFollowModule', - RevertFollowModule = 'RevertFollowModule', - UnknownFollowModule = 'UnknownFollowModule', -} - -export type FollowProxyAction = { - freeFollow?: InputMaybe; -}; - -export type FollowRequest = { - follow: Array; -}; - -export type FollowerNftOwnedTokenIdsRequest = { - address: Scalars['EthereumAddress']; - profileId: Scalars['ProfileId']; -}; - -export type FollowersRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; - profileId: Scalars['ProfileId']; -}; - -export type FollowingRequest = { - address: Scalars['EthereumAddress']; - cursor?: InputMaybe; - limit?: InputMaybe; -}; - -export type FraudReasonInputParams = { - reason: PublicationReportingReason; - subreason: PublicationReportingFraudSubreason; -}; - -export type FreeCollectModuleParams = { - /** Follower only */ - followerOnly: Scalars['Boolean']; -}; - -export type FreeCollectProxyAction = { - publicationId: Scalars['InternalPublicationId']; -}; - -export type FreeFollowProxyAction = { - profileId: Scalars['ProfileId']; -}; - -/** The access conditions for the publication */ -export type GatedPublicationParamsInput = { - /** AND condition */ - and?: InputMaybe; - /** Profile follow condition */ - collect?: InputMaybe; - /** The LIT Protocol encrypted symmetric key */ - encryptedSymmetricKey: Scalars['ContentEncryptionKey']; - /** EOA ownership condition */ - eoa?: InputMaybe; - /** Profile follow condition */ - follow?: InputMaybe; - /** NFT ownership condition */ - nft?: InputMaybe; - /** OR condition */ - or?: InputMaybe; - /** Profile ownership condition */ - profile?: InputMaybe; - /** ERC20 token ownership condition */ - token?: InputMaybe; -}; - -export type GciRequest = { - hhh: Scalars['String']; - secret: Scalars['String']; - ttt: Scalars['String']; -}; - -export type GcrRequest = { - hhh: Scalars['String']; - secret: Scalars['String']; - ttt: Scalars['String']; -}; - -export type GctRequest = { - hhh: Scalars['String']; - secret: Scalars['String']; -}; - -export type GddRequest = { - domain: Scalars['Url']; - secret: Scalars['String']; -}; - -export type GdmRequest = { - secret: Scalars['String']; -}; - -export type GenerateModuleCurrencyApprovalDataRequest = { - collectModule?: InputMaybe; - currency: Scalars['ContractAddress']; - followModule?: InputMaybe; - referenceModule?: InputMaybe; - unknownCollectModule?: InputMaybe; - unknownFollowModule?: InputMaybe; - unknownReferenceModule?: InputMaybe; - /** Floating point number as string (e.g. 42.009837). The server will move its decimal places for you */ - value: Scalars['String']; -}; - -export type GetPublicationMetadataStatusRequest = { - publicationId?: InputMaybe; - txHash?: InputMaybe; - txId?: InputMaybe; -}; - -export type GlobalProtocolStatsRequest = { - /** Unix time from timestamp - if not supplied it will go from 0 timestamp */ - fromTimestamp?: InputMaybe; - /** The App Id */ - sources?: InputMaybe>; - /** Unix time to timestamp - if not supplied it go to the present timestamp */ - toTimestamp?: InputMaybe; -}; - -export type HasTxHashBeenIndexedRequest = { - /** Tx hash.. if your using the broadcaster you should use txId due to gas price upgrades */ - txHash?: InputMaybe; - /** Tx id.. if your using the broadcaster you should always use this field */ - txId?: InputMaybe; -}; - -export type HelRequest = { - handle: Scalars['Handle']; - remove: Scalars['Boolean']; - secret: Scalars['String']; -}; - -export type HidePublicationRequest = { - /** Publication id */ - publicationId: Scalars['InternalPublicationId']; -}; - -export type IdKitPhoneVerifyWebhookRequest = { - sharedSecret: Scalars['String']; - worldcoin?: InputMaybe; -}; - -/** The verify webhook result status type */ -export enum IdKitPhoneVerifyWebhookResultStatusType { - AlreadyVerified = 'ALREADY_VERIFIED', - Success = 'SUCCESS', -} - -export type IllegalReasonInputParams = { - reason: PublicationReportingReason; - subreason: PublicationReportingIllegalSubreason; -}; - -export type InRequest = { - ethereumAddress: Scalars['EthereumAddress']; - numInvites: Scalars['Int']; - secret: Scalars['String']; -}; - -export type InTotalRequest = { - ethereumAddress: Scalars['EthereumAddress']; - secret: Scalars['String']; -}; - -export type InternalPinRequest = { - /** The shared secret */ - items: Array; - /** The shared secret */ - secret: Scalars['String']; -}; - -export type InviteRequest = { - invites: Array; - secret: Scalars['String']; -}; - -export type LimitedFeeCollectModuleParams = { - /** The collect module amount info */ - amount: ModuleFeeAmountParams; - /** The collect module limit */ - collectLimit: Scalars['String']; - /** Follower only */ - followerOnly: Scalars['Boolean']; - /** The collect module recipient address */ - recipient: Scalars['EthereumAddress']; - /** The collect module referral fee */ - referralFee: Scalars['Float']; -}; - -export type LimitedTimedFeeCollectModuleParams = { - /** The collect module amount info */ - amount: ModuleFeeAmountParams; - /** The collect module limit */ - collectLimit: Scalars['String']; - /** Follower only */ - followerOnly: Scalars['Boolean']; - /** The collect module recipient address */ - recipient: Scalars['EthereumAddress']; - /** The collect module referral fee */ - referralFee: Scalars['Float']; -}; - -export type MediaTransformParams = { - /** Set the transformed image's height. You can use specific size in pixels eg. 100px, a percentage eg. 50% or set as 'auto' to be set automatically. Default value is 'auto'. */ - height?: InputMaybe; - /** Set if you want to keep the image's original aspect ratio. True by default. If explicitly set to false, the image will stretch based on the width and height values. */ - keepAspectRatio?: InputMaybe; - /** Set the transformed image's width. You can use specific size in pixels eg. 100px, a percentage eg. 50% or set as 'auto' to be set automatically. Default value is 'auto'. */ - width?: InputMaybe; -}; - -/** The metadata attribute input */ -export type MetadataAttributeInput = { - /** The display type */ - displayType?: InputMaybe; - /** The trait type - can be anything its the name it will render so include spaces */ - traitType: Scalars['String']; - /** The value */ - value: Scalars['String']; -}; - -export type ModuleFeeAmountParams = { - /** The currency address */ - currency: Scalars['ContractAddress']; - /** Floating point number as string (e.g. 42.009837). It could have the entire precision of the Asset or be truncated to the last significant decimal. */ - value: Scalars['String']; -}; - -export type ModuleFeeParams = { - /** The fee amount */ - amount: ModuleFeeAmountParams; - /** The fee recipient */ - recipient: Scalars['EthereumAddress']; - /** The referral fee */ - referralFee: Scalars['Float']; -}; - -/** The momka validator error */ -export enum MomokaValidatorError { - BlockCantBeReadFromNode = 'BLOCK_CANT_BE_READ_FROM_NODE', - BlockTooFar = 'BLOCK_TOO_FAR', - CanNotConnectToBundlr = 'CAN_NOT_CONNECT_TO_BUNDLR', - ChainSignatureAlreadyUsed = 'CHAIN_SIGNATURE_ALREADY_USED', - DataCantBeReadFromNode = 'DATA_CANT_BE_READ_FROM_NODE', - EventMismatch = 'EVENT_MISMATCH', - GeneratedPublicationIdMismatch = 'GENERATED_PUBLICATION_ID_MISMATCH', - InvalidEventTimestamp = 'INVALID_EVENT_TIMESTAMP', - InvalidFormattedTypedData = 'INVALID_FORMATTED_TYPED_DATA', - InvalidPointerSetNotNeeded = 'INVALID_POINTER_SET_NOT_NEEDED', - InvalidSignatureSubmitter = 'INVALID_SIGNATURE_SUBMITTER', - InvalidTxId = 'INVALID_TX_ID', - InvalidTypedDataDeadlineTimestamp = 'INVALID_TYPED_DATA_DEADLINE_TIMESTAMP', - NotClosestBlock = 'NOT_CLOSEST_BLOCK', - NoSignatureSubmitter = 'NO_SIGNATURE_SUBMITTER', - PointerFailedVerification = 'POINTER_FAILED_VERIFICATION', - PotentialReorg = 'POTENTIAL_REORG', - PublicationNonceInvalid = 'PUBLICATION_NONCE_INVALID', - PublicationNoneDa = 'PUBLICATION_NONE_DA', - PublicationNoPointer = 'PUBLICATION_NO_POINTER', - PublicationSignerNotAllowed = 'PUBLICATION_SIGNER_NOT_ALLOWED', - SimulationFailed = 'SIMULATION_FAILED', - SimulationNodeCouldNotRun = 'SIMULATION_NODE_COULD_NOT_RUN', - TimestampProofInvalidDaId = 'TIMESTAMP_PROOF_INVALID_DA_ID', - TimestampProofInvalidSignature = 'TIMESTAMP_PROOF_INVALID_SIGNATURE', - TimestampProofInvalidType = 'TIMESTAMP_PROOF_INVALID_TYPE', - TimestampProofNotSubmitter = 'TIMESTAMP_PROOF_NOT_SUBMITTER', - Unknown = 'UNKNOWN', -} - -export type MultirecipientFeeCollectModuleParams = { - /** The collecting cost associated with this publication. 0 for free collect. */ - amount: ModuleFeeAmountParams; - /** The maximum number of collects for this publication. Omit for no limit. */ - collectLimit?: InputMaybe; - /** The end timestamp after which collecting is impossible. Omit for no expiry. */ - endTimestamp?: InputMaybe; - /** True if only followers of publisher may collect the post. */ - followerOnly: Scalars['Boolean']; - /** Recipient of collect fees. */ - recipients: Array; - /** The referral fee associated with this publication. */ - referralFee?: InputMaybe; -}; - -export type MutualFollowersProfilesQueryRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; - /** The profile id your viewing */ - viewingProfileId: Scalars['ProfileId']; - /** The profile id you want the result to come back as your viewing from */ - yourProfileId: Scalars['ProfileId']; -}; - -export type NftData = { - /** Id of the nft ownership challenge */ - id: Scalars['NftOwnershipId']; - /** The signature */ - signature: Scalars['Signature']; -}; - -/** NFT search query */ -export type NftSearchRequest = { - /** Chain IDs to search. Supports Ethereum and Polygon. If omitted, it will search in both chains */ - chainIds?: InputMaybe>; - cursor?: InputMaybe; - /** Exclude follower NFTs from the search */ - excludeFollowers?: InputMaybe; - limit?: InputMaybe; - /** Ethereum address of the owner. If unknown you can also search by profile ID */ - ownerAddress?: InputMaybe; - /** Profile ID of the owner */ - profileId?: InputMaybe; - /** Search query. Has to be part of a collection name */ - query: Scalars['String']; -}; - -export type NfTsRequest = { - /** Chain Ids */ - chainIds?: InputMaybe>; - /** Filter by contract address */ - contractAddress?: InputMaybe; - cursor?: InputMaybe; - /** Exclude filtered collection addresses from the search. Cannot be used together ith `includeCollections` */ - excludeCollections?: InputMaybe>; - /** Exclude follower NFTs from the search. */ - excludeFollowers?: InputMaybe; - /** Include only filtered collection addresses in the search. Overrides `contractAddress` */ - includeCollections?: InputMaybe>; - limit?: InputMaybe; - /** Filter by owner address */ - ownerAddress: Scalars['EthereumAddress']; -}; - -export type Nfi = { - c: Scalars['ContractAddress']; - i: Scalars['ChainId']; -}; - -/** NFT collection filtering input */ -export type NftCollectionInput = { - /** The chain id that the collection exists in */ - chainId: Scalars['ChainId']; - /** Filter by NFT collection contract address */ - contractAddress: Scalars['ContractAddress']; -}; - -/** The NFT gallery input */ -export type NftGalleriesRequest = { - /** The profile id */ - profileId: Scalars['ProfileId']; -}; - -/** The input for creating a new NFT gallery */ -export type NftGalleryCreateRequest = { - /** The NFTs in the gallery */ - items: Array; - /** The name of the NFT gallery */ - name: Scalars['NftGalleryName']; - /** The owner profile id */ - profileId: Scalars['ProfileId']; -}; - -/** The input for deleting gallery */ -export type NftGalleryDeleteRequest = { - /** The NFT gallery id */ - galleryId: Scalars['NftGalleryId']; - /** The profile id of the gallery owner */ - profileId: Scalars['ProfileId']; -}; - -/** The input for updating NFT gallery name */ -export type NftGalleryUpdateInfoRequest = { - /** The NFT gallery id */ - galleryId: Scalars['NftGalleryId']; - /** The name of the NFT gallery */ - name: Scalars['NftGalleryName']; - /** The profile id of the gallery owner */ - profileId: Scalars['ProfileId']; -}; - -/** The input for reordering gallery items */ -export type NftGalleryUpdateItemOrderRequest = { - /** The NFT gallery id */ - galleryId: Scalars['NftGalleryId']; - /** The profile id of the gallery owner */ - profileId: Scalars['ProfileId']; - /** The order of the NFTs in the gallery */ - updates: Array; -}; - -/** The input for adding/removing gallery items */ -export type NftGalleryUpdateItemsRequest = { - /** The NFT gallery id */ - galleryId: Scalars['NftGalleryId']; - /** The profile id of the gallery owner */ - profileId: Scalars['ProfileId']; - /** The contents of the NFT gallery */ - toAdd?: InputMaybe>; - /** The contents of the NFT gallery */ - toRemove?: InputMaybe>; -}; - -/** The NFT input for gallery */ -export type NftInput = { - /** The chain ID of the NFT */ - chainId: Scalars['ChainId']; - /** The contract address of the NFT */ - contractAddress: Scalars['ContractAddress']; - /** The token ID of the NFT */ - tokenId: Scalars['String']; -}; - -export type NftOwnershipChallenge = { - /** Chain Id */ - chainId: Scalars['ChainId']; - /** ContractAddress for nft */ - contractAddress: Scalars['ContractAddress']; - /** Token id for NFT */ - tokenId: Scalars['String']; -}; - -export type NftOwnershipChallengeRequest = { - /** The wallet address which owns the NFT */ - ethereumAddress: Scalars['EthereumAddress']; - nfts: Array; -}; - -export type NftOwnershipInput = { - /** The NFT chain id */ - chainID: Scalars['ChainId']; - /** The NFT collection's ethereum address */ - contractAddress: Scalars['ContractAddress']; - /** The unlocker contract type */ - contractType: ContractType; - /** The optional token ID(s) to check for ownership */ - tokenIds?: InputMaybe>; -}; - -/** The input for updating the order of a NFT gallery item */ -export type NftUpdateItemOrder = { - /** The chain ID of the NFT */ - chainId: Scalars['ChainId']; - /** The contract address of the NFT */ - contractAddress: Scalars['ContractAddress']; - /** The new order of the NFT in the gallery */ - newOrder: Scalars['Int']; - /** The token ID of the NFT */ - tokenId: Scalars['String']; -}; - -export type NniRequest = { - n: Array; - secret: Scalars['String']; -}; - -export type NnvRequest = { - n: Array; - secret: Scalars['String']; -}; - -export type NotificationRequest = { - cursor?: InputMaybe; - customFilters?: InputMaybe>; - highSignalFilter?: InputMaybe; - limit?: InputMaybe; - /** The notification types */ - notificationTypes?: InputMaybe>; - /** The profile id */ - profileId: Scalars['ProfileId']; - /** The App Id */ - sources?: InputMaybe>; -}; - -/** The notification filter types */ -export enum NotificationTypes { - CollectedComment = 'COLLECTED_COMMENT', - CollectedPost = 'COLLECTED_POST', - CommentedComment = 'COMMENTED_COMMENT', - CommentedPost = 'COMMENTED_POST', - Followed = 'FOLLOWED', - MentionComment = 'MENTION_COMMENT', - MentionPost = 'MENTION_POST', - MirroredComment = 'MIRRORED_COMMENT', - MirroredPost = 'MIRRORED_POST', - ReactionComment = 'REACTION_COMMENT', - ReactionPost = 'REACTION_POST', -} - -export type OrConditionInput = { - /** The list of conditions to apply OR to. You can only use nested boolean conditions at the root level. */ - criteria: Array; -}; - -export type PendingApprovalFollowsRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; -}; - -export type PrfRequest = { - dd: Scalars['Boolean']; - hhh: Scalars['String']; - secret: Scalars['String']; - ss: Scalars['Boolean']; -}; - -export type PriRequest = { - hhh: Scalars['String']; - secret: Scalars['String']; -}; - -export type ProfileFollowModuleBeenRedeemedRequest = { - followProfileId: Scalars['ProfileId']; - redeemingProfileId: Scalars['ProfileId']; -}; - -export type ProfileFollowModuleRedeemParams = { - /** The profile id to use to follow this profile */ - profileId: Scalars['ProfileId']; -}; - -export type ProfileFollowRevenueQueryRequest = { - /** The profile id */ - profileId: Scalars['ProfileId']; -}; - -export type ProfileGuardianRequest = { - profileId: Scalars['ProfileId']; -}; - -export type ProfileOnChainIdentityRequest = { - profileIds: Array; -}; - -/** Condition that signifies if address has access to profile */ -export type ProfileOwnershipInput = { - /** The profile id */ - profileId: Scalars['ProfileId']; -}; - -export type ProfilePublicationRevenueQueryRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; - metadata?: InputMaybe; - /** The profile id */ - profileId: Scalars['ProfileId']; - /** The App Id */ - sources?: InputMaybe>; - /** The revenue types */ - types?: InputMaybe>; -}; - -export type ProfilePublicationsForSaleRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; - metadata?: InputMaybe; - /** Profile id */ - profileId: Scalars['ProfileId']; - /** The App Id */ - sources?: InputMaybe>; -}; - -export type ProfileQueryRequest = { - cursor?: InputMaybe; - /** The handles for the profile */ - handles?: InputMaybe>; - limit?: InputMaybe; - /** The ethereum addresses */ - ownedBy?: InputMaybe>; - /** The profile ids */ - profileIds?: InputMaybe>; - /** The mirrored publication id */ - whoMirroredPublicationId?: InputMaybe; -}; - -/** profile sort criteria */ -export enum ProfileSortCriteria { - CreatedOn = 'CREATED_ON', - LatestCreated = 'LATEST_CREATED', - MostCollects = 'MOST_COLLECTS', - MostComments = 'MOST_COMMENTS', - MostFollowers = 'MOST_FOLLOWERS', - MostMirrors = 'MOST_MIRRORS', - MostPosts = 'MOST_POSTS', - MostPublication = 'MOST_PUBLICATION', -} - -export type ProxyActionRequest = { - collect?: InputMaybe; - follow?: InputMaybe; -}; - -/** The proxy action status */ -export enum ProxyActionStatusTypes { - Complete = 'COMPLETE', - Minting = 'MINTING', - Transferring = 'TRANSFERRING', -} - -export type PublicMediaRequest = { - /** The alt tags for accessibility */ - altTag?: InputMaybe; - /** The cover for any video or audio you attached */ - cover?: InputMaybe; - /** Pre calculated cid of the file to push */ - itemCid: Scalars['IpfsCid']; - /** This is the mime type of media */ - type?: InputMaybe; -}; - -/** The publication content warning */ -export enum PublicationContentWarning { - Nsfw = 'NSFW', - Sensitive = 'SENSITIVE', - Spoiler = 'SPOILER', -} - -export type PublicationForYouRequest = { - cursor?: InputMaybe; - for: Scalars['ProfileId']; - limit?: InputMaybe; -}; - -/** The publication main focus */ -export enum PublicationMainFocus { - Article = 'ARTICLE', - Audio = 'AUDIO', - Embed = 'EMBED', - Image = 'IMAGE', - Link = 'LINK', - TextOnly = 'TEXT_ONLY', - Video = 'VIDEO', -} - -/** The source of the media */ -export enum PublicationMediaSource { - Lens = 'LENS', -} - -/** Publication metadata content warning filters */ -export type PublicationMetadataContentWarningFilter = { - /** By default all content warnings will be hidden you can include them in your query by adding them to this array. */ - includeOneOf?: InputMaybe>; -}; - -/** The publication metadata display types */ -export enum PublicationMetadataDisplayTypes { - Date = 'date', - Number = 'number', - String = 'string', -} - -/** Publication metadata filters */ -export type PublicationMetadataFilters = { - contentWarning?: InputMaybe; - /** IOS 639-1 language code aka en or it and ISO 3166-1 alpha-2 region code aka US or IT aka en-US or it-IT. You can just filter on language if you wish. */ - locale?: InputMaybe; - mainContentFocus?: InputMaybe>; - tags?: InputMaybe; -}; - -/** The metadata attribute input */ -export type PublicationMetadataMediaInput = { - /** The alt tags for accessibility */ - altTag?: InputMaybe; - /** The cover for any video or audio you attached */ - cover?: InputMaybe; - item: Scalars['Url']; - source?: InputMaybe; - /** This is the mime type of media */ - type?: InputMaybe; -}; - -/** publication metadata status type */ -export enum PublicationMetadataStatusType { - MetadataValidationFailed = 'METADATA_VALIDATION_FAILED', - NotFound = 'NOT_FOUND', - Pending = 'PENDING', - Success = 'SUCCESS', -} - -/** Publication metadata tag filter */ -export type PublicationMetadataTagsFilter = { - /** Needs to match all */ - all?: InputMaybe>; - /** Needs to only match one of */ - oneOf?: InputMaybe>; -}; - -export type PublicationMetadataV1Input = { - /** - * A URL to a multi-media attachment for the item. The file extensions GLTF, GLB, WEBM, MP4, M4V, OGV, - * and OGG are supported, along with the audio-only extensions MP3, WAV, and OGA. - * Animation_url also supports HTML pages, allowing you to build rich experiences and interactive NFTs using JavaScript canvas, - * WebGL, and more. Scripts and relative paths within the HTML page are now supported. However, access to browser extensions is not supported. - */ - animation_url?: InputMaybe; - /** This is the appId the content belongs to */ - appId?: InputMaybe; - /** These are the attributes for the item, which will show up on the OpenSea and others NFT trading websites on the item. */ - attributes: Array; - /** The content of a publication. If this is blank `media` must be defined or its out of spec */ - content?: InputMaybe; - /** A human-readable description of the item. */ - description?: InputMaybe; - /** - * This is the URL that will appear below the asset's image on OpenSea and others etc - * and will allow users to leave OpenSea and view the item on the site. - */ - external_url?: InputMaybe; - /** legacy to support OpenSea will store any NFT image here. */ - image?: InputMaybe; - /** This is the mime type of the image. This is used if your uploading more advanced cover images as sometimes ipfs does not emit the content header so this solves that */ - imageMimeType?: InputMaybe; - /** This is lens supported attached media items to the publication */ - media?: InputMaybe>; - /** The metadata id can be anything but if your uploading to ipfs you will want it to be random.. using uuid could be an option! */ - metadata_id: Scalars['String']; - /** Name of the item. */ - name: Scalars['String']; - /** Signed metadata to validate the owner */ - signatureContext?: InputMaybe; - /** The metadata version. (1.0.0 | 2.0.0) */ - version: Scalars['String']; -}; - -export type PublicationMetadataV2Input = { - /** - * A URL to a multi-media attachment for the item. The file extensions GLTF, GLB, WEBM, MP4, M4V, OGV, - * and OGG are supported, along with the audio-only extensions MP3, WAV, and OGA. - * Animation_url also supports HTML pages, allowing you to build rich experiences and interactive NFTs using JavaScript canvas, - * WebGL, and more. Scripts and relative paths within the HTML page are now supported. However, access to browser extensions is not supported. - */ - animation_url?: InputMaybe; - /** This is the appId the content belongs to */ - appId?: InputMaybe; - /** These are the attributes for the item, which will show up on the OpenSea and others NFT trading websites on the item. */ - attributes: Array; - /** The content of a publication. If this is blank `media` must be defined or its out of spec */ - content?: InputMaybe; - /** Ability to add a content warning */ - contentWarning?: InputMaybe; - /** A human-readable description of the item. */ - description?: InputMaybe; - /** - * This is the URL that will appear below the asset's image on OpenSea and others etc - * and will allow users to leave OpenSea and view the item on the site. - */ - external_url?: InputMaybe; - /** legacy to support OpenSea will store any NFT image here. */ - image?: InputMaybe; - /** This is the mime type of the image. This is used if your uploading more advanced cover images as sometimes ipfs does not emit the content header so this solves that */ - imageMimeType?: InputMaybe; - /** IOS 639-1 language code aka en or it and ISO 3166-1 alpha-2 region code aka US or IT aka en-US or it-IT */ - locale: Scalars['Locale']; - /** Main content focus that for this publication */ - mainContentFocus: PublicationMainFocus; - /** This is lens supported attached media items to the publication */ - media?: InputMaybe>; - /** The metadata id can be anything but if your uploading to ipfs you will want it to be random.. using uuid could be an option! */ - metadata_id: Scalars['String']; - /** Name of the item. */ - name: Scalars['String']; - /** Signed metadata to validate the owner */ - signatureContext?: InputMaybe; - /** Ability to tag your publication */ - tags?: InputMaybe>; - /** The metadata version. (1.0.0 | 2.0.0) */ - version: Scalars['String']; -}; - -export type PublicationProfileBookmarkRequest = { - /** Profile id to perform the action */ - profileId: Scalars['ProfileId']; - /** The internal publication id */ - publicationId: Scalars['InternalPublicationId']; -}; - -export type PublicationProfileNotInterestedRequest = { - /** Profile id to perform the action */ - profileId: Scalars['ProfileId']; - /** The internal publication id */ - publicationId: Scalars['InternalPublicationId']; -}; - -export type PublicationQueryRequest = { - /** The publication id */ - publicationId?: InputMaybe; - /** The tx hash */ - txHash?: InputMaybe; -}; - -/** Publication reporting fraud subreason */ -export enum PublicationReportingFraudSubreason { - Impersonation = 'IMPERSONATION', - Scam = 'SCAM', -} - -/** Publication reporting illegal subreason */ -export enum PublicationReportingIllegalSubreason { - AnimalAbuse = 'ANIMAL_ABUSE', - DirectThreat = 'DIRECT_THREAT', - HumanAbuse = 'HUMAN_ABUSE', - ThreatIndividual = 'THREAT_INDIVIDUAL', - Violence = 'VIOLENCE', -} - -/** Publication reporting reason */ -export enum PublicationReportingReason { - Fraud = 'FRAUD', - Illegal = 'ILLEGAL', - Sensitive = 'SENSITIVE', - Spam = 'SPAM', -} - -/** Publication reporting sensitive subreason */ -export enum PublicationReportingSensitiveSubreason { - Nsfw = 'NSFW', - Offensive = 'OFFENSIVE', -} - -/** Publication reporting spam subreason */ -export enum PublicationReportingSpamSubreason { - FakeEngagement = 'FAKE_ENGAGEMENT', - LowSignal = 'LOW_SIGNAL', - ManipulationAlgo = 'MANIPULATION_ALGO', - Misleading = 'MISLEADING', - MisuseHashtags = 'MISUSE_HASHTAGS', - Repetitive = 'REPETITIVE', - SomethingElse = 'SOMETHING_ELSE', - Unrelated = 'UNRELATED', -} - -export type PublicationRevenueQueryRequest = { - /** The publication id */ - publicationId: Scalars['InternalPublicationId']; -}; - -export type PublicationSignatureContextInput = { - signature: Scalars['String']; -}; - -/** Publication sort criteria */ -export enum PublicationSortCriteria { - CuratedProfiles = 'CURATED_PROFILES', - Latest = 'LATEST', - TopCollected = 'TOP_COLLECTED', - TopCommented = 'TOP_COMMENTED', - TopMirrored = 'TOP_MIRRORED', -} - -/** The publication types */ -export enum PublicationTypes { - Comment = 'COMMENT', - Mirror = 'MIRROR', - Post = 'POST', -} - -export type PublicationsProfileBookmarkedQueryRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; - metadata?: InputMaybe; - /** Profile id */ - profileId: Scalars['ProfileId']; - /** The App Id */ - sources?: InputMaybe>; -}; - -export type PublicationsQueryRequest = { - /** The ethereum address */ - collectedBy?: InputMaybe; - /** The publication id you wish to get comments for */ - commentsOf?: InputMaybe; - /** The comment ordering type - only used when you use commentsOf */ - commentsOfOrdering?: InputMaybe; - /** The comment ranking filter, you can use - only used when you use commentsOf + commentsOfOrdering=ranking */ - commentsRankingFilter?: InputMaybe; - cursor?: InputMaybe; - customFilters?: InputMaybe>; - limit?: InputMaybe; - metadata?: InputMaybe; - /** Profile id */ - profileId?: InputMaybe; - /** Profile ids */ - profileIds?: InputMaybe>; - /** The publication id */ - publicationIds?: InputMaybe>; - /** The publication types you want to query */ - publicationTypes?: InputMaybe>; - /** The App Id */ - sources?: InputMaybe>; -}; - -export type ReactionFieldResolverRequest = { - /** Profile id */ - profileId?: InputMaybe; -}; - -export type ReactionRequest = { - /** Profile id to perform the action */ - profileId: Scalars['ProfileId']; - /** The internal publication id */ - publicationId: Scalars['InternalPublicationId']; - /** The reaction */ - reaction: ReactionTypes; -}; - -/** Reaction types */ -export enum ReactionTypes { - Downvote = 'DOWNVOTE', - Upvote = 'UPVOTE', -} - -export type RecipientDataInput = { - /** Recipient of collect fees. */ - recipient: Scalars['EthereumAddress']; - /** Split %, should be between 0.01 and 100. Up to 2 decimal points supported. All % should add up to 100 */ - split: Scalars['Float']; -}; - -export type RecommendedProfileOptions = { - /** If you wish to turn ML off */ - disableML?: InputMaybe; - /** The more advanced who to follow you should pass this in */ - profileId?: InputMaybe; - /** If you wish to shuffle the results */ - shuffle?: InputMaybe; -}; - -export type ReferenceModuleParams = { - /** The degrees of separation reference module */ - degreesOfSeparationReferenceModule?: InputMaybe; - /** The follower only reference module */ - followerOnlyReferenceModule?: InputMaybe; - /** A unknown reference module */ - unknownReferenceModule?: InputMaybe; -}; - -/** The reference module types */ -export enum ReferenceModules { - DegreesOfSeparationReferenceModule = 'DegreesOfSeparationReferenceModule', - FollowerOnlyReferenceModule = 'FollowerOnlyReferenceModule', - UnknownReferenceModule = 'UnknownReferenceModule', -} - -/** The refresh request */ -export type RefreshRequest = { - /** The refresh token */ - refreshToken: Scalars['Jwt']; -}; - -export type RelRequest = { - ethereumAddress: Scalars['EthereumAddress']; - secret: Scalars['String']; -}; - -/** Relay error reason */ -export enum RelayErrorReasons { - Expired = 'EXPIRED', - HandleTaken = 'HANDLE_TAKEN', - NotAllowed = 'NOT_ALLOWED', - Rejected = 'REJECTED', - WrongWalletSigned = 'WRONG_WALLET_SIGNED', -} - -/** The relay role key */ -export enum RelayRoleKey { - CreateProfile = 'CREATE_PROFILE', - Dispatcher_1 = 'DISPATCHER_1', - Dispatcher_2 = 'DISPATCHER_2', - Dispatcher_3 = 'DISPATCHER_3', - Dispatcher_4 = 'DISPATCHER_4', - Dispatcher_5 = 'DISPATCHER_5', - Dispatcher_6 = 'DISPATCHER_6', - Dispatcher_7 = 'DISPATCHER_7', - Dispatcher_8 = 'DISPATCHER_8', - Dispatcher_9 = 'DISPATCHER_9', - Dispatcher_10 = 'DISPATCHER_10', - ProxyActionCollect_1 = 'PROXY_ACTION_COLLECT_1', - ProxyActionCollect_2 = 'PROXY_ACTION_COLLECT_2', - ProxyActionCollect_3 = 'PROXY_ACTION_COLLECT_3', - ProxyActionCollect_4 = 'PROXY_ACTION_COLLECT_4', - ProxyActionCollect_5 = 'PROXY_ACTION_COLLECT_5', - ProxyActionCollect_6 = 'PROXY_ACTION_COLLECT_6', - ProxyActionFollow_1 = 'PROXY_ACTION_FOLLOW_1', - ProxyActionFollow_2 = 'PROXY_ACTION_FOLLOW_2', - ProxyActionFollow_3 = 'PROXY_ACTION_FOLLOW_3', - ProxyActionFollow_4 = 'PROXY_ACTION_FOLLOW_4', - ProxyActionFollow_5 = 'PROXY_ACTION_FOLLOW_5', - ProxyActionFollow_6 = 'PROXY_ACTION_FOLLOW_6', - ProxyActionFollow_7 = 'PROXY_ACTION_FOLLOW_7', - ProxyActionFollow_8 = 'PROXY_ACTION_FOLLOW_8', - ProxyActionFollow_9 = 'PROXY_ACTION_FOLLOW_9', - ProxyActionFollow_10 = 'PROXY_ACTION_FOLLOW_10', - WithSig_1 = 'WITH_SIG_1', - WithSig_2 = 'WITH_SIG_2', - WithSig_3 = 'WITH_SIG_3', - ZkRelayer_1 = 'ZK_RELAYER_1', -} - -/** The request object to remove interests from a profile */ -export type RemoveProfileInterestsRequest = { - /** The profile interest to add */ - interests: Array; - /** The profileId to add interests to */ - profileId: Scalars['ProfileId']; -}; - -export type ReportPublicationRequest = { - additionalComments?: InputMaybe; - publicationId: Scalars['InternalPublicationId']; - reason: ReportingReasonInputParams; -}; - -export type ReportingReasonInputParams = { - fraudReason?: InputMaybe; - illegalReason?: InputMaybe; - sensitiveReason?: InputMaybe; - spamReason?: InputMaybe; -}; - -/** The gated publication access criteria scalar operators */ -export enum ScalarOperator { - Equal = 'EQUAL', - GreaterThan = 'GREATER_THAN', - GreaterThanOrEqual = 'GREATER_THAN_OR_EQUAL', - LessThan = 'LESS_THAN', - LessThanOrEqual = 'LESS_THAN_OR_EQUAL', - NotEqual = 'NOT_EQUAL', -} - -export type SearchQueryRequest = { - cursor?: InputMaybe; - customFilters?: InputMaybe>; - limit?: InputMaybe; - /** The search term */ - query: Scalars['Search']; - /** The App Id */ - sources?: InputMaybe>; - type: SearchRequestTypes; -}; - -/** Search request types */ -export enum SearchRequestTypes { - Profile = 'PROFILE', - Publication = 'PUBLICATION', -} - -export type SensitiveReasonInputParams = { - reason: PublicationReportingReason; - subreason: PublicationReportingSensitiveSubreason; -}; - -export type SetDispatcherRequest = { - /** The dispatcher address - they can post, comment, mirror, set follow module, change your profile picture on your behalf, if left as none it will use the built in dispatcher address. */ - dispatcher?: InputMaybe; - /** If you want to enable or disable it */ - enable?: InputMaybe; - /** The profile id */ - profileId: Scalars['ProfileId']; -}; - -/** The signed auth challenge */ -export type SignedAuthChallenge = { - /** The ethereum address you signed the signature with */ - address: Scalars['EthereumAddress']; - /** The signature */ - signature: Scalars['Signature']; -}; - -export type SimpleCollectModuleParams = { - /** The collect module limit */ - collectLimit?: InputMaybe; - /** The timestamp that this collect module will expire */ - endTimestamp?: InputMaybe; - /** The collect module fee params */ - fee?: InputMaybe; - /** Collectible by followers only */ - followerOnly: Scalars['Boolean']; -}; - -export type SingleProfileQueryRequest = { - /** The handle for the profile */ - handle?: InputMaybe; - /** The profile id */ - profileId?: InputMaybe; -}; - -export type SpamReasonInputParams = { - reason: PublicationReportingReason; - subreason: PublicationReportingSpamSubreason; -}; - -/** The publications tags sort criteria */ -export enum TagSortCriteria { - Alphabetical = 'ALPHABETICAL', - MostPopular = 'MOST_POPULAR', -} - -export type TimedFeeCollectModuleParams = { - /** The collect module amount info */ - amount: ModuleFeeAmountParams; - /** Follower only */ - followerOnly: Scalars['Boolean']; - /** The collect module recipient address */ - recipient: Scalars['EthereumAddress']; - /** The collect module referral fee */ - referralFee: Scalars['Float']; -}; - -/** Transaction error reason */ -export enum TransactionErrorReasons { - Reverted = 'REVERTED', -} - -export type TypedDataOptions = { - /** If you wish to override the nonce for the sig if you want to do some clever stuff in the client */ - overrideSigNonce: Scalars['Nonce']; -}; - -export type UnfollowRequest = { - profile: Scalars['ProfileId']; -}; - -export type UnknownCollectModuleParams = { - contractAddress: Scalars['ContractAddress']; - /** The encoded data to submit with the module */ - data: Scalars['BlockchainData']; -}; - -export type UnknownFollowModuleParams = { - contractAddress: Scalars['ContractAddress']; - /** The encoded data to submit with the module */ - data: Scalars['BlockchainData']; -}; - -export type UnknownFollowModuleRedeemParams = { - /** The encoded data to submit with the module */ - data: Scalars['BlockchainData']; -}; - -export type UnknownReferenceModuleParams = { - contractAddress: Scalars['ContractAddress']; - /** The encoded data to submit with the module */ - data: Scalars['BlockchainData']; -}; - -export type UpdateProfileImageRequest = { - /** The nft data */ - nftData?: InputMaybe; - profileId: Scalars['ProfileId']; - /** The url to the image if offline */ - url?: InputMaybe; -}; - -export type ValidatePublicationMetadataRequest = { - metadatav1?: InputMaybe; - metadatav2?: InputMaybe; -}; - -/** The access request */ -export type VerifyRequest = { - /** The access token */ - accessToken: Scalars['Jwt']; -}; - -export type WhoCollectedPublicationRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; - /** Internal publication id */ - publicationId: Scalars['InternalPublicationId']; -}; - -export type WhoReactedPublicationRequest = { - cursor?: InputMaybe; - limit?: InputMaybe; - /** Internal publication id */ - publicationId: Scalars['InternalPublicationId']; -}; - -/** The worldcoin signal type */ -export enum WorldcoinPhoneVerifyType { - Orb = 'ORB', - Phone = 'PHONE', -} - -export type WorldcoinPhoneVerifyWebhookRequest = { - nullifierHash: Scalars['String']; - signal: Scalars['EthereumAddress']; - signalType: WorldcoinPhoneVerifyType; -}; - -export type AuthChallengeVariables = Exact<{ - address: Scalars['EthereumAddress']; -}>; - -export type AuthChallengeData = { result: { text: string } }; - -export type AuthAuthenticateVariables = Exact<{ - address: Scalars['EthereumAddress']; - signature: Scalars['Signature']; -}>; - -export type AuthAuthenticateData = { result: { accessToken: string; refreshToken: string } }; - -export type AuthRefreshVariables = Exact<{ - refreshToken: Scalars['Jwt']; -}>; - -export type AuthRefreshData = { result: { accessToken: string; refreshToken: string } }; - -export type CreateCollectTypedDataVariables = Exact<{ - request: CreateCollectRequest; - options?: InputMaybe; -}>; - -export type CreateCollectTypedDataData = { - result: { - id: string; - expiresAt: string; - typedData: { - types: { CollectWithSig: Array<{ name: string; type: string }> }; - domain: Eip712TypedDataDomain; - message: { - nonce: number; - deadline: unknown; - profileId: ProfileId; - pubId: string; - data: string; - }; - }; - }; -}; - -export type CreateCommentEip712TypedData = { - types: { CommentWithSig: Array<{ name: string; type: string }> }; - domain: Eip712TypedDataDomain; - message: { - nonce: number; - deadline: unknown; - profileId: ProfileId; - contentURI: Url; - profileIdPointed: ProfileId; - pubIdPointed: string; - collectModule: string; - collectModuleInitData: string; - referenceModuleData: string; - referenceModule: string; - referenceModuleInitData: string; - }; -}; - -export type CreateCommentTypedDataVariables = Exact<{ - request: CreatePublicCommentRequest; - options?: InputMaybe; -}>; - -export type CreateCommentTypedDataData = { - result: { id: string; expiresAt: string; typedData: CreateCommentEip712TypedData }; -}; - -export type CreateCommentViaDispatcherVariables = Exact<{ - request: CreatePublicCommentRequest; -}>; - -export type CreateCommentViaDispatcherData = { - result: BroadcastOnChainResult_RelayError_ | BroadcastOnChainResult_RelayerResult_; -}; - -export type CreateDataAvailabilityCommentTypedDataVariables = Exact<{ - request: CreateDataAvailabilityCommentRequest; -}>; - -export type CreateDataAvailabilityCommentTypedDataData = { - result: { id: string; expiresAt: string; typedData: CreateCommentEip712TypedData }; -}; - -export type CreateDataAvailabilityCommentViaDispatcherVariables = Exact<{ - request: CreateDataAvailabilityCommentRequest; -}>; - -export type CreateDataAvailabilityCommentViaDispatcherData = { - result: - | BroadcastOffChainResult_CreateDataAvailabilityPublicationResult_ - | BroadcastOffChainResult_RelayError_; -}; - -export type Erc20Fields = { - __typename: 'Erc20'; - name: string; - symbol: string; - decimals: number; - address: string; -}; - -export type Erc20AmountFields = { __typename: 'Erc20Amount'; value: string; asset: Erc20Fields }; - -export type ModuleFeeAmount = { __typename: 'ModuleFeeAmount'; value: string; asset: Erc20Fields }; - -export type AaveFeeCollectModuleSettings = { - __typename: 'AaveFeeCollectModuleSettings'; - contractAddress: string; - followerOnly: boolean; - recipient: EthereumAddress; - referralFee: number; - collectLimitOptional: string | null; - endTimestampOptional: string | null; - amount: ModuleFeeAmount; -}; - -export type Erc4626FeeCollectModuleSettings = { - __typename: 'ERC4626FeeCollectModuleSettings'; - contractAddress: string; - followerOnly: boolean; - recipient: EthereumAddress; - referralFee: number; - vault: string; - collectLimitOptional: string | null; - endTimestampOptional: string | null; - amount: ModuleFeeAmount; -}; - -export type MultirecipientFeeCollectModuleSettings = { - __typename: 'MultirecipientFeeCollectModuleSettings'; - contractAddress: string; - followerOnly: boolean; - referralFee: number; - collectLimitOptional: string | null; - endTimestampOptional: string | null; - amount: ModuleFeeAmount; - recipients: Array<{ recipient: EthereumAddress; split: number }>; -}; - -export type UnknownCollectModuleSettings = { - __typename: 'UnknownCollectModuleSettings'; - contractAddress: string; - collectModuleReturnData: string; -}; - -export type FreeCollectModuleSettings = { - __typename: 'FreeCollectModuleSettings'; - contractAddress: string; - followerOnly: boolean; -}; - -export type FeeCollectModuleSettings = { - __typename: 'FeeCollectModuleSettings'; - contractAddress: string; - followerOnly: boolean; - recipient: EthereumAddress; - referralFee: number; - amount: ModuleFeeAmount; -}; - -export type LimitedFeeCollectModuleSettings = { - __typename: 'LimitedFeeCollectModuleSettings'; - collectLimit: string; - contractAddress: string; - followerOnly: boolean; - recipient: EthereumAddress; - referralFee: number; - amount: ModuleFeeAmount; -}; - -export type LimitedTimedFeeCollectModuleSettings = { - __typename: 'LimitedTimedFeeCollectModuleSettings'; - collectLimit: string; - contractAddress: string; - followerOnly: boolean; - endTimestamp: string; - recipient: EthereumAddress; - referralFee: number; - amount: ModuleFeeAmount; -}; - -export type RevertCollectModuleSettings = { - __typename: 'RevertCollectModuleSettings'; - contractAddress: string; -}; - -export type TimedFeeCollectModuleSettings = { - __typename: 'TimedFeeCollectModuleSettings'; - contractAddress: string; - followerOnly: boolean; - endTimestamp: string; - recipient: EthereumAddress; - referralFee: number; - amount: ModuleFeeAmount; -}; - -export type SimpleCollectModuleSettings = { - __typename: 'SimpleCollectModuleSettings'; - contractAddress: string; - followerOnly: boolean; - collectLimitOptional: string | null; - endTimestampOptional: string | null; - feeOptional: { referralFee: number; recipient: EthereumAddress; amount: ModuleFeeAmount } | null; -}; - -export type Wallet = { - __typename: 'Wallet'; - address: EthereumAddress; - defaultProfile: Profile | null; -}; - -export type Media = { - __typename: 'Media'; - altTag: string | null; - cover: Url | null; - mimeType: string | null; - url: Url; -}; - -export type PublicationMediaSet = { - __typename: 'MediaSet'; - original: Media; - optimized: Media | null; - small: Media | null; - medium: Media | null; -}; - -export type ProfilePictureSet = { - __typename: 'MediaSet'; - original: Media; - optimized: Media | null; - thumbnail: Media | null; -}; - -export type ProfileCoverSet = { __typename: 'MediaSet'; original: Media; optimized: Media | null }; - -export type MetadataOutput = { - __typename: 'MetadataOutput'; - animatedUrl: Url | null; - content: string | null; - contentWarning: PublicationContentWarning | null; - description: string | null; - image: Url | null; - locale: string | null; - mainContentFocus: PublicationMainFocus; - name: string | null; - tags: Array; - media: Array; - attributes: Array; - encryptionParams: EncryptionParamsOutput | null; -}; - -export type MetadataAttributeOutput = { - __typename: 'MetadataAttributeOutput'; - traitType: string | null; - value: string | null; -}; - -export type PublicationStats = { - __typename: 'PublicationStats'; - totalAmountOfMirrors: number; - totalUpvotes: number; - totalDownvotes: number; - totalAmountOfCollects: number; - totalAmountOfComments: number; - totalBookmarks: number; - commentsCount: number; -}; - -export type MirrorBase = { - __typename: 'Mirror'; - id: PublicationId; - createdAt: string; - hidden: boolean; - profile: Profile; -}; - -export type Mirror = { __typename: 'Mirror'; mirrorOf: Comment | Post } & MirrorBase; - -export type FollowOnlyReferenceModuleSettings = { - __typename: 'FollowOnlyReferenceModuleSettings'; - contractAddress: string; -}; - -export type DegreesOfSeparationReferenceModuleSettings = { - __typename: 'DegreesOfSeparationReferenceModuleSettings'; - contractAddress: string; - commentsRestricted: boolean; - degreesOfSeparation: number; - mirrorsRestricted: boolean; -}; - -export type UnknownReferenceModuleSettings = { - __typename: 'UnknownReferenceModuleSettings'; - contractAddress: string; - referenceModuleReturnData: string; -}; - -export type CommentBase = { - __typename: 'Comment'; - id: PublicationId; - appId: AppId | null; - collectNftAddress: string | null; - createdAt: string; - hidden: boolean; - isGated: boolean; - reaction: ReactionTypes | null; - hasCollectedByMe: boolean; - mirrors: Array; - notInterested: boolean; - bookmarked: boolean; - hasOptimisticCollectedByMe: boolean; - isOptimisticMirroredByMe: boolean; - isMirroredByMe: boolean; - collectPolicy: CollectPolicy; - referencePolicy: ReferencePolicy; - decryptionCriteria: DecryptionCriteria | null; - contentInsight: ContentInsight; - observedBy: ProfileId | null; - stats: PublicationStats; - metadata: MetadataOutput; - profile: Profile; - collectedBy: Wallet | null; - collectModule: - | AaveFeeCollectModuleSettings - | Erc4626FeeCollectModuleSettings - | FeeCollectModuleSettings - | FreeCollectModuleSettings - | LimitedFeeCollectModuleSettings - | LimitedTimedFeeCollectModuleSettings - | MultirecipientFeeCollectModuleSettings - | RevertCollectModuleSettings - | SimpleCollectModuleSettings - | TimedFeeCollectModuleSettings - | UnknownCollectModuleSettings; - referenceModule: - | DegreesOfSeparationReferenceModuleSettings - | FollowOnlyReferenceModuleSettings - | UnknownReferenceModuleSettings - | null; - canComment: { result: boolean }; - canMirror: { result: boolean }; - canObserverDecrypt: { result: boolean; reasons: Array | null }; -}; - -export type PaginatedResultInfo = { - __typename: 'PaginatedResultInfo'; - moreAfter: boolean; - prev: Cursor | null; - next: Cursor | null; - totalCount: number | null; -}; - -export type Comment = { - __typename: 'Comment'; - commentOn: CommentBase | MirrorBase | Post | null; - mainPost: MirrorBase | Post; - firstComment: CommentBase | null; -} & CommentBase; - -export type Post = { - __typename: 'Post'; - id: PublicationId; - appId: AppId | null; - collectNftAddress: string | null; - createdAt: string; - hidden: boolean; - isGated: boolean; - reaction: ReactionTypes | null; - hasCollectedByMe: boolean; - mirrors: Array; - notInterested: boolean; - bookmarked: boolean; - hasOptimisticCollectedByMe: boolean; - isOptimisticMirroredByMe: boolean; - isMirroredByMe: boolean; - collectPolicy: CollectPolicy; - referencePolicy: ReferencePolicy; - decryptionCriteria: DecryptionCriteria | null; - contentInsight: ContentInsight; - observedBy: ProfileId | null; - stats: PublicationStats; - metadata: MetadataOutput; - profile: Profile; - collectedBy: Wallet | null; - collectModule: - | AaveFeeCollectModuleSettings - | Erc4626FeeCollectModuleSettings - | FeeCollectModuleSettings - | FreeCollectModuleSettings - | LimitedFeeCollectModuleSettings - | LimitedTimedFeeCollectModuleSettings - | MultirecipientFeeCollectModuleSettings - | RevertCollectModuleSettings - | SimpleCollectModuleSettings - | TimedFeeCollectModuleSettings - | UnknownCollectModuleSettings; - referenceModule: - | DegreesOfSeparationReferenceModuleSettings - | FollowOnlyReferenceModuleSettings - | UnknownReferenceModuleSettings - | null; - canComment: { result: boolean }; - canMirror: { result: boolean }; - canObserverDecrypt: { result: boolean; reasons: Array | null }; -}; - -type Publication_Comment_ = Comment; - -type Publication_Mirror_ = Mirror; - -type Publication_Post_ = Post; - -export type Publication = Publication_Comment_ | Publication_Mirror_ | Publication_Post_; - -export type PendingPost = { - __typename: 'PendingPost'; - id: string; - content: string | null; - locale: string; - mainContentFocus: PublicationMainFocus; - media: Array | null; - profile: Profile; -}; - -export type Eip712TypedDataDomain = { - __typename: 'EIP712TypedDataDomain'; - name: string; - chainId: number; - version: string; - verifyingContract: string; -}; - -export type EnabledModuleCurrenciesVariables = Exact<{ [key: string]: never }>; - -export type EnabledModuleCurrenciesData = { result: Array }; - -export type ElectedMirror = { - __typename: 'ElectedMirror'; - mirrorId: PublicationId; - timestamp: string; - profile: Profile; -}; - -export type MirrorEvent = { __typename: 'MirrorEvent'; timestamp: string; profile: Profile }; - -export type CollectedEvent = { __typename: 'CollectedEvent'; timestamp: string; profile: Profile }; - -export type ReactionEvent = { - __typename: 'ReactionEvent'; - reaction: ReactionTypes; - timestamp: string; - profile: Profile; -}; - -export type FeedItem = { - __typename: 'FeedItem'; - root: Comment | Post; - comments: Array | null; - electedMirror: ElectedMirror | null; - mirrors: Array; - collects: Array; - reactions: Array; -}; - -export type FeedVariables = Exact<{ - profileId: Scalars['ProfileId']; - restrictEventTypesTo?: InputMaybe | FeedEventItemType>; - observerId?: InputMaybe; - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - sources: Array | Scalars['Sources']; - metadata?: InputMaybe; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type FeedData = { result: { items: Array; pageInfo: PaginatedResultInfo } }; - -export type ExploreProfilesVariables = Exact<{ - sortCriteria: ProfileSortCriteria; - limit?: InputMaybe; - cursor?: InputMaybe; - observerId?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type ExploreProfilesData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type CreateFollowTypedDataVariables = Exact<{ - request: FollowRequest; - options?: InputMaybe; -}>; - -export type CreateFollowTypedDataData = { - result: { - id: string; - expiresAt: string; - typedData: { - types: { FollowWithSig: Array<{ name: string; type: string }> }; - domain: Eip712TypedDataDomain; - message: { - nonce: number; - deadline: unknown; - profileIds: Array; - datas: Array; - }; - }; - }; -}; - -export type NftOwnershipOutput = { - __typename: 'NftOwnershipOutput'; - contractAddress: string; - chainID: number; - contractType: ContractType; - tokenIds: Array | null; -}; - -export type Erc20OwnershipOutput = { - __typename: 'Erc20OwnershipOutput'; - amount: string; - chainID: number; - condition: ScalarOperator; - contractAddress: string; - decimals: number; - name: string; - symbol: string; -}; - -export type EoaOwnershipOutput = { __typename: 'EoaOwnershipOutput'; address: EthereumAddress }; - -export type ProfileOwnershipOutput = { __typename: 'ProfileOwnershipOutput'; profileId: ProfileId }; - -export type FollowConditionOutput = { __typename: 'FollowConditionOutput'; profileId: ProfileId }; - -export type CollectConditionOutput = { - __typename: 'CollectConditionOutput'; - publicationId: PublicationId | null; - thisPublication: boolean | null; -}; - -export type LeafConditionOutput = { - __typename: 'AccessConditionOutput'; - nft: NftOwnershipOutput | null; - token: Erc20OwnershipOutput | null; - eoa: EoaOwnershipOutput | null; - profile: ProfileOwnershipOutput | null; - follow: FollowConditionOutput | null; - collect: CollectConditionOutput | null; -}; - -export type OrConditionOutput = { - __typename: 'OrConditionOutput'; - criteria: Array; -}; - -export type AndConditionOutput = { - __typename: 'AndConditionOutput'; - criteria: Array; -}; - -export type AnyConditionOutput = { - __typename: 'AccessConditionOutput'; - or: OrConditionOutput | null; - and: AndConditionOutput | null; -} & LeafConditionOutput; - -export type RootConditionOutput = { - __typename: 'AccessConditionOutput'; - or: { criteria: Array } | null; -}; - -export type EncryptedMedia = { - __typename: 'EncryptedMedia'; - altTag: string | null; - cover: string | null; - mimeType: string | null; - url: Url; -}; - -export type EncryptedMediaSet = { __typename: 'EncryptedMediaSet'; original: EncryptedMedia }; - -export type EncryptedFieldsOutput = { - __typename: 'EncryptedFieldsOutput'; - animation_url: string | null; - content: string | null; - external_url: string | null; - image: string | null; - media: Array<{ original: EncryptedMedia }> | null; -}; - -export type EncryptionParamsOutput = { - __typename: 'EncryptionParamsOutput'; - encryptionProvider: EncryptionProvider; - accessCondition: RootConditionOutput; - encryptedFields: EncryptedFieldsOutput; - providerSpecificParams: { encryptionKey: ContentEncryptionKey }; -}; - -export type CreateMirrorEip712TypedData = { - types: { MirrorWithSig: Array<{ name: string; type: string }> }; - domain: Eip712TypedDataDomain; - message: { - nonce: number; - deadline: unknown; - profileId: ProfileId; - profileIdPointed: ProfileId; - pubIdPointed: string; - referenceModuleData: string; - referenceModule: string; - referenceModuleInitData: string; - }; -}; - -export type CreateMirrorTypedDataVariables = Exact<{ - request: CreateMirrorRequest; - options?: InputMaybe; -}>; - -export type CreateMirrorTypedDataData = { - result: { id: string; expiresAt: string; typedData: CreateMirrorEip712TypedData }; -}; - -export type CreateMirrorViaDispatcherVariables = Exact<{ - request: CreateMirrorRequest; -}>; - -export type CreateMirrorViaDispatcherData = { - result: BroadcastOnChainResult_RelayError_ | BroadcastOnChainResult_RelayerResult_; -}; - -export type CreateDataAvailabilityMirrorTypedDataVariables = Exact<{ - request: CreateDataAvailabilityMirrorRequest; -}>; - -export type CreateDataAvailabilityMirrorTypedDataData = { - result: { id: string; expiresAt: string; typedData: CreateMirrorEip712TypedData }; -}; - -export type CreateDataAvailabilityMirrorViaDispatcherVariables = Exact<{ - request: CreateDataAvailabilityMirrorRequest; -}>; - -export type CreateDataAvailabilityMirrorViaDispatcherData = { - result: - | BroadcastOffChainResult_CreateDataAvailabilityPublicationResult_ - | BroadcastOffChainResult_RelayError_; -}; - -export type ModuleInfo = { __typename: 'ModuleInfo'; name: string; type: string }; - -export type EnabledModule = { - __typename: 'EnabledModule'; - moduleName: string; - contractAddress: string; - inputParams: Array; - redeemParams: Array; - returnDataParams: Array; -}; - -export type EnabledModules = { - __typename: 'EnabledModules'; - collectModules: Array; - followModules: Array; - referenceModules: Array; -}; - -export type EnabledModulesVariables = Exact<{ [key: string]: never }>; - -export type EnabledModulesData = { result: EnabledModules }; - -export type NewFollowerNotification = { - __typename: 'NewFollowerNotification'; - notificationId: string; - createdAt: string; - isFollowedByMe: boolean; - wallet: Wallet; -}; - -export type NewCollectNotification = { - __typename: 'NewCollectNotification'; - notificationId: string; - createdAt: string; - wallet: Wallet; - collectedPublication: Comment | Mirror | Post; -}; - -export type NewMirrorNotification = { - __typename: 'NewMirrorNotification'; - notificationId: string; - createdAt: string; - profile: Profile; - publication: Comment | Post; -}; - -export type NewCommentNotification = { - __typename: 'NewCommentNotification'; - notificationId: string; - createdAt: string; - profile: Profile; - comment: Comment; -}; - -export type NewMentionNotification = { - __typename: 'NewMentionNotification'; - notificationId: string; - createdAt: string; - mentionPublication: Comment | Post; -}; - -export type NewReactionNotification = { - __typename: 'NewReactionNotification'; - notificationId: string; - createdAt: string; - reaction: ReactionTypes; - profile: Profile; - publication: Comment | Mirror | Post; -}; - -export type NotificationsVariables = Exact<{ - observerId: Scalars['ProfileId']; - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - sources: Array | Scalars['Sources']; - notificationTypes?: InputMaybe | NotificationTypes>; - highSignalFilter: Scalars['Boolean']; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type NotificationsData = { - result: { - items: Array< - | NewCollectNotification - | NewCommentNotification - | NewFollowerNotification - | NewMentionNotification - | NewMirrorNotification - | NewReactionNotification - >; - pageInfo: PaginatedResultInfo; - }; -}; - -export type UnreadNotificationCountVariables = Exact<{ - profileId: Scalars['ProfileId']; - sources?: InputMaybe | Scalars['Sources']>; - notificationTypes?: InputMaybe | NotificationTypes>; -}>; - -export type UnreadNotificationCountData = { result: { pageInfo: { totalCount: number | null } } }; - -export type CreatePostEip712TypedData = { - types: { PostWithSig: Array<{ name: string; type: string }> }; - domain: Eip712TypedDataDomain; - message: { - nonce: number; - deadline: unknown; - profileId: ProfileId; - contentURI: Url; - collectModule: string; - collectModuleInitData: string; - referenceModule: string; - referenceModuleInitData: string; - }; -}; - -export type CreatePostTypedDataVariables = Exact<{ - request: CreatePublicPostRequest; - options?: InputMaybe; -}>; - -export type CreatePostTypedDataData = { - result: { id: string; expiresAt: string; typedData: CreatePostEip712TypedData }; -}; - -export type CreatePostViaDispatcherVariables = Exact<{ - request: CreatePublicPostRequest; -}>; - -export type CreatePostViaDispatcherData = { - result: BroadcastOnChainResult_RelayError_ | BroadcastOnChainResult_RelayerResult_; -}; - -export type CreateDataAvailabilityPostTypedDataVariables = Exact<{ - request: CreateDataAvailabilityPostRequest; -}>; - -export type CreateDataAvailabilityPostTypedDataData = { - result: { id: string; expiresAt: string; typedData: CreatePostEip712TypedData }; -}; - -export type CreateDataAvailabilityPostViaDispatcherVariables = Exact<{ - request: CreateDataAvailabilityPostRequest; -}>; - -export type CreateDataAvailabilityPostViaDispatcherData = { - result: - | BroadcastOffChainResult_CreateDataAvailabilityPublicationResult_ - | BroadcastOffChainResult_RelayError_; -}; - -export type CreateSetDispatcherTypedDataVariables = Exact<{ - request: SetDispatcherRequest; - options?: InputMaybe; -}>; - -export type CreateSetDispatcherTypedDataData = { - result: { - id: string; - expiresAt: string; - typedData: { - types: { SetDispatcherWithSig: Array<{ name: string; type: string }> }; - domain: { name: string; chainId: number; version: string; verifyingContract: string }; - message: { - nonce: number; - deadline: unknown; - profileId: ProfileId; - dispatcher: EthereumAddress; - }; - }; - }; -}; - -export type ProfileGuardianResult = { - protected: boolean; - disablingProtectionTimestamp: string | null; -}; - -export type ProfileGuardianVariables = Exact<{ - request: ProfileGuardianRequest; -}>; - -export type ProfileGuardianData = { result: ProfileGuardianResult }; - -export type FeeFollowModuleSettings = { - __typename: 'FeeFollowModuleSettings'; - contractAddress: string; - recipient: EthereumAddress; - amount: ModuleFeeAmount; -}; - -export type ProfileFollowModuleSettings = { - __typename: 'ProfileFollowModuleSettings'; - contractAddress: string; -}; - -export type RevertFollowModuleSettings = { - __typename: 'RevertFollowModuleSettings'; - contractAddress: string; -}; - -export type UnknownFollowModuleSettings = { - __typename: 'UnknownFollowModuleSettings'; - contractAddress: string; -}; - -export type NftImage = { - __typename: 'NftImage'; - contractAddress: string; - tokenId: string; - uri: Url; - verified: boolean; -}; - -export type Attribute = { - __typename: 'Attribute'; - displayType: string | null; - key: string; - value: string; -}; - -export type ProfileStats = { - __typename: 'ProfileStats'; - totalCollects: number; - totalComments: number; - totalFollowers: number; - totalFollowing: number; - totalMirrors: number; - totalPosts: number; - totalPublications: number; - commentsCount: number; - postsCount: number; - mirrorsCount: number; -}; - -export type ProfileFields = { - __typename: 'Profile'; - id: ProfileId; - name: string | null; - bio: string | null; - handle: string; - ownedBy: EthereumAddress; - interests: Array | null; - followNftAddress: string | null; - followPolicy: FollowPolicy; - isFollowedByMe: boolean; - followStatus: FollowStatus | null; - ownedByMe: boolean; - observedBy: ProfileId | null; - attributes: ProfileAttributes; - isFollowingObserver: boolean; - picture: ProfilePictureSet | NftImage | null; - coverPicture: ProfileCoverSet | NftImage | null; - stats: ProfileStats; - followModule: - | FeeFollowModuleSettings - | ProfileFollowModuleSettings - | RevertFollowModuleSettings - | UnknownFollowModuleSettings - | null; - __attributes: Array | null; - dispatcher: { address: EthereumAddress; canUseRelay: boolean } | null; - onChainIdentity: { - proofOfHumanity: boolean; - ens: { name: unknown | null } | null; - sybilDotOrg: { verified: boolean; source: { twitter: { handle: string | null } } }; - worldcoin: { isHuman: boolean }; - }; -}; - -export type Profile = { invitedBy: ProfileFields | null } & ProfileFields; - -export type ProfilesToFollowVariables = Exact<{ - observerId?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type ProfilesToFollowData = { result: Array }; - -export type GetProfileVariables = Exact<{ - request: SingleProfileQueryRequest; - observerId?: InputMaybe; - sources?: InputMaybe | Scalars['Sources']>; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type GetProfileData = { result: Profile | null }; - -export type GetAllProfilesVariables = Exact<{ - byProfileIds?: InputMaybe | Scalars['ProfileId']>; - byHandles?: InputMaybe | Scalars['Handle']>; - byOwnerAddresses?: InputMaybe | Scalars['EthereumAddress']>; - byWhoMirroredPublicationId?: InputMaybe; - observerId?: InputMaybe; - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - sources?: InputMaybe | Scalars['Sources']>; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type GetAllProfilesData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type CreateProfileVariables = Exact<{ - request: CreateProfileRequest; -}>; - -export type CreateProfileData = { - result: BroadcastOnChainResult_RelayError_ | BroadcastOnChainResult_RelayerResult_; -}; - -export type MutualFollowersProfilesVariables = Exact<{ - observerId: Scalars['ProfileId']; - viewingProfileId: Scalars['ProfileId']; - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type MutualFollowersProfilesData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type CreateSetFollowModuleTypedDataVariables = Exact<{ - request: CreateSetFollowModuleRequest; - options?: InputMaybe; -}>; - -export type CreateSetFollowModuleTypedDataData = { - result: { - id: string; - expiresAt: string; - typedData: { - types: { SetFollowModuleWithSig: Array<{ name: string; type: string }> }; - domain: { name: string; chainId: number; version: string; verifyingContract: string }; - message: { - nonce: number; - deadline: unknown; - profileId: ProfileId; - followModule: string; - followModuleInitData: string; - }; - }; - }; -}; - -export type CreateSetProfileImageUriTypedDataVariables = Exact<{ - request: UpdateProfileImageRequest; - options?: InputMaybe; -}>; - -export type CreateSetProfileImageUriTypedDataData = { - result: { - id: string; - expiresAt: string; - typedData: { - types: { SetProfileImageURIWithSig: Array<{ name: string; type: string }> }; - domain: { name: string; chainId: number; version: string; verifyingContract: string }; - message: { nonce: number; deadline: unknown; profileId: ProfileId; imageURI: Url }; - }; - }; -}; - -export type CreateSetProfileImageUriViaDispatcherVariables = Exact<{ - request: UpdateProfileImageRequest; -}>; - -export type CreateSetProfileImageUriViaDispatcherData = { - result: BroadcastOnChainResult_RelayError_ | BroadcastOnChainResult_RelayerResult_; -}; - -export type CreateSetProfileMetadataTypedDataVariables = Exact<{ - request: CreatePublicSetProfileMetadataUriRequest; - options?: InputMaybe; -}>; - -export type CreateSetProfileMetadataTypedDataData = { - result: { - id: string; - expiresAt: string; - typedData: { - types: { SetProfileMetadataURIWithSig: Array<{ name: string; type: string }> }; - domain: { name: string; chainId: number; version: string; verifyingContract: string }; - message: { nonce: number; deadline: unknown; profileId: ProfileId; metadata: Url }; - }; - }; -}; - -export type CreateSetProfileMetadataViaDispatcherVariables = Exact<{ - request: CreatePublicSetProfileMetadataUriRequest; -}>; - -export type CreateSetProfileMetadataViaDispatcherData = { - result: BroadcastOnChainResult_RelayError_ | BroadcastOnChainResult_RelayerResult_; -}; - -export type Follower = { __typename: 'Follower'; wallet: Wallet }; - -export type Following = { __typename: 'Following'; profile: Profile }; - -export type ProfileFollowersVariables = Exact<{ - profileId: Scalars['ProfileId']; - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - observerId?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type ProfileFollowersData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type ProfileFollowingVariables = Exact<{ - walletAddress: Scalars['EthereumAddress']; - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - observerId?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type ProfileFollowingData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type ProxyActionStatusResult = { - __typename: 'ProxyActionStatusResult'; - txHash: string; - txId: string; - status: ProxyActionStatusTypes; -}; - -export type ProxyActionError = { - __typename: 'ProxyActionError'; - reason: string; - lastKnownTxId: string | null; -}; - -export type ProxyActionQueued = { __typename: 'ProxyActionQueued'; queuedAt: string }; - -export type ProxyActionStatusVariables = Exact<{ - proxyActionId: Scalars['ProxyActionId']; -}>; - -export type ProxyActionStatusData = { - result: ProxyActionError | ProxyActionQueued | ProxyActionStatusResult; -}; - -export type ProxyActionVariables = Exact<{ - request: ProxyActionRequest; -}>; - -export type ProxyActionData = { result: string }; - -export type GetPublicationVariables = Exact<{ - request: PublicationQueryRequest; - observerId?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type GetPublicationData = { result: Comment | Mirror | Post | null }; - -export type HidePublicationVariables = Exact<{ - publicationId: Scalars['InternalPublicationId']; -}>; - -export type HidePublicationData = { hidePublication: void | null }; - -export type AddNotInterestedVariables = Exact<{ - request: PublicationProfileNotInterestedRequest; -}>; - -export type AddNotInterestedData = { result: void | null }; - -export type RemoveNotInterestedVariables = Exact<{ - request: PublicationProfileNotInterestedRequest; -}>; - -export type RemoveNotInterestedData = { result: void | null }; - -export type AddToMyBookmarksVariables = Exact<{ - request: PublicationProfileBookmarkRequest; -}>; - -export type AddToMyBookmarksData = { result: void | null }; - -export type RemoveFromMyBookmarksVariables = Exact<{ - request: PublicationProfileBookmarkRequest; -}>; - -export type RemoveFromMyBookmarksData = { result: void | null }; - -export type GetPublicationsVariables = Exact<{ - profileId?: InputMaybe; - profileIds?: InputMaybe | Scalars['ProfileId']>; - publicationIds?: InputMaybe< - Array | Scalars['InternalPublicationId'] - >; - observerId?: InputMaybe; - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - publicationTypes?: InputMaybe | PublicationTypes>; - sources: Array | Scalars['Sources']; - metadata?: InputMaybe; - commentsOf?: InputMaybe; - commentsOfOrdering?: InputMaybe; - commentsRankingFilter?: InputMaybe; - walletAddress?: InputMaybe; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type GetPublicationsData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type ExplorePublicationsVariables = Exact<{ - cursor?: InputMaybe; - excludeProfileIds?: InputMaybe | Scalars['ProfileId']>; - limit: Scalars['LimitScalar']; - metadata?: InputMaybe; - observerId?: InputMaybe; - publicationTypes?: InputMaybe | PublicationTypes>; - sortCriteria: PublicationSortCriteria; - sources: Array | Scalars['Sources']; - timestamp?: InputMaybe; - noRandomize?: InputMaybe; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type ExplorePublicationsData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type WhoCollectedPublicationVariables = Exact<{ - publicationId: Scalars['InternalPublicationId']; - observerId?: InputMaybe; - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type WhoCollectedPublicationData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type ProfilePublicationsForSaleVariables = Exact<{ - profileId: Scalars['ProfileId']; - observerId?: InputMaybe; - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type ProfilePublicationsForSaleData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type GetProfileBookmarksVariables = Exact<{ - profileId: Scalars['ProfileId']; - limit: Scalars['LimitScalar']; - sources: Array | Scalars['Sources']; - metadata?: InputMaybe; - cursor?: InputMaybe; - observerId?: InputMaybe; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type GetProfileBookmarksData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type AddReactionVariables = Exact<{ - publicationId: Scalars['InternalPublicationId']; - reaction: ReactionTypes; - profileId: Scalars['ProfileId']; -}>; - -export type AddReactionData = { addReaction: void | null }; - -export type RemoveReactionVariables = Exact<{ - publicationId: Scalars['InternalPublicationId']; - reaction: ReactionTypes; - profileId: Scalars['ProfileId']; -}>; - -export type RemoveReactionData = { removeReaction: void | null }; - -export type WhoReactedResult = { - __typename: 'WhoReactedResult'; - reactionId: unknown; - reaction: ReactionTypes; - reactionAt: string; - profile: Profile; -}; - -export type WhoReactedPublicationVariables = Exact<{ - limit?: InputMaybe; - cursor?: InputMaybe; - publicationId: Scalars['InternalPublicationId']; - observerId?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type WhoReactedPublicationData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type ReportPublicationVariables = Exact<{ - publicationId: Scalars['InternalPublicationId']; - reason: ReportingReasonInputParams; - additionalComments?: InputMaybe; -}>; - -export type ReportPublicationData = { reportPublication: void | null }; - -export type RevenueAggregate = { - __typename: 'RevenueAggregate'; - totalAmount: ClientErc20Amount; - __total: Erc20AmountFields; -}; - -export type PublicationRevenue = { - __typename: 'PublicationRevenue'; - publication: Comment | Mirror | Post; - revenue: RevenueAggregate; -}; - -export type GetPublicationRevenueVariables = Exact<{ - publicationId: Scalars['InternalPublicationId']; - observerId?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type GetPublicationRevenueData = { result: PublicationRevenue | null }; - -export type GetProfilePublicationRevenueVariables = Exact<{ - profileId: Scalars['ProfileId']; - observerId?: InputMaybe; - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - publicationTypes?: InputMaybe | PublicationTypes>; - sources: Array | Scalars['Sources']; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type GetProfilePublicationRevenueData = { - result: { items: Array; pageInfo: PaginatedResultInfo }; -}; - -export type ProfileFollowRevenue = { - __typename: 'FollowRevenueResult'; - revenues: Array; -}; - -export type ProfileFollowRevenueVariables = Exact<{ - profileId: Scalars['ProfileId']; -}>; - -export type ProfileFollowRevenueData = { result: ProfileFollowRevenue }; - -export type SearchPublicationsVariables = Exact<{ - limit?: InputMaybe; - cursor?: InputMaybe; - query: Scalars['Search']; - sources: Array | Scalars['Sources']; - observerId?: InputMaybe; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type SearchPublicationsData = { - result: - | { - __typename: 'PublicationSearchResult'; - items: Array; - pageInfo: PaginatedResultInfo; - } - | {}; -}; - -export type SearchProfilesVariables = Exact<{ - limit: Scalars['LimitScalar']; - cursor?: InputMaybe; - query: Scalars['Search']; - observerId?: InputMaybe; - sources: Array | Scalars['Sources']; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type SearchProfilesData = { - result: - | { __typename: 'ProfileSearchResult'; items: Array; pageInfo: PaginatedResultInfo } - | {}; -}; - -export type RelayerResult = { __typename: 'RelayerResult'; txHash: string; txId: string }; - -export type RelayError = { __typename: 'RelayError'; reason: RelayErrorReasons }; - -type BroadcastOnChainResult_RelayError_ = RelayError; - -type BroadcastOnChainResult_RelayerResult_ = RelayerResult; - -export type BroadcastOnChainResult = - | BroadcastOnChainResult_RelayError_ - | BroadcastOnChainResult_RelayerResult_; - -export type DataAvailabilityPublicationResult = { - __typename: 'CreateDataAvailabilityPublicationResult'; - id: PublicationId; - dataAvailabilityId: string; -}; - -type BroadcastOffChainResult_CreateDataAvailabilityPublicationResult_ = - DataAvailabilityPublicationResult; - -type BroadcastOffChainResult_RelayError_ = RelayError; - -export type BroadcastOffChainResult = - | BroadcastOffChainResult_CreateDataAvailabilityPublicationResult_ - | BroadcastOffChainResult_RelayError_; - -export type TransactionIndexedResult = { - __typename: 'TransactionIndexedResult'; - indexed: boolean; - txHash: string; -}; - -export type TransactionError = { __typename: 'TransactionError'; reason: TransactionErrorReasons }; - -export type HasTxHashBeenIndexedVariables = Exact<{ - request: HasTxHashBeenIndexedRequest; -}>; - -export type HasTxHashBeenIndexedData = { result: TransactionError | TransactionIndexedResult }; - -export type BroadcastOnChainVariables = Exact<{ - request: BroadcastRequest; -}>; - -export type BroadcastOnChainData = { - result: BroadcastOnChainResult_RelayError_ | BroadcastOnChainResult_RelayerResult_; -}; - -export type BroadcastOffChainVariables = Exact<{ - request: BroadcastRequest; -}>; - -export type BroadcastOffChainData = { - result: - | BroadcastOffChainResult_CreateDataAvailabilityPublicationResult_ - | BroadcastOffChainResult_RelayError_; -}; - -export type CreateUnfollowTypedDataVariables = Exact<{ - request: UnfollowRequest; -}>; - -export type CreateUnfollowTypedDataData = { - result: { - id: string; - expiresAt: string; - typedData: { - types: { BurnWithSig: Array<{ name: string; type: string }> }; - domain: Eip712TypedDataDomain; - message: { nonce: number; deadline: unknown; tokenId: string }; - }; - }; -}; - -export const FragmentEip712TypedDataDomain = /*#__PURE__*/ gql` - fragment EIP712TypedDataDomain on EIP712TypedDataDomain { - __typename - name - chainId - version - verifyingContract - } -`; -export const FragmentCreateCommentEip712TypedData = /*#__PURE__*/ gql` - fragment CreateCommentEIP712TypedData on CreateCommentEIP712TypedData { - types { - CommentWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - profileId - contentURI - profileIdPointed - pubIdPointed - collectModule - collectModuleInitData - referenceModuleData - referenceModule - referenceModuleInitData - } - } - ${FragmentEip712TypedDataDomain} -`; -export const FragmentPaginatedResultInfo = /*#__PURE__*/ gql` - fragment PaginatedResultInfo on PaginatedResultInfo { - __typename - moreAfter @client - prev - next - totalCount - } -`; -export const FragmentPublicationStats = /*#__PURE__*/ gql` - fragment PublicationStats on PublicationStats { - __typename - totalAmountOfMirrors - totalUpvotes - totalDownvotes - totalAmountOfCollects - totalAmountOfComments - totalBookmarks - commentsCount: commentsTotal(forSources: $sources) - } -`; -export const FragmentMedia = /*#__PURE__*/ gql` - fragment Media on Media { - __typename - altTag - cover - mimeType - url - } -`; -export const FragmentPublicationMediaSet = /*#__PURE__*/ gql` - fragment PublicationMediaSet on MediaSet { - __typename - original { - ...Media - } - optimized { - ...Media - } - small: transformed(params: $mediaTransformPublicationSmall) { - ...Media - } - medium: transformed(params: $mediaTransformPublicationMedium) { - ...Media - } - } - ${FragmentMedia} -`; -export const FragmentMetadataAttributeOutput = /*#__PURE__*/ gql` - fragment MetadataAttributeOutput on MetadataAttributeOutput { - __typename - traitType - value - } -`; -export const FragmentNftOwnershipOutput = /*#__PURE__*/ gql` - fragment NftOwnershipOutput on NftOwnershipOutput { - __typename - contractAddress - chainID - contractType - tokenIds - } -`; -export const FragmentErc20OwnershipOutput = /*#__PURE__*/ gql` - fragment Erc20OwnershipOutput on Erc20OwnershipOutput { - __typename - amount - chainID - condition - contractAddress - decimals - name - symbol - } -`; -export const FragmentEoaOwnershipOutput = /*#__PURE__*/ gql` - fragment EoaOwnershipOutput on EoaOwnershipOutput { - __typename - address - } -`; -export const FragmentProfileOwnershipOutput = /*#__PURE__*/ gql` - fragment ProfileOwnershipOutput on ProfileOwnershipOutput { - __typename - profileId - } -`; -export const FragmentFollowConditionOutput = /*#__PURE__*/ gql` - fragment FollowConditionOutput on FollowConditionOutput { - __typename - profileId - } -`; -export const FragmentCollectConditionOutput = /*#__PURE__*/ gql` - fragment CollectConditionOutput on CollectConditionOutput { - __typename - publicationId - thisPublication - } -`; -export const FragmentLeafConditionOutput = /*#__PURE__*/ gql` - fragment LeafConditionOutput on AccessConditionOutput { - __typename - nft { - ...NftOwnershipOutput - } - token { - ...Erc20OwnershipOutput - } - eoa { - ...EoaOwnershipOutput - } - profile { - ...ProfileOwnershipOutput - } - follow { - ...FollowConditionOutput - } - collect { - ...CollectConditionOutput - } - } - ${FragmentNftOwnershipOutput} - ${FragmentErc20OwnershipOutput} - ${FragmentEoaOwnershipOutput} - ${FragmentProfileOwnershipOutput} - ${FragmentFollowConditionOutput} - ${FragmentCollectConditionOutput} -`; -export const FragmentOrConditionOutput = /*#__PURE__*/ gql` - fragment OrConditionOutput on OrConditionOutput { - __typename - criteria { - ...LeafConditionOutput - } - } - ${FragmentLeafConditionOutput} -`; -export const FragmentAndConditionOutput = /*#__PURE__*/ gql` - fragment AndConditionOutput on AndConditionOutput { - __typename - criteria { - ...LeafConditionOutput - } - } - ${FragmentLeafConditionOutput} -`; -export const FragmentAnyConditionOutput = /*#__PURE__*/ gql` - fragment AnyConditionOutput on AccessConditionOutput { - __typename - ...LeafConditionOutput - or { - ...OrConditionOutput - } - and { - ...AndConditionOutput - } - } - ${FragmentLeafConditionOutput} - ${FragmentOrConditionOutput} - ${FragmentAndConditionOutput} -`; -export const FragmentRootConditionOutput = /*#__PURE__*/ gql` - fragment RootConditionOutput on AccessConditionOutput { - __typename - or { - criteria { - ...AnyConditionOutput - } - } - } - ${FragmentAnyConditionOutput} -`; -export const FragmentEncryptedMedia = /*#__PURE__*/ gql` - fragment EncryptedMedia on EncryptedMedia { - __typename - altTag - cover - mimeType - url - } -`; -export const FragmentEncryptedFieldsOutput = /*#__PURE__*/ gql` - fragment EncryptedFieldsOutput on EncryptedFieldsOutput { - __typename - animation_url - content - external_url - image - media { - original { - ...EncryptedMedia - } - } - } - ${FragmentEncryptedMedia} -`; -export const FragmentEncryptionParamsOutput = /*#__PURE__*/ gql` - fragment EncryptionParamsOutput on EncryptionParamsOutput { - __typename - accessCondition { - ...RootConditionOutput - } - encryptionProvider - encryptedFields { - ...EncryptedFieldsOutput - } - providerSpecificParams { - encryptionKey - } - } - ${FragmentRootConditionOutput} - ${FragmentEncryptedFieldsOutput} -`; -export const FragmentMetadataOutput = /*#__PURE__*/ gql` - fragment MetadataOutput on MetadataOutput { - __typename - animatedUrl - content - contentWarning - description - image - locale - mainContentFocus - name - media { - ...PublicationMediaSet - } - attributes { - ...MetadataAttributeOutput - } - encryptionParams { - ...EncryptionParamsOutput - } - tags - } - ${FragmentPublicationMediaSet} - ${FragmentMetadataAttributeOutput} - ${FragmentEncryptionParamsOutput} -`; -export const FragmentNftImage = /*#__PURE__*/ gql` - fragment NftImage on NftImage { - __typename - contractAddress - tokenId - uri - verified - } -`; -export const FragmentProfilePictureSet = /*#__PURE__*/ gql` - fragment ProfilePictureSet on MediaSet { - __typename - original { - ...Media - } - optimized { - ...Media - } - thumbnail: transformed(params: $mediaTransformProfileThumbnail) { - ...Media - } - } - ${FragmentMedia} -`; -export const FragmentProfileCoverSet = /*#__PURE__*/ gql` - fragment ProfileCoverSet on MediaSet { - __typename - original { - ...Media - } - optimized { - ...Media - } - } - ${FragmentMedia} -`; -export const FragmentProfileStats = /*#__PURE__*/ gql` - fragment ProfileStats on ProfileStats { - __typename - totalCollects - totalComments - totalFollowers - totalFollowing - totalMirrors - totalPosts - totalPublications - commentsCount: commentsTotal(forSources: $sources) - postsCount: postsTotal(forSources: $sources) - mirrorsCount: mirrorsTotal(forSources: $sources) - } -`; -export const FragmentErc20Fields = /*#__PURE__*/ gql` - fragment Erc20Fields on Erc20 { - __typename - name - symbol - decimals - address - } -`; -export const FragmentModuleFeeAmount = /*#__PURE__*/ gql` - fragment ModuleFeeAmount on ModuleFeeAmount { - __typename - asset { - ...Erc20Fields - } - value - } - ${FragmentErc20Fields} -`; -export const FragmentFeeFollowModuleSettings = /*#__PURE__*/ gql` - fragment FeeFollowModuleSettings on FeeFollowModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - contractAddress - recipient - } - ${FragmentModuleFeeAmount} -`; -export const FragmentProfileFollowModuleSettings = /*#__PURE__*/ gql` - fragment ProfileFollowModuleSettings on ProfileFollowModuleSettings { - __typename - contractAddress - } -`; -export const FragmentRevertFollowModuleSettings = /*#__PURE__*/ gql` - fragment RevertFollowModuleSettings on RevertFollowModuleSettings { - __typename - contractAddress - } -`; -export const FragmentUnknownFollowModuleSettings = /*#__PURE__*/ gql` - fragment UnknownFollowModuleSettings on UnknownFollowModuleSettings { - __typename - contractAddress - } -`; -export const FragmentAttribute = /*#__PURE__*/ gql` - fragment Attribute on Attribute { - __typename - displayType - key - value - } -`; -export const FragmentProfileFields = /*#__PURE__*/ gql` - fragment ProfileFields on Profile { - __typename - id - name - bio - handle - ownedBy - interests - followNftAddress - picture { - ... on NftImage { - ...NftImage - } - ... on MediaSet { - ...ProfilePictureSet - } - } - coverPicture { - ... on NftImage { - ...NftImage - } - ... on MediaSet { - ...ProfileCoverSet - } - } - stats { - ...ProfileStats - } - followModule { - ... on FeeFollowModuleSettings { - ...FeeFollowModuleSettings - } - ... on ProfileFollowModuleSettings { - ...ProfileFollowModuleSettings - } - ... on RevertFollowModuleSettings { - ...RevertFollowModuleSettings - } - ... on UnknownFollowModuleSettings { - ...UnknownFollowModuleSettings - } - } - followPolicy @client - __attributes: attributes { - ...Attribute - } - attributes: attributesMap @client - dispatcher { - address - canUseRelay - } - onChainIdentity { - proofOfHumanity - ens { - name - } - sybilDotOrg { - verified - source { - twitter { - handle - } - } - } - worldcoin { - isHuman - } - } - isFollowedByMe - isFollowingObserver: isFollowing(who: $observerId) - followStatus @client - ownedByMe @client - observedBy @client - } - ${FragmentNftImage} - ${FragmentProfilePictureSet} - ${FragmentProfileCoverSet} - ${FragmentProfileStats} - ${FragmentFeeFollowModuleSettings} - ${FragmentProfileFollowModuleSettings} - ${FragmentRevertFollowModuleSettings} - ${FragmentUnknownFollowModuleSettings} - ${FragmentAttribute} -`; -export const FragmentProfile = /*#__PURE__*/ gql` - fragment Profile on Profile { - ...ProfileFields - invitedBy { - ...ProfileFields - } - } - ${FragmentProfileFields} -`; -export const FragmentWallet = /*#__PURE__*/ gql` - fragment Wallet on Wallet { - __typename - address - defaultProfile { - ...Profile - } - } - ${FragmentProfile} -`; -export const FragmentAaveFeeCollectModuleSettings = /*#__PURE__*/ gql` - fragment AaveFeeCollectModuleSettings on AaveFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimitOptional: collectLimit - contractAddress - followerOnly - endTimestampOptional: endTimestamp - recipient - referralFee - } - ${FragmentModuleFeeAmount} -`; -export const FragmentErc4626FeeCollectModuleSettings = /*#__PURE__*/ gql` - fragment Erc4626FeeCollectModuleSettings on ERC4626FeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimitOptional: collectLimit - contractAddress - followerOnly - endTimestampOptional: endTimestamp - recipient - referralFee - vault - } - ${FragmentModuleFeeAmount} -`; -export const FragmentMultirecipientFeeCollectModuleSettings = /*#__PURE__*/ gql` - fragment MultirecipientFeeCollectModuleSettings on MultirecipientFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimitOptional: collectLimit - contractAddress - followerOnly - endTimestampOptional: endTimestamp - recipients { - recipient - split - } - referralFee - } - ${FragmentModuleFeeAmount} -`; -export const FragmentUnknownCollectModuleSettings = /*#__PURE__*/ gql` - fragment UnknownCollectModuleSettings on UnknownCollectModuleSettings { - __typename - contractAddress - collectModuleReturnData - } -`; -export const FragmentFreeCollectModuleSettings = /*#__PURE__*/ gql` - fragment FreeCollectModuleSettings on FreeCollectModuleSettings { - __typename - contractAddress - followerOnly - } -`; -export const FragmentFeeCollectModuleSettings = /*#__PURE__*/ gql` - fragment FeeCollectModuleSettings on FeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - contractAddress - followerOnly - recipient - referralFee - } - ${FragmentModuleFeeAmount} -`; -export const FragmentLimitedFeeCollectModuleSettings = /*#__PURE__*/ gql` - fragment LimitedFeeCollectModuleSettings on LimitedFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimit - contractAddress - followerOnly - recipient - referralFee - } - ${FragmentModuleFeeAmount} -`; -export const FragmentLimitedTimedFeeCollectModuleSettings = /*#__PURE__*/ gql` - fragment LimitedTimedFeeCollectModuleSettings on LimitedTimedFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - collectLimit - contractAddress - followerOnly - endTimestamp - recipient - referralFee - } - ${FragmentModuleFeeAmount} -`; -export const FragmentRevertCollectModuleSettings = /*#__PURE__*/ gql` - fragment RevertCollectModuleSettings on RevertCollectModuleSettings { - __typename - contractAddress - } -`; -export const FragmentTimedFeeCollectModuleSettings = /*#__PURE__*/ gql` - fragment TimedFeeCollectModuleSettings on TimedFeeCollectModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - contractAddress - followerOnly - endTimestamp - recipient - referralFee - } - ${FragmentModuleFeeAmount} -`; -export const FragmentSimpleCollectModuleSettings = /*#__PURE__*/ gql` - fragment SimpleCollectModuleSettings on SimpleCollectModuleSettings { - __typename - contractAddress - followerOnly - feeOptional: fee { - amount { - ...ModuleFeeAmount - } - referralFee - recipient - } - collectLimitOptional: collectLimit - endTimestampOptional: endTimestamp - } - ${FragmentModuleFeeAmount} -`; -export const FragmentFollowOnlyReferenceModuleSettings = /*#__PURE__*/ gql` - fragment FollowOnlyReferenceModuleSettings on FollowOnlyReferenceModuleSettings { - __typename - contractAddress - } -`; -export const FragmentDegreesOfSeparationReferenceModuleSettings = /*#__PURE__*/ gql` - fragment DegreesOfSeparationReferenceModuleSettings on DegreesOfSeparationReferenceModuleSettings { - __typename - contractAddress - commentsRestricted - degreesOfSeparation - mirrorsRestricted - } -`; -export const FragmentUnknownReferenceModuleSettings = /*#__PURE__*/ gql` - fragment UnknownReferenceModuleSettings on UnknownReferenceModuleSettings { - __typename - contractAddress - referenceModuleReturnData - } -`; -export const FragmentCommentBase = /*#__PURE__*/ gql` - fragment CommentBase on Comment { - __typename - id - appId - stats { - ...PublicationStats - } - metadata { - ...MetadataOutput - } - profile { - ...Profile - } - collectedBy { - ...Wallet - } - collectModule { - ... on AaveFeeCollectModuleSettings { - ...AaveFeeCollectModuleSettings - } - ... on ERC4626FeeCollectModuleSettings { - ...Erc4626FeeCollectModuleSettings - } - ... on MultirecipientFeeCollectModuleSettings { - ...MultirecipientFeeCollectModuleSettings - } - ... on UnknownCollectModuleSettings { - ...UnknownCollectModuleSettings - } - ... on FreeCollectModuleSettings { - ...FreeCollectModuleSettings - } - ... on FeeCollectModuleSettings { - ...FeeCollectModuleSettings - } - ... on LimitedFeeCollectModuleSettings { - ...LimitedFeeCollectModuleSettings - } - ... on LimitedTimedFeeCollectModuleSettings { - ...LimitedTimedFeeCollectModuleSettings - } - ... on RevertCollectModuleSettings { - ...RevertCollectModuleSettings - } - ... on TimedFeeCollectModuleSettings { - ...TimedFeeCollectModuleSettings - } - ... on SimpleCollectModuleSettings { - ...SimpleCollectModuleSettings - } - } - collectNftAddress - referenceModule { - ... on FollowOnlyReferenceModuleSettings { - ...FollowOnlyReferenceModuleSettings - } - ... on DegreesOfSeparationReferenceModuleSettings { - ...DegreesOfSeparationReferenceModuleSettings - } - ... on UnknownReferenceModuleSettings { - ...UnknownReferenceModuleSettings - } - } - createdAt - hidden - isGated - reaction(request: { profileId: $observerId }) - hasCollectedByMe - canComment(profileId: $observerId) { - result - } - canMirror(profileId: $observerId) { - result - } - canObserverDecrypt: canDecrypt(profileId: $observerId) { - result - reasons - } - mirrors(by: $observerId) - notInterested(by: $observerId) - bookmarked(by: $observerId) - hasOptimisticCollectedByMe @client - isOptimisticMirroredByMe @client - isMirroredByMe @client - collectPolicy @client - referencePolicy @client - decryptionCriteria @client - contentInsight @client - observedBy @client - } - ${FragmentPublicationStats} - ${FragmentMetadataOutput} - ${FragmentProfile} - ${FragmentWallet} - ${FragmentAaveFeeCollectModuleSettings} - ${FragmentErc4626FeeCollectModuleSettings} - ${FragmentMultirecipientFeeCollectModuleSettings} - ${FragmentUnknownCollectModuleSettings} - ${FragmentFreeCollectModuleSettings} - ${FragmentFeeCollectModuleSettings} - ${FragmentLimitedFeeCollectModuleSettings} - ${FragmentLimitedTimedFeeCollectModuleSettings} - ${FragmentRevertCollectModuleSettings} - ${FragmentTimedFeeCollectModuleSettings} - ${FragmentSimpleCollectModuleSettings} - ${FragmentFollowOnlyReferenceModuleSettings} - ${FragmentDegreesOfSeparationReferenceModuleSettings} - ${FragmentUnknownReferenceModuleSettings} -`; -export const FragmentPost = /*#__PURE__*/ gql` - fragment Post on Post { - __typename - id - appId - stats { - ...PublicationStats - } - metadata { - ...MetadataOutput - } - profile { - ...Profile - } - collectedBy { - ...Wallet - } - collectModule { - ... on AaveFeeCollectModuleSettings { - ...AaveFeeCollectModuleSettings - } - ... on ERC4626FeeCollectModuleSettings { - ...Erc4626FeeCollectModuleSettings - } - ... on MultirecipientFeeCollectModuleSettings { - ...MultirecipientFeeCollectModuleSettings - } - ... on UnknownCollectModuleSettings { - ...UnknownCollectModuleSettings - } - ... on FreeCollectModuleSettings { - ...FreeCollectModuleSettings - } - ... on FeeCollectModuleSettings { - ...FeeCollectModuleSettings - } - ... on LimitedFeeCollectModuleSettings { - ...LimitedFeeCollectModuleSettings - } - ... on LimitedTimedFeeCollectModuleSettings { - ...LimitedTimedFeeCollectModuleSettings - } - ... on RevertCollectModuleSettings { - ...RevertCollectModuleSettings - } - ... on TimedFeeCollectModuleSettings { - ...TimedFeeCollectModuleSettings - } - ... on SimpleCollectModuleSettings { - ...SimpleCollectModuleSettings - } - } - collectNftAddress - referenceModule { - ... on FollowOnlyReferenceModuleSettings { - ...FollowOnlyReferenceModuleSettings - } - ... on DegreesOfSeparationReferenceModuleSettings { - ...DegreesOfSeparationReferenceModuleSettings - } - ... on UnknownReferenceModuleSettings { - ...UnknownReferenceModuleSettings - } - } - createdAt - hidden - isGated - reaction(request: { profileId: $observerId }) - hasCollectedByMe - canComment(profileId: $observerId) { - result - } - canMirror(profileId: $observerId) { - result - } - canObserverDecrypt: canDecrypt(profileId: $observerId) { - result - reasons - } - mirrors(by: $observerId) - notInterested(by: $observerId) - bookmarked(by: $observerId) - hasOptimisticCollectedByMe @client - isOptimisticMirroredByMe @client - isMirroredByMe @client - collectPolicy @client - referencePolicy @client - decryptionCriteria @client - contentInsight @client - observedBy @client - } - ${FragmentPublicationStats} - ${FragmentMetadataOutput} - ${FragmentProfile} - ${FragmentWallet} - ${FragmentAaveFeeCollectModuleSettings} - ${FragmentErc4626FeeCollectModuleSettings} - ${FragmentMultirecipientFeeCollectModuleSettings} - ${FragmentUnknownCollectModuleSettings} - ${FragmentFreeCollectModuleSettings} - ${FragmentFeeCollectModuleSettings} - ${FragmentLimitedFeeCollectModuleSettings} - ${FragmentLimitedTimedFeeCollectModuleSettings} - ${FragmentRevertCollectModuleSettings} - ${FragmentTimedFeeCollectModuleSettings} - ${FragmentSimpleCollectModuleSettings} - ${FragmentFollowOnlyReferenceModuleSettings} - ${FragmentDegreesOfSeparationReferenceModuleSettings} - ${FragmentUnknownReferenceModuleSettings} -`; -export const FragmentMirrorBase = /*#__PURE__*/ gql` - fragment MirrorBase on Mirror { - __typename - id - createdAt - profile { - ...Profile - } - hidden - } - ${FragmentProfile} -`; -export const FragmentComment = /*#__PURE__*/ gql` - fragment Comment on Comment { - __typename - ...CommentBase - commentOn { - ... on Post { - ...Post - } - ... on Mirror { - ...MirrorBase - } - ... on Comment { - ...CommentBase - } - } - mainPost { - ... on Post { - ...Post - } - ... on Mirror { - ...MirrorBase - } - } - firstComment { - ...CommentBase - } - } - ${FragmentCommentBase} - ${FragmentPost} - ${FragmentMirrorBase} -`; -export const FragmentMirror = /*#__PURE__*/ gql` - fragment Mirror on Mirror { - __typename - ...MirrorBase - mirrorOf { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - } - } - ${FragmentMirrorBase} - ${FragmentPost} - ${FragmentComment} -`; -export const FragmentPublication = /*#__PURE__*/ gql` - fragment Publication on Publication { - ... on Comment { - ...Comment - } - ... on Post { - ...Post - } - ... on Mirror { - ...Mirror - } - } - ${FragmentComment} - ${FragmentPost} - ${FragmentMirror} -`; -export const FragmentPendingPost = /*#__PURE__*/ gql` - fragment PendingPost on PendingPost { - __typename - id - content - media { - ...Media - } - profile { - ...Profile - } - locale - mainContentFocus - } - ${FragmentMedia} - ${FragmentProfile} -`; -export const FragmentElectedMirror = /*#__PURE__*/ gql` - fragment ElectedMirror on ElectedMirror { - __typename - mirrorId - profile { - ...Profile - } - timestamp - } - ${FragmentProfile} -`; -export const FragmentMirrorEvent = /*#__PURE__*/ gql` - fragment MirrorEvent on MirrorEvent { - __typename - profile { - ...Profile - } - timestamp - } - ${FragmentProfile} -`; -export const FragmentCollectedEvent = /*#__PURE__*/ gql` - fragment CollectedEvent on CollectedEvent { - __typename - profile { - ...Profile - } - timestamp - } - ${FragmentProfile} -`; -export const FragmentReactionEvent = /*#__PURE__*/ gql` - fragment ReactionEvent on ReactionEvent { - __typename - profile { - ...Profile - } - reaction - timestamp - } - ${FragmentProfile} -`; -export const FragmentFeedItem = /*#__PURE__*/ gql` - fragment FeedItem on FeedItem { - __typename - root { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - } - comments { - ...Comment - } - electedMirror { - ...ElectedMirror - } - mirrors { - ...MirrorEvent - } - collects { - ...CollectedEvent - } - reactions { - ...ReactionEvent - } - } - ${FragmentPost} - ${FragmentComment} - ${FragmentElectedMirror} - ${FragmentMirrorEvent} - ${FragmentCollectedEvent} - ${FragmentReactionEvent} -`; -export const FragmentEncryptedMediaSet = /*#__PURE__*/ gql` - fragment EncryptedMediaSet on EncryptedMediaSet { - __typename - original { - ...EncryptedMedia - } - } - ${FragmentEncryptedMedia} -`; -export const FragmentCreateMirrorEip712TypedData = /*#__PURE__*/ gql` - fragment CreateMirrorEIP712TypedData on CreateMirrorEIP712TypedData { - types { - MirrorWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - profileId - profileIdPointed - pubIdPointed - referenceModuleData - referenceModule - referenceModuleInitData - } - } - ${FragmentEip712TypedDataDomain} -`; -export const FragmentModuleInfo = /*#__PURE__*/ gql` - fragment ModuleInfo on ModuleInfo { - __typename - name - type - } -`; -export const FragmentEnabledModule = /*#__PURE__*/ gql` - fragment EnabledModule on EnabledModule { - __typename - moduleName - contractAddress - inputParams { - ...ModuleInfo - } - redeemParams { - ...ModuleInfo - } - returnDataParams: returnDataParms { - ...ModuleInfo - } - } - ${FragmentModuleInfo} -`; -export const FragmentEnabledModules = /*#__PURE__*/ gql` - fragment EnabledModules on EnabledModules { - __typename - collectModules { - ...EnabledModule - } - followModules { - ...EnabledModule - } - referenceModules { - ...EnabledModule - } - } - ${FragmentEnabledModule} -`; -export const FragmentNewFollowerNotification = /*#__PURE__*/ gql` - fragment NewFollowerNotification on NewFollowerNotification { - __typename - notificationId - createdAt - isFollowedByMe - wallet { - ...Wallet - } - } - ${FragmentWallet} -`; -export const FragmentNewCollectNotification = /*#__PURE__*/ gql` - fragment NewCollectNotification on NewCollectNotification { - __typename - notificationId - createdAt - wallet { - ...Wallet - } - collectedPublication { - ... on Post { - ...Post - } - ... on Mirror { - ...Mirror - } - ... on Comment { - ...Comment - } - } - } - ${FragmentWallet} - ${FragmentPost} - ${FragmentMirror} - ${FragmentComment} -`; -export const FragmentNewMirrorNotification = /*#__PURE__*/ gql` - fragment NewMirrorNotification on NewMirrorNotification { - __typename - notificationId - createdAt - profile { - ...Profile - } - publication { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - } - } - ${FragmentProfile} - ${FragmentPost} - ${FragmentComment} -`; -export const FragmentNewCommentNotification = /*#__PURE__*/ gql` - fragment NewCommentNotification on NewCommentNotification { - __typename - notificationId - createdAt - profile { - ...Profile - } - comment { - ...Comment - } - } - ${FragmentProfile} - ${FragmentComment} -`; -export const FragmentNewMentionNotification = /*#__PURE__*/ gql` - fragment NewMentionNotification on NewMentionNotification { - __typename - notificationId - createdAt - mentionPublication { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - } - } - ${FragmentPost} - ${FragmentComment} -`; -export const FragmentNewReactionNotification = /*#__PURE__*/ gql` - fragment NewReactionNotification on NewReactionNotification { - __typename - notificationId - createdAt - profile { - ...Profile - } - reaction - publication { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - ... on Mirror { - ...Mirror - } - } - } - ${FragmentProfile} - ${FragmentPost} - ${FragmentComment} - ${FragmentMirror} -`; -export const FragmentCreatePostEip712TypedData = /*#__PURE__*/ gql` - fragment CreatePostEIP712TypedData on CreatePostEIP712TypedData { - types { - PostWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - profileId - contentURI - collectModule - collectModuleInitData - referenceModule - referenceModuleInitData - } - } - ${FragmentEip712TypedDataDomain} -`; -export const FragmentProfileGuardianResult = /*#__PURE__*/ gql` - fragment ProfileGuardianResult on ProfileGuardianResult { - protected - disablingProtectionTimestamp - } -`; -export const FragmentFollower = /*#__PURE__*/ gql` - fragment Follower on Follower { - __typename - wallet { - ...Wallet - } - } - ${FragmentWallet} -`; -export const FragmentFollowing = /*#__PURE__*/ gql` - fragment Following on Following { - __typename - profile { - ...Profile - } - } - ${FragmentProfile} -`; -export const FragmentProxyActionStatusResult = /*#__PURE__*/ gql` - fragment ProxyActionStatusResult on ProxyActionStatusResult { - __typename - txHash - txId - status - } -`; -export const FragmentProxyActionError = /*#__PURE__*/ gql` - fragment ProxyActionError on ProxyActionError { - __typename - reason - lastKnownTxId - } -`; -export const FragmentProxyActionQueued = /*#__PURE__*/ gql` - fragment ProxyActionQueued on ProxyActionQueued { - __typename - queuedAt - } -`; -export const FragmentWhoReactedResult = /*#__PURE__*/ gql` - fragment WhoReactedResult on WhoReactedResult { - __typename - reactionId - reaction - reactionAt - profile { - ...Profile - } - } - ${FragmentProfile} -`; -export const FragmentErc20AmountFields = /*#__PURE__*/ gql` - fragment Erc20AmountFields on Erc20Amount { - __typename - asset { - ...Erc20Fields - } - value - } - ${FragmentErc20Fields} -`; -export const FragmentRevenueAggregate = /*#__PURE__*/ gql` - fragment RevenueAggregate on RevenueAggregate { - __typename - __total: total { - ...Erc20AmountFields - } - totalAmount @client - } - ${FragmentErc20AmountFields} -`; -export const FragmentPublicationRevenue = /*#__PURE__*/ gql` - fragment PublicationRevenue on PublicationRevenue { - __typename - publication { - ... on Post { - ...Post - } - ... on Mirror { - ...Mirror - } - ... on Comment { - ...Comment - } - } - revenue { - ...RevenueAggregate - } - } - ${FragmentPost} - ${FragmentMirror} - ${FragmentComment} - ${FragmentRevenueAggregate} -`; -export const FragmentProfileFollowRevenue = /*#__PURE__*/ gql` - fragment ProfileFollowRevenue on FollowRevenueResult { - __typename - revenues { - ...RevenueAggregate - } - } - ${FragmentRevenueAggregate} -`; -export const FragmentRelayerResult = /*#__PURE__*/ gql` - fragment RelayerResult on RelayerResult { - __typename - txHash - txId - } -`; -export const FragmentRelayError = /*#__PURE__*/ gql` - fragment RelayError on RelayError { - __typename - reason - } -`; -export const FragmentBroadcastOnChainResult = /*#__PURE__*/ gql` - fragment BroadcastOnChainResult on RelayResult { - ... on RelayerResult { - ...RelayerResult - } - ... on RelayError { - ...RelayError - } - } - ${FragmentRelayerResult} - ${FragmentRelayError} -`; -export const FragmentDataAvailabilityPublicationResult = /*#__PURE__*/ gql` - fragment DataAvailabilityPublicationResult on CreateDataAvailabilityPublicationResult { - __typename - id - dataAvailabilityId - } -`; -export const FragmentBroadcastOffChainResult = /*#__PURE__*/ gql` - fragment BroadcastOffChainResult on BroadcastDataAvailabilityUnion { - ... on CreateDataAvailabilityPublicationResult { - ...DataAvailabilityPublicationResult - } - ... on RelayError { - ...RelayError - } - } - ${FragmentDataAvailabilityPublicationResult} - ${FragmentRelayError} -`; -export const FragmentTransactionIndexedResult = /*#__PURE__*/ gql` - fragment TransactionIndexedResult on TransactionIndexedResult { - __typename - indexed - txHash - } -`; -export const FragmentTransactionError = /*#__PURE__*/ gql` - fragment TransactionError on TransactionError { - __typename - reason - } -`; -export const AuthChallengeDocument = /*#__PURE__*/ gql` - query AuthChallenge($address: EthereumAddress!) { - result: challenge(request: { address: $address }) { - text - } - } -`; - -/** - * __useAuthChallenge__ - * - * To run a query within a React component, call `useAuthChallenge` and pass it any options that fit your needs. - * When your component renders, `useAuthChallenge` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useAuthChallenge({ - * variables: { - * address: // value for 'address' - * }, - * }); - */ -export function useAuthChallenge( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery(AuthChallengeDocument, options); -} -export function useAuthChallengeLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - AuthChallengeDocument, - options, - ); -} -export type AuthChallengeHookResult = ReturnType; -export type AuthChallengeLazyQueryHookResult = ReturnType; -export type AuthChallengeQueryResult = Apollo.QueryResult< - AuthChallengeData, - AuthChallengeVariables ->; -export const AuthAuthenticateDocument = /*#__PURE__*/ gql` - mutation AuthAuthenticate($address: EthereumAddress!, $signature: Signature!) { - result: authenticate(request: { address: $address, signature: $signature }) { - accessToken - refreshToken - } - } -`; -export type AuthAuthenticateMutationFn = Apollo.MutationFunction< - AuthAuthenticateData, - AuthAuthenticateVariables ->; - -/** - * __useAuthAuthenticate__ - * - * To run a mutation, you first call `useAuthAuthenticate` within a React component and pass it any options that fit your needs. - * When your component renders, `useAuthAuthenticate` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [authAuthenticate, { data, loading, error }] = useAuthAuthenticate({ - * variables: { - * address: // value for 'address' - * signature: // value for 'signature' - * }, - * }); - */ -export function useAuthAuthenticate( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - AuthAuthenticateDocument, - options, - ); -} -export type AuthAuthenticateHookResult = ReturnType; -export type AuthAuthenticateMutationResult = Apollo.MutationResult; -export type AuthAuthenticateMutationOptions = Apollo.BaseMutationOptions< - AuthAuthenticateData, - AuthAuthenticateVariables ->; -export const AuthRefreshDocument = /*#__PURE__*/ gql` - mutation AuthRefresh($refreshToken: Jwt!) { - result: refresh(request: { refreshToken: $refreshToken }) { - accessToken - refreshToken - } - } -`; -export type AuthRefreshMutationFn = Apollo.MutationFunction; - -/** - * __useAuthRefresh__ - * - * To run a mutation, you first call `useAuthRefresh` within a React component and pass it any options that fit your needs. - * When your component renders, `useAuthRefresh` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [authRefresh, { data, loading, error }] = useAuthRefresh({ - * variables: { - * refreshToken: // value for 'refreshToken' - * }, - * }); - */ -export function useAuthRefresh( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation(AuthRefreshDocument, options); -} -export type AuthRefreshHookResult = ReturnType; -export type AuthRefreshMutationResult = Apollo.MutationResult; -export type AuthRefreshMutationOptions = Apollo.BaseMutationOptions< - AuthRefreshData, - AuthRefreshVariables ->; -export const CreateCollectTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateCollectTypedData($request: CreateCollectRequest!, $options: TypedDataOptions) { - result: createCollectTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - CollectWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - profileId - pubId - data - } - } - } - } - ${FragmentEip712TypedDataDomain} -`; -export type CreateCollectTypedDataMutationFn = Apollo.MutationFunction< - CreateCollectTypedDataData, - CreateCollectTypedDataVariables ->; - -/** - * __useCreateCollectTypedData__ - * - * To run a mutation, you first call `useCreateCollectTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateCollectTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createCollectTypedData, { data, loading, error }] = useCreateCollectTypedData({ - * variables: { - * request: // value for 'request' - * options: // value for 'options' - * }, - * }); - */ -export function useCreateCollectTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateCollectTypedDataData, - CreateCollectTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - CreateCollectTypedDataDocument, - options, - ); -} -export type CreateCollectTypedDataHookResult = ReturnType; -export type CreateCollectTypedDataMutationResult = - Apollo.MutationResult; -export type CreateCollectTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateCollectTypedDataData, - CreateCollectTypedDataVariables ->; -export const CreateCommentTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateCommentTypedData( - $request: CreatePublicCommentRequest! - $options: TypedDataOptions - ) { - result: createCommentTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - ...CreateCommentEIP712TypedData - } - } - } - ${FragmentCreateCommentEip712TypedData} -`; -export type CreateCommentTypedDataMutationFn = Apollo.MutationFunction< - CreateCommentTypedDataData, - CreateCommentTypedDataVariables ->; - -/** - * __useCreateCommentTypedData__ - * - * To run a mutation, you first call `useCreateCommentTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateCommentTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createCommentTypedData, { data, loading, error }] = useCreateCommentTypedData({ - * variables: { - * request: // value for 'request' - * options: // value for 'options' - * }, - * }); - */ -export function useCreateCommentTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateCommentTypedDataData, - CreateCommentTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - CreateCommentTypedDataDocument, - options, - ); -} -export type CreateCommentTypedDataHookResult = ReturnType; -export type CreateCommentTypedDataMutationResult = - Apollo.MutationResult; -export type CreateCommentTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateCommentTypedDataData, - CreateCommentTypedDataVariables ->; -export const CreateCommentViaDispatcherDocument = /*#__PURE__*/ gql` - mutation CreateCommentViaDispatcher($request: CreatePublicCommentRequest!) { - result: createCommentViaDispatcher(request: $request) { - ...BroadcastOnChainResult - } - } - ${FragmentBroadcastOnChainResult} -`; -export type CreateCommentViaDispatcherMutationFn = Apollo.MutationFunction< - CreateCommentViaDispatcherData, - CreateCommentViaDispatcherVariables ->; - -/** - * __useCreateCommentViaDispatcher__ - * - * To run a mutation, you first call `useCreateCommentViaDispatcher` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateCommentViaDispatcher` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createCommentViaDispatcher, { data, loading, error }] = useCreateCommentViaDispatcher({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateCommentViaDispatcher( - baseOptions?: Apollo.MutationHookOptions< - CreateCommentViaDispatcherData, - CreateCommentViaDispatcherVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - CreateCommentViaDispatcherDocument, - options, - ); -} -export type CreateCommentViaDispatcherHookResult = ReturnType; -export type CreateCommentViaDispatcherMutationResult = - Apollo.MutationResult; -export type CreateCommentViaDispatcherMutationOptions = Apollo.BaseMutationOptions< - CreateCommentViaDispatcherData, - CreateCommentViaDispatcherVariables ->; -export const CreateDataAvailabilityCommentTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateDataAvailabilityCommentTypedData($request: CreateDataAvailabilityCommentRequest!) { - result: createDataAvailabilityCommentTypedData(request: $request) { - id - expiresAt - typedData { - ...CreateCommentEIP712TypedData - } - } - } - ${FragmentCreateCommentEip712TypedData} -`; -export type CreateDataAvailabilityCommentTypedDataMutationFn = Apollo.MutationFunction< - CreateDataAvailabilityCommentTypedDataData, - CreateDataAvailabilityCommentTypedDataVariables ->; - -/** - * __useCreateDataAvailabilityCommentTypedData__ - * - * To run a mutation, you first call `useCreateDataAvailabilityCommentTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateDataAvailabilityCommentTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createDataAvailabilityCommentTypedData, { data, loading, error }] = useCreateDataAvailabilityCommentTypedData({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateDataAvailabilityCommentTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateDataAvailabilityCommentTypedDataData, - CreateDataAvailabilityCommentTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateDataAvailabilityCommentTypedDataData, - CreateDataAvailabilityCommentTypedDataVariables - >(CreateDataAvailabilityCommentTypedDataDocument, options); -} -export type CreateDataAvailabilityCommentTypedDataHookResult = ReturnType< - typeof useCreateDataAvailabilityCommentTypedData ->; -export type CreateDataAvailabilityCommentTypedDataMutationResult = - Apollo.MutationResult; -export type CreateDataAvailabilityCommentTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateDataAvailabilityCommentTypedDataData, - CreateDataAvailabilityCommentTypedDataVariables ->; -export const CreateDataAvailabilityCommentViaDispatcherDocument = /*#__PURE__*/ gql` - mutation CreateDataAvailabilityCommentViaDispatcher( - $request: CreateDataAvailabilityCommentRequest! - ) { - result: createDataAvailabilityCommentViaDispatcher(request: $request) { - ...BroadcastOffChainResult - } - } - ${FragmentBroadcastOffChainResult} -`; -export type CreateDataAvailabilityCommentViaDispatcherMutationFn = Apollo.MutationFunction< - CreateDataAvailabilityCommentViaDispatcherData, - CreateDataAvailabilityCommentViaDispatcherVariables ->; - -/** - * __useCreateDataAvailabilityCommentViaDispatcher__ - * - * To run a mutation, you first call `useCreateDataAvailabilityCommentViaDispatcher` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateDataAvailabilityCommentViaDispatcher` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createDataAvailabilityCommentViaDispatcher, { data, loading, error }] = useCreateDataAvailabilityCommentViaDispatcher({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateDataAvailabilityCommentViaDispatcher( - baseOptions?: Apollo.MutationHookOptions< - CreateDataAvailabilityCommentViaDispatcherData, - CreateDataAvailabilityCommentViaDispatcherVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateDataAvailabilityCommentViaDispatcherData, - CreateDataAvailabilityCommentViaDispatcherVariables - >(CreateDataAvailabilityCommentViaDispatcherDocument, options); -} -export type CreateDataAvailabilityCommentViaDispatcherHookResult = ReturnType< - typeof useCreateDataAvailabilityCommentViaDispatcher ->; -export type CreateDataAvailabilityCommentViaDispatcherMutationResult = - Apollo.MutationResult; -export type CreateDataAvailabilityCommentViaDispatcherMutationOptions = Apollo.BaseMutationOptions< - CreateDataAvailabilityCommentViaDispatcherData, - CreateDataAvailabilityCommentViaDispatcherVariables ->; -export const EnabledModuleCurrenciesDocument = /*#__PURE__*/ gql` - query EnabledModuleCurrencies { - result: enabledModuleCurrencies { - ...Erc20Fields - } - } - ${FragmentErc20Fields} -`; - -/** - * __useEnabledModuleCurrencies__ - * - * To run a query within a React component, call `useEnabledModuleCurrencies` and pass it any options that fit your needs. - * When your component renders, `useEnabledModuleCurrencies` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useEnabledModuleCurrencies({ - * variables: { - * }, - * }); - */ -export function useEnabledModuleCurrencies( - baseOptions?: Apollo.QueryHookOptions< - EnabledModuleCurrenciesData, - EnabledModuleCurrenciesVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - EnabledModuleCurrenciesDocument, - options, - ); -} -export function useEnabledModuleCurrenciesLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - EnabledModuleCurrenciesData, - EnabledModuleCurrenciesVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - EnabledModuleCurrenciesDocument, - options, - ); -} -export type EnabledModuleCurrenciesHookResult = ReturnType; -export type EnabledModuleCurrenciesLazyQueryHookResult = ReturnType< - typeof useEnabledModuleCurrenciesLazyQuery ->; -export type EnabledModuleCurrenciesQueryResult = Apollo.QueryResult< - EnabledModuleCurrenciesData, - EnabledModuleCurrenciesVariables ->; -export const FeedDocument = /*#__PURE__*/ gql` - query Feed( - $profileId: ProfileId! - $restrictEventTypesTo: [FeedEventItemType!] - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!]! - $metadata: PublicationMetadataFilters - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: feed( - request: { - profileId: $profileId - feedEventItemTypes: $restrictEventTypesTo - limit: $limit - cursor: $cursor - sources: $sources - metadata: $metadata - } - ) { - items { - ...FeedItem - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentFeedItem} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useFeed__ - * - * To run a query within a React component, call `useFeed` and pass it any options that fit your needs. - * When your component renders, `useFeed` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useFeed({ - * variables: { - * profileId: // value for 'profileId' - * restrictEventTypesTo: // value for 'restrictEventTypesTo' - * observerId: // value for 'observerId' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * sources: // value for 'sources' - * metadata: // value for 'metadata' - * mediaTransformPublicationSmall: // value for 'mediaTransformPublicationSmall' - * mediaTransformPublicationMedium: // value for 'mediaTransformPublicationMedium' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useFeed(baseOptions: Apollo.QueryHookOptions) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery(FeedDocument, options); -} -export function useFeedLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery(FeedDocument, options); -} -export type FeedHookResult = ReturnType; -export type FeedLazyQueryHookResult = ReturnType; -export type FeedQueryResult = Apollo.QueryResult; -export const ExploreProfilesDocument = /*#__PURE__*/ gql` - query ExploreProfiles( - $sortCriteria: ProfileSortCriteria! - $limit: LimitScalar - $cursor: Cursor - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: exploreProfiles( - request: { limit: $limit, cursor: $cursor, sortCriteria: $sortCriteria } - ) { - items { - ...Profile - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentProfile} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useExploreProfiles__ - * - * To run a query within a React component, call `useExploreProfiles` and pass it any options that fit your needs. - * When your component renders, `useExploreProfiles` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useExploreProfiles({ - * variables: { - * sortCriteria: // value for 'sortCriteria' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * observerId: // value for 'observerId' - * sources: // value for 'sources' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useExploreProfiles( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - ExploreProfilesDocument, - options, - ); -} -export function useExploreProfilesLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - ExploreProfilesDocument, - options, - ); -} -export type ExploreProfilesHookResult = ReturnType; -export type ExploreProfilesLazyQueryHookResult = ReturnType; -export type ExploreProfilesQueryResult = Apollo.QueryResult< - ExploreProfilesData, - ExploreProfilesVariables ->; -export const CreateFollowTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateFollowTypedData($request: FollowRequest!, $options: TypedDataOptions) { - result: createFollowTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - FollowWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - profileIds - datas - } - } - } - } - ${FragmentEip712TypedDataDomain} -`; -export type CreateFollowTypedDataMutationFn = Apollo.MutationFunction< - CreateFollowTypedDataData, - CreateFollowTypedDataVariables ->; - -/** - * __useCreateFollowTypedData__ - * - * To run a mutation, you first call `useCreateFollowTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateFollowTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createFollowTypedData, { data, loading, error }] = useCreateFollowTypedData({ - * variables: { - * request: // value for 'request' - * options: // value for 'options' - * }, - * }); - */ -export function useCreateFollowTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateFollowTypedDataData, - CreateFollowTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - CreateFollowTypedDataDocument, - options, - ); -} -export type CreateFollowTypedDataHookResult = ReturnType; -export type CreateFollowTypedDataMutationResult = Apollo.MutationResult; -export type CreateFollowTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateFollowTypedDataData, - CreateFollowTypedDataVariables ->; -export const CreateMirrorTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateMirrorTypedData($request: CreateMirrorRequest!, $options: TypedDataOptions) { - result: createMirrorTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - ...CreateMirrorEIP712TypedData - } - } - } - ${FragmentCreateMirrorEip712TypedData} -`; -export type CreateMirrorTypedDataMutationFn = Apollo.MutationFunction< - CreateMirrorTypedDataData, - CreateMirrorTypedDataVariables ->; - -/** - * __useCreateMirrorTypedData__ - * - * To run a mutation, you first call `useCreateMirrorTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateMirrorTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createMirrorTypedData, { data, loading, error }] = useCreateMirrorTypedData({ - * variables: { - * request: // value for 'request' - * options: // value for 'options' - * }, - * }); - */ -export function useCreateMirrorTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateMirrorTypedDataData, - CreateMirrorTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - CreateMirrorTypedDataDocument, - options, - ); -} -export type CreateMirrorTypedDataHookResult = ReturnType; -export type CreateMirrorTypedDataMutationResult = Apollo.MutationResult; -export type CreateMirrorTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateMirrorTypedDataData, - CreateMirrorTypedDataVariables ->; -export const CreateMirrorViaDispatcherDocument = /*#__PURE__*/ gql` - mutation CreateMirrorViaDispatcher($request: CreateMirrorRequest!) { - result: createMirrorViaDispatcher(request: $request) { - ...BroadcastOnChainResult - } - } - ${FragmentBroadcastOnChainResult} -`; -export type CreateMirrorViaDispatcherMutationFn = Apollo.MutationFunction< - CreateMirrorViaDispatcherData, - CreateMirrorViaDispatcherVariables ->; - -/** - * __useCreateMirrorViaDispatcher__ - * - * To run a mutation, you first call `useCreateMirrorViaDispatcher` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateMirrorViaDispatcher` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createMirrorViaDispatcher, { data, loading, error }] = useCreateMirrorViaDispatcher({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateMirrorViaDispatcher( - baseOptions?: Apollo.MutationHookOptions< - CreateMirrorViaDispatcherData, - CreateMirrorViaDispatcherVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - CreateMirrorViaDispatcherDocument, - options, - ); -} -export type CreateMirrorViaDispatcherHookResult = ReturnType; -export type CreateMirrorViaDispatcherMutationResult = - Apollo.MutationResult; -export type CreateMirrorViaDispatcherMutationOptions = Apollo.BaseMutationOptions< - CreateMirrorViaDispatcherData, - CreateMirrorViaDispatcherVariables ->; -export const CreateDataAvailabilityMirrorTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateDataAvailabilityMirrorTypedData($request: CreateDataAvailabilityMirrorRequest!) { - result: createDataAvailabilityMirrorTypedData(request: $request) { - id - expiresAt - typedData { - ...CreateMirrorEIP712TypedData - } - } - } - ${FragmentCreateMirrorEip712TypedData} -`; -export type CreateDataAvailabilityMirrorTypedDataMutationFn = Apollo.MutationFunction< - CreateDataAvailabilityMirrorTypedDataData, - CreateDataAvailabilityMirrorTypedDataVariables ->; - -/** - * __useCreateDataAvailabilityMirrorTypedData__ - * - * To run a mutation, you first call `useCreateDataAvailabilityMirrorTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateDataAvailabilityMirrorTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createDataAvailabilityMirrorTypedData, { data, loading, error }] = useCreateDataAvailabilityMirrorTypedData({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateDataAvailabilityMirrorTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateDataAvailabilityMirrorTypedDataData, - CreateDataAvailabilityMirrorTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateDataAvailabilityMirrorTypedDataData, - CreateDataAvailabilityMirrorTypedDataVariables - >(CreateDataAvailabilityMirrorTypedDataDocument, options); -} -export type CreateDataAvailabilityMirrorTypedDataHookResult = ReturnType< - typeof useCreateDataAvailabilityMirrorTypedData ->; -export type CreateDataAvailabilityMirrorTypedDataMutationResult = - Apollo.MutationResult; -export type CreateDataAvailabilityMirrorTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateDataAvailabilityMirrorTypedDataData, - CreateDataAvailabilityMirrorTypedDataVariables ->; -export const CreateDataAvailabilityMirrorViaDispatcherDocument = /*#__PURE__*/ gql` - mutation CreateDataAvailabilityMirrorViaDispatcher( - $request: CreateDataAvailabilityMirrorRequest! - ) { - result: createDataAvailabilityMirrorViaDispatcher(request: $request) { - ...BroadcastOffChainResult - } - } - ${FragmentBroadcastOffChainResult} -`; -export type CreateDataAvailabilityMirrorViaDispatcherMutationFn = Apollo.MutationFunction< - CreateDataAvailabilityMirrorViaDispatcherData, - CreateDataAvailabilityMirrorViaDispatcherVariables ->; - -/** - * __useCreateDataAvailabilityMirrorViaDispatcher__ - * - * To run a mutation, you first call `useCreateDataAvailabilityMirrorViaDispatcher` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateDataAvailabilityMirrorViaDispatcher` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createDataAvailabilityMirrorViaDispatcher, { data, loading, error }] = useCreateDataAvailabilityMirrorViaDispatcher({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateDataAvailabilityMirrorViaDispatcher( - baseOptions?: Apollo.MutationHookOptions< - CreateDataAvailabilityMirrorViaDispatcherData, - CreateDataAvailabilityMirrorViaDispatcherVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateDataAvailabilityMirrorViaDispatcherData, - CreateDataAvailabilityMirrorViaDispatcherVariables - >(CreateDataAvailabilityMirrorViaDispatcherDocument, options); -} -export type CreateDataAvailabilityMirrorViaDispatcherHookResult = ReturnType< - typeof useCreateDataAvailabilityMirrorViaDispatcher ->; -export type CreateDataAvailabilityMirrorViaDispatcherMutationResult = - Apollo.MutationResult; -export type CreateDataAvailabilityMirrorViaDispatcherMutationOptions = Apollo.BaseMutationOptions< - CreateDataAvailabilityMirrorViaDispatcherData, - CreateDataAvailabilityMirrorViaDispatcherVariables ->; -export const EnabledModulesDocument = /*#__PURE__*/ gql` - query EnabledModules { - result: enabledModules { - ...EnabledModules - } - } - ${FragmentEnabledModules} -`; - -/** - * __useEnabledModules__ - * - * To run a query within a React component, call `useEnabledModules` and pass it any options that fit your needs. - * When your component renders, `useEnabledModules` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useEnabledModules({ - * variables: { - * }, - * }); - */ -export function useEnabledModules( - baseOptions?: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - EnabledModulesDocument, - options, - ); -} -export function useEnabledModulesLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - EnabledModulesDocument, - options, - ); -} -export type EnabledModulesHookResult = ReturnType; -export type EnabledModulesLazyQueryHookResult = ReturnType; -export type EnabledModulesQueryResult = Apollo.QueryResult< - EnabledModulesData, - EnabledModulesVariables ->; -export const NotificationsDocument = /*#__PURE__*/ gql` - query Notifications( - $observerId: ProfileId! - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!]! - $notificationTypes: [NotificationTypes!] - $highSignalFilter: Boolean! - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: notifications( - request: { - profileId: $observerId - limit: $limit - cursor: $cursor - sources: $sources - notificationTypes: $notificationTypes - highSignalFilter: $highSignalFilter - } - ) { - items { - ... on NewFollowerNotification { - ...NewFollowerNotification - } - ... on NewMirrorNotification { - ...NewMirrorNotification - } - ... on NewCollectNotification { - ...NewCollectNotification - } - ... on NewCommentNotification { - ...NewCommentNotification - } - ... on NewMentionNotification { - ...NewMentionNotification - } - ... on NewReactionNotification { - ...NewReactionNotification - } - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentNewFollowerNotification} - ${FragmentNewMirrorNotification} - ${FragmentNewCollectNotification} - ${FragmentNewCommentNotification} - ${FragmentNewMentionNotification} - ${FragmentNewReactionNotification} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useNotifications__ - * - * To run a query within a React component, call `useNotifications` and pass it any options that fit your needs. - * When your component renders, `useNotifications` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useNotifications({ - * variables: { - * observerId: // value for 'observerId' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * sources: // value for 'sources' - * notificationTypes: // value for 'notificationTypes' - * highSignalFilter: // value for 'highSignalFilter' - * mediaTransformPublicationSmall: // value for 'mediaTransformPublicationSmall' - * mediaTransformPublicationMedium: // value for 'mediaTransformPublicationMedium' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useNotifications( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery(NotificationsDocument, options); -} -export function useNotificationsLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - NotificationsDocument, - options, - ); -} -export type NotificationsHookResult = ReturnType; -export type NotificationsLazyQueryHookResult = ReturnType; -export type NotificationsQueryResult = Apollo.QueryResult< - NotificationsData, - NotificationsVariables ->; -export const UnreadNotificationCountDocument = /*#__PURE__*/ gql` - query UnreadNotificationCount( - $profileId: ProfileId! - $sources: [Sources!] - $notificationTypes: [NotificationTypes!] - ) { - result: notifications( - request: { profileId: $profileId, sources: $sources, notificationTypes: $notificationTypes } - ) { - pageInfo { - totalCount - } - } - } -`; - -/** - * __useUnreadNotificationCount__ - * - * To run a query within a React component, call `useUnreadNotificationCount` and pass it any options that fit your needs. - * When your component renders, `useUnreadNotificationCount` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useUnreadNotificationCount({ - * variables: { - * profileId: // value for 'profileId' - * sources: // value for 'sources' - * notificationTypes: // value for 'notificationTypes' - * }, - * }); - */ -export function useUnreadNotificationCount( - baseOptions: Apollo.QueryHookOptions< - UnreadNotificationCountData, - UnreadNotificationCountVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - UnreadNotificationCountDocument, - options, - ); -} -export function useUnreadNotificationCountLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - UnreadNotificationCountData, - UnreadNotificationCountVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - UnreadNotificationCountDocument, - options, - ); -} -export type UnreadNotificationCountHookResult = ReturnType; -export type UnreadNotificationCountLazyQueryHookResult = ReturnType< - typeof useUnreadNotificationCountLazyQuery ->; -export type UnreadNotificationCountQueryResult = Apollo.QueryResult< - UnreadNotificationCountData, - UnreadNotificationCountVariables ->; -export const CreatePostTypedDataDocument = /*#__PURE__*/ gql` - mutation CreatePostTypedData($request: CreatePublicPostRequest!, $options: TypedDataOptions) { - result: createPostTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - ...CreatePostEIP712TypedData - } - } - } - ${FragmentCreatePostEip712TypedData} -`; -export type CreatePostTypedDataMutationFn = Apollo.MutationFunction< - CreatePostTypedDataData, - CreatePostTypedDataVariables ->; - -/** - * __useCreatePostTypedData__ - * - * To run a mutation, you first call `useCreatePostTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreatePostTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createPostTypedData, { data, loading, error }] = useCreatePostTypedData({ - * variables: { - * request: // value for 'request' - * options: // value for 'options' - * }, - * }); - */ -export function useCreatePostTypedData( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - CreatePostTypedDataDocument, - options, - ); -} -export type CreatePostTypedDataHookResult = ReturnType; -export type CreatePostTypedDataMutationResult = Apollo.MutationResult; -export type CreatePostTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreatePostTypedDataData, - CreatePostTypedDataVariables ->; -export const CreatePostViaDispatcherDocument = /*#__PURE__*/ gql` - mutation CreatePostViaDispatcher($request: CreatePublicPostRequest!) { - result: createPostViaDispatcher(request: $request) { - ...BroadcastOnChainResult - } - } - ${FragmentBroadcastOnChainResult} -`; -export type CreatePostViaDispatcherMutationFn = Apollo.MutationFunction< - CreatePostViaDispatcherData, - CreatePostViaDispatcherVariables ->; - -/** - * __useCreatePostViaDispatcher__ - * - * To run a mutation, you first call `useCreatePostViaDispatcher` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreatePostViaDispatcher` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createPostViaDispatcher, { data, loading, error }] = useCreatePostViaDispatcher({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreatePostViaDispatcher( - baseOptions?: Apollo.MutationHookOptions< - CreatePostViaDispatcherData, - CreatePostViaDispatcherVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - CreatePostViaDispatcherDocument, - options, - ); -} -export type CreatePostViaDispatcherHookResult = ReturnType; -export type CreatePostViaDispatcherMutationResult = - Apollo.MutationResult; -export type CreatePostViaDispatcherMutationOptions = Apollo.BaseMutationOptions< - CreatePostViaDispatcherData, - CreatePostViaDispatcherVariables ->; -export const CreateDataAvailabilityPostTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateDataAvailabilityPostTypedData($request: CreateDataAvailabilityPostRequest!) { - result: createDataAvailabilityPostTypedData(request: $request) { - id - expiresAt - typedData { - ...CreatePostEIP712TypedData - } - } - } - ${FragmentCreatePostEip712TypedData} -`; -export type CreateDataAvailabilityPostTypedDataMutationFn = Apollo.MutationFunction< - CreateDataAvailabilityPostTypedDataData, - CreateDataAvailabilityPostTypedDataVariables ->; - -/** - * __useCreateDataAvailabilityPostTypedData__ - * - * To run a mutation, you first call `useCreateDataAvailabilityPostTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateDataAvailabilityPostTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createDataAvailabilityPostTypedData, { data, loading, error }] = useCreateDataAvailabilityPostTypedData({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateDataAvailabilityPostTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateDataAvailabilityPostTypedDataData, - CreateDataAvailabilityPostTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateDataAvailabilityPostTypedDataData, - CreateDataAvailabilityPostTypedDataVariables - >(CreateDataAvailabilityPostTypedDataDocument, options); -} -export type CreateDataAvailabilityPostTypedDataHookResult = ReturnType< - typeof useCreateDataAvailabilityPostTypedData ->; -export type CreateDataAvailabilityPostTypedDataMutationResult = - Apollo.MutationResult; -export type CreateDataAvailabilityPostTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateDataAvailabilityPostTypedDataData, - CreateDataAvailabilityPostTypedDataVariables ->; -export const CreateDataAvailabilityPostViaDispatcherDocument = /*#__PURE__*/ gql` - mutation CreateDataAvailabilityPostViaDispatcher($request: CreateDataAvailabilityPostRequest!) { - result: createDataAvailabilityPostViaDispatcher(request: $request) { - ...BroadcastOffChainResult - } - } - ${FragmentBroadcastOffChainResult} -`; -export type CreateDataAvailabilityPostViaDispatcherMutationFn = Apollo.MutationFunction< - CreateDataAvailabilityPostViaDispatcherData, - CreateDataAvailabilityPostViaDispatcherVariables ->; - -/** - * __useCreateDataAvailabilityPostViaDispatcher__ - * - * To run a mutation, you first call `useCreateDataAvailabilityPostViaDispatcher` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateDataAvailabilityPostViaDispatcher` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createDataAvailabilityPostViaDispatcher, { data, loading, error }] = useCreateDataAvailabilityPostViaDispatcher({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateDataAvailabilityPostViaDispatcher( - baseOptions?: Apollo.MutationHookOptions< - CreateDataAvailabilityPostViaDispatcherData, - CreateDataAvailabilityPostViaDispatcherVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateDataAvailabilityPostViaDispatcherData, - CreateDataAvailabilityPostViaDispatcherVariables - >(CreateDataAvailabilityPostViaDispatcherDocument, options); -} -export type CreateDataAvailabilityPostViaDispatcherHookResult = ReturnType< - typeof useCreateDataAvailabilityPostViaDispatcher ->; -export type CreateDataAvailabilityPostViaDispatcherMutationResult = - Apollo.MutationResult; -export type CreateDataAvailabilityPostViaDispatcherMutationOptions = Apollo.BaseMutationOptions< - CreateDataAvailabilityPostViaDispatcherData, - CreateDataAvailabilityPostViaDispatcherVariables ->; -export const CreateSetDispatcherTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateSetDispatcherTypedData( - $request: SetDispatcherRequest! - $options: TypedDataOptions - ) { - result: createSetDispatcherTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - SetDispatcherWithSig { - name - type - } - } - domain { - name - chainId - version - verifyingContract - } - message: value { - nonce - deadline - profileId - dispatcher - } - } - } - } -`; -export type CreateSetDispatcherTypedDataMutationFn = Apollo.MutationFunction< - CreateSetDispatcherTypedDataData, - CreateSetDispatcherTypedDataVariables ->; - -/** - * __useCreateSetDispatcherTypedData__ - * - * To run a mutation, you first call `useCreateSetDispatcherTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateSetDispatcherTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createSetDispatcherTypedData, { data, loading, error }] = useCreateSetDispatcherTypedData({ - * variables: { - * request: // value for 'request' - * options: // value for 'options' - * }, - * }); - */ -export function useCreateSetDispatcherTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateSetDispatcherTypedDataData, - CreateSetDispatcherTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateSetDispatcherTypedDataData, - CreateSetDispatcherTypedDataVariables - >(CreateSetDispatcherTypedDataDocument, options); -} -export type CreateSetDispatcherTypedDataHookResult = ReturnType< - typeof useCreateSetDispatcherTypedData ->; -export type CreateSetDispatcherTypedDataMutationResult = - Apollo.MutationResult; -export type CreateSetDispatcherTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateSetDispatcherTypedDataData, - CreateSetDispatcherTypedDataVariables ->; -export const ProfileGuardianDocument = /*#__PURE__*/ gql` - query ProfileGuardian($request: ProfileGuardianRequest!) { - result: profileGuardianInformation(request: $request) { - ...ProfileGuardianResult - } - } - ${FragmentProfileGuardianResult} -`; - -/** - * __useProfileGuardian__ - * - * To run a query within a React component, call `useProfileGuardian` and pass it any options that fit your needs. - * When your component renders, `useProfileGuardian` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useProfileGuardian({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useProfileGuardian( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - ProfileGuardianDocument, - options, - ); -} -export function useProfileGuardianLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - ProfileGuardianDocument, - options, - ); -} -export type ProfileGuardianHookResult = ReturnType; -export type ProfileGuardianLazyQueryHookResult = ReturnType; -export type ProfileGuardianQueryResult = Apollo.QueryResult< - ProfileGuardianData, - ProfileGuardianVariables ->; -export const ProfilesToFollowDocument = /*#__PURE__*/ gql` - query ProfilesToFollow( - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: recommendedProfiles { - ...Profile - } - } - ${FragmentProfile} -`; - -/** - * __useProfilesToFollow__ - * - * To run a query within a React component, call `useProfilesToFollow` and pass it any options that fit your needs. - * When your component renders, `useProfilesToFollow` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useProfilesToFollow({ - * variables: { - * observerId: // value for 'observerId' - * sources: // value for 'sources' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useProfilesToFollow( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - ProfilesToFollowDocument, - options, - ); -} -export function useProfilesToFollowLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - ProfilesToFollowDocument, - options, - ); -} -export type ProfilesToFollowHookResult = ReturnType; -export type ProfilesToFollowLazyQueryHookResult = ReturnType; -export type ProfilesToFollowQueryResult = Apollo.QueryResult< - ProfilesToFollowData, - ProfilesToFollowVariables ->; -export const GetProfileDocument = /*#__PURE__*/ gql` - query GetProfile( - $request: SingleProfileQueryRequest! - $observerId: ProfileId - $sources: [Sources!] = [] - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: profile(request: $request) { - ...Profile - } - } - ${FragmentProfile} -`; - -/** - * __useGetProfile__ - * - * To run a query within a React component, call `useGetProfile` and pass it any options that fit your needs. - * When your component renders, `useGetProfile` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useGetProfile({ - * variables: { - * request: // value for 'request' - * observerId: // value for 'observerId' - * sources: // value for 'sources' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useGetProfile( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery(GetProfileDocument, options); -} -export function useGetProfileLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery(GetProfileDocument, options); -} -export type GetProfileHookResult = ReturnType; -export type GetProfileLazyQueryHookResult = ReturnType; -export type GetProfileQueryResult = Apollo.QueryResult; -export const GetAllProfilesDocument = /*#__PURE__*/ gql` - query GetAllProfiles( - $byProfileIds: [ProfileId!] - $byHandles: [Handle!] - $byOwnerAddresses: [EthereumAddress!] - $byWhoMirroredPublicationId: InternalPublicationId - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!] = [] - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: profiles( - request: { - whoMirroredPublicationId: $byWhoMirroredPublicationId - ownedBy: $byOwnerAddresses - profileIds: $byProfileIds - handles: $byHandles - limit: $limit - cursor: $cursor - } - ) { - items { - ...Profile - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentProfile} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useGetAllProfiles__ - * - * To run a query within a React component, call `useGetAllProfiles` and pass it any options that fit your needs. - * When your component renders, `useGetAllProfiles` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useGetAllProfiles({ - * variables: { - * byProfileIds: // value for 'byProfileIds' - * byHandles: // value for 'byHandles' - * byOwnerAddresses: // value for 'byOwnerAddresses' - * byWhoMirroredPublicationId: // value for 'byWhoMirroredPublicationId' - * observerId: // value for 'observerId' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * sources: // value for 'sources' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useGetAllProfiles( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - GetAllProfilesDocument, - options, - ); -} -export function useGetAllProfilesLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - GetAllProfilesDocument, - options, - ); -} -export type GetAllProfilesHookResult = ReturnType; -export type GetAllProfilesLazyQueryHookResult = ReturnType; -export type GetAllProfilesQueryResult = Apollo.QueryResult< - GetAllProfilesData, - GetAllProfilesVariables ->; -export const CreateProfileDocument = /*#__PURE__*/ gql` - mutation CreateProfile($request: CreateProfileRequest!) { - result: createProfile(request: $request) { - ...BroadcastOnChainResult - } - } - ${FragmentBroadcastOnChainResult} -`; -export type CreateProfileMutationFn = Apollo.MutationFunction< - CreateProfileData, - CreateProfileVariables ->; - -/** - * __useCreateProfile__ - * - * To run a mutation, you first call `useCreateProfile` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateProfile` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createProfile, { data, loading, error }] = useCreateProfile({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateProfile( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - CreateProfileDocument, - options, - ); -} -export type CreateProfileHookResult = ReturnType; -export type CreateProfileMutationResult = Apollo.MutationResult; -export type CreateProfileMutationOptions = Apollo.BaseMutationOptions< - CreateProfileData, - CreateProfileVariables ->; -export const MutualFollowersProfilesDocument = /*#__PURE__*/ gql` - query MutualFollowersProfiles( - $observerId: ProfileId! - $viewingProfileId: ProfileId! - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: mutualFollowersProfiles( - request: { - yourProfileId: $observerId - viewingProfileId: $viewingProfileId - limit: $limit - cursor: $cursor - } - ) { - items { - ...Profile - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentProfile} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useMutualFollowersProfiles__ - * - * To run a query within a React component, call `useMutualFollowersProfiles` and pass it any options that fit your needs. - * When your component renders, `useMutualFollowersProfiles` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useMutualFollowersProfiles({ - * variables: { - * observerId: // value for 'observerId' - * viewingProfileId: // value for 'viewingProfileId' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * sources: // value for 'sources' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useMutualFollowersProfiles( - baseOptions: Apollo.QueryHookOptions< - MutualFollowersProfilesData, - MutualFollowersProfilesVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - MutualFollowersProfilesDocument, - options, - ); -} -export function useMutualFollowersProfilesLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - MutualFollowersProfilesData, - MutualFollowersProfilesVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - MutualFollowersProfilesDocument, - options, - ); -} -export type MutualFollowersProfilesHookResult = ReturnType; -export type MutualFollowersProfilesLazyQueryHookResult = ReturnType< - typeof useMutualFollowersProfilesLazyQuery ->; -export type MutualFollowersProfilesQueryResult = Apollo.QueryResult< - MutualFollowersProfilesData, - MutualFollowersProfilesVariables ->; -export const CreateSetFollowModuleTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateSetFollowModuleTypedData( - $request: CreateSetFollowModuleRequest! - $options: TypedDataOptions - ) { - result: createSetFollowModuleTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - SetFollowModuleWithSig { - name - type - } - } - domain { - name - chainId - version - verifyingContract - } - message: value { - nonce - deadline - profileId - followModule - followModuleInitData - } - } - } - } -`; -export type CreateSetFollowModuleTypedDataMutationFn = Apollo.MutationFunction< - CreateSetFollowModuleTypedDataData, - CreateSetFollowModuleTypedDataVariables ->; - -/** - * __useCreateSetFollowModuleTypedData__ - * - * To run a mutation, you first call `useCreateSetFollowModuleTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateSetFollowModuleTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createSetFollowModuleTypedData, { data, loading, error }] = useCreateSetFollowModuleTypedData({ - * variables: { - * request: // value for 'request' - * options: // value for 'options' - * }, - * }); - */ -export function useCreateSetFollowModuleTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateSetFollowModuleTypedDataData, - CreateSetFollowModuleTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateSetFollowModuleTypedDataData, - CreateSetFollowModuleTypedDataVariables - >(CreateSetFollowModuleTypedDataDocument, options); -} -export type CreateSetFollowModuleTypedDataHookResult = ReturnType< - typeof useCreateSetFollowModuleTypedData ->; -export type CreateSetFollowModuleTypedDataMutationResult = - Apollo.MutationResult; -export type CreateSetFollowModuleTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateSetFollowModuleTypedDataData, - CreateSetFollowModuleTypedDataVariables ->; -export const CreateSetProfileImageUriTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateSetProfileImageURITypedData( - $request: UpdateProfileImageRequest! - $options: TypedDataOptions - ) { - result: createSetProfileImageURITypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - SetProfileImageURIWithSig { - name - type - } - } - domain { - name - chainId - version - verifyingContract - } - message: value { - nonce - deadline - profileId - imageURI - } - } - } - } -`; -export type CreateSetProfileImageUriTypedDataMutationFn = Apollo.MutationFunction< - CreateSetProfileImageUriTypedDataData, - CreateSetProfileImageUriTypedDataVariables ->; - -/** - * __useCreateSetProfileImageUriTypedData__ - * - * To run a mutation, you first call `useCreateSetProfileImageUriTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateSetProfileImageUriTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createSetProfileImageUriTypedData, { data, loading, error }] = useCreateSetProfileImageUriTypedData({ - * variables: { - * request: // value for 'request' - * options: // value for 'options' - * }, - * }); - */ -export function useCreateSetProfileImageUriTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateSetProfileImageUriTypedDataData, - CreateSetProfileImageUriTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateSetProfileImageUriTypedDataData, - CreateSetProfileImageUriTypedDataVariables - >(CreateSetProfileImageUriTypedDataDocument, options); -} -export type CreateSetProfileImageUriTypedDataHookResult = ReturnType< - typeof useCreateSetProfileImageUriTypedData ->; -export type CreateSetProfileImageUriTypedDataMutationResult = - Apollo.MutationResult; -export type CreateSetProfileImageUriTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateSetProfileImageUriTypedDataData, - CreateSetProfileImageUriTypedDataVariables ->; -export const CreateSetProfileImageUriViaDispatcherDocument = /*#__PURE__*/ gql` - mutation CreateSetProfileImageURIViaDispatcher($request: UpdateProfileImageRequest!) { - result: createSetProfileImageURIViaDispatcher(request: $request) { - ...BroadcastOnChainResult - } - } - ${FragmentBroadcastOnChainResult} -`; -export type CreateSetProfileImageUriViaDispatcherMutationFn = Apollo.MutationFunction< - CreateSetProfileImageUriViaDispatcherData, - CreateSetProfileImageUriViaDispatcherVariables ->; - -/** - * __useCreateSetProfileImageUriViaDispatcher__ - * - * To run a mutation, you first call `useCreateSetProfileImageUriViaDispatcher` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateSetProfileImageUriViaDispatcher` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createSetProfileImageUriViaDispatcher, { data, loading, error }] = useCreateSetProfileImageUriViaDispatcher({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateSetProfileImageUriViaDispatcher( - baseOptions?: Apollo.MutationHookOptions< - CreateSetProfileImageUriViaDispatcherData, - CreateSetProfileImageUriViaDispatcherVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateSetProfileImageUriViaDispatcherData, - CreateSetProfileImageUriViaDispatcherVariables - >(CreateSetProfileImageUriViaDispatcherDocument, options); -} -export type CreateSetProfileImageUriViaDispatcherHookResult = ReturnType< - typeof useCreateSetProfileImageUriViaDispatcher ->; -export type CreateSetProfileImageUriViaDispatcherMutationResult = - Apollo.MutationResult; -export type CreateSetProfileImageUriViaDispatcherMutationOptions = Apollo.BaseMutationOptions< - CreateSetProfileImageUriViaDispatcherData, - CreateSetProfileImageUriViaDispatcherVariables ->; -export const CreateSetProfileMetadataTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateSetProfileMetadataTypedData( - $request: CreatePublicSetProfileMetadataURIRequest! - $options: TypedDataOptions - ) { - result: createSetProfileMetadataTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - SetProfileMetadataURIWithSig { - name - type - } - } - domain { - name - chainId - version - verifyingContract - } - message: value { - nonce - deadline - profileId - metadata - } - } - } - } -`; -export type CreateSetProfileMetadataTypedDataMutationFn = Apollo.MutationFunction< - CreateSetProfileMetadataTypedDataData, - CreateSetProfileMetadataTypedDataVariables ->; - -/** - * __useCreateSetProfileMetadataTypedData__ - * - * To run a mutation, you first call `useCreateSetProfileMetadataTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateSetProfileMetadataTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createSetProfileMetadataTypedData, { data, loading, error }] = useCreateSetProfileMetadataTypedData({ - * variables: { - * request: // value for 'request' - * options: // value for 'options' - * }, - * }); - */ -export function useCreateSetProfileMetadataTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateSetProfileMetadataTypedDataData, - CreateSetProfileMetadataTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateSetProfileMetadataTypedDataData, - CreateSetProfileMetadataTypedDataVariables - >(CreateSetProfileMetadataTypedDataDocument, options); -} -export type CreateSetProfileMetadataTypedDataHookResult = ReturnType< - typeof useCreateSetProfileMetadataTypedData ->; -export type CreateSetProfileMetadataTypedDataMutationResult = - Apollo.MutationResult; -export type CreateSetProfileMetadataTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateSetProfileMetadataTypedDataData, - CreateSetProfileMetadataTypedDataVariables ->; -export const CreateSetProfileMetadataViaDispatcherDocument = /*#__PURE__*/ gql` - mutation CreateSetProfileMetadataViaDispatcher( - $request: CreatePublicSetProfileMetadataURIRequest! - ) { - result: createSetProfileMetadataViaDispatcher(request: $request) { - ...BroadcastOnChainResult - } - } - ${FragmentBroadcastOnChainResult} -`; -export type CreateSetProfileMetadataViaDispatcherMutationFn = Apollo.MutationFunction< - CreateSetProfileMetadataViaDispatcherData, - CreateSetProfileMetadataViaDispatcherVariables ->; - -/** - * __useCreateSetProfileMetadataViaDispatcher__ - * - * To run a mutation, you first call `useCreateSetProfileMetadataViaDispatcher` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateSetProfileMetadataViaDispatcher` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createSetProfileMetadataViaDispatcher, { data, loading, error }] = useCreateSetProfileMetadataViaDispatcher({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateSetProfileMetadataViaDispatcher( - baseOptions?: Apollo.MutationHookOptions< - CreateSetProfileMetadataViaDispatcherData, - CreateSetProfileMetadataViaDispatcherVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation< - CreateSetProfileMetadataViaDispatcherData, - CreateSetProfileMetadataViaDispatcherVariables - >(CreateSetProfileMetadataViaDispatcherDocument, options); -} -export type CreateSetProfileMetadataViaDispatcherHookResult = ReturnType< - typeof useCreateSetProfileMetadataViaDispatcher ->; -export type CreateSetProfileMetadataViaDispatcherMutationResult = - Apollo.MutationResult; -export type CreateSetProfileMetadataViaDispatcherMutationOptions = Apollo.BaseMutationOptions< - CreateSetProfileMetadataViaDispatcherData, - CreateSetProfileMetadataViaDispatcherVariables ->; -export const ProfileFollowersDocument = /*#__PURE__*/ gql` - query ProfileFollowers( - $profileId: ProfileId! - $limit: LimitScalar! - $cursor: Cursor - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: followers(request: { profileId: $profileId, limit: $limit, cursor: $cursor }) { - items { - ...Follower - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentFollower} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useProfileFollowers__ - * - * To run a query within a React component, call `useProfileFollowers` and pass it any options that fit your needs. - * When your component renders, `useProfileFollowers` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useProfileFollowers({ - * variables: { - * profileId: // value for 'profileId' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * observerId: // value for 'observerId' - * sources: // value for 'sources' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useProfileFollowers( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - ProfileFollowersDocument, - options, - ); -} -export function useProfileFollowersLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - ProfileFollowersDocument, - options, - ); -} -export type ProfileFollowersHookResult = ReturnType; -export type ProfileFollowersLazyQueryHookResult = ReturnType; -export type ProfileFollowersQueryResult = Apollo.QueryResult< - ProfileFollowersData, - ProfileFollowersVariables ->; -export const ProfileFollowingDocument = /*#__PURE__*/ gql` - query ProfileFollowing( - $walletAddress: EthereumAddress! - $limit: LimitScalar! - $cursor: Cursor - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: following(request: { address: $walletAddress, limit: $limit, cursor: $cursor }) { - items { - ...Following - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentFollowing} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useProfileFollowing__ - * - * To run a query within a React component, call `useProfileFollowing` and pass it any options that fit your needs. - * When your component renders, `useProfileFollowing` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useProfileFollowing({ - * variables: { - * walletAddress: // value for 'walletAddress' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * observerId: // value for 'observerId' - * sources: // value for 'sources' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useProfileFollowing( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - ProfileFollowingDocument, - options, - ); -} -export function useProfileFollowingLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - ProfileFollowingDocument, - options, - ); -} -export type ProfileFollowingHookResult = ReturnType; -export type ProfileFollowingLazyQueryHookResult = ReturnType; -export type ProfileFollowingQueryResult = Apollo.QueryResult< - ProfileFollowingData, - ProfileFollowingVariables ->; -export const ProxyActionStatusDocument = /*#__PURE__*/ gql` - query ProxyActionStatus($proxyActionId: ProxyActionId!) { - result: proxyActionStatus(proxyActionId: $proxyActionId) { - ... on ProxyActionStatusResult { - ...ProxyActionStatusResult - } - ... on ProxyActionError { - ...ProxyActionError - } - ... on ProxyActionQueued { - ...ProxyActionQueued - } - } - } - ${FragmentProxyActionStatusResult} - ${FragmentProxyActionError} - ${FragmentProxyActionQueued} -`; - -/** - * __useProxyActionStatus__ - * - * To run a query within a React component, call `useProxyActionStatus` and pass it any options that fit your needs. - * When your component renders, `useProxyActionStatus` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useProxyActionStatus({ - * variables: { - * proxyActionId: // value for 'proxyActionId' - * }, - * }); - */ -export function useProxyActionStatus( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - ProxyActionStatusDocument, - options, - ); -} -export function useProxyActionStatusLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - ProxyActionStatusDocument, - options, - ); -} -export type ProxyActionStatusHookResult = ReturnType; -export type ProxyActionStatusLazyQueryHookResult = ReturnType; -export type ProxyActionStatusQueryResult = Apollo.QueryResult< - ProxyActionStatusData, - ProxyActionStatusVariables ->; -export const ProxyActionDocument = /*#__PURE__*/ gql` - mutation ProxyAction($request: ProxyActionRequest!) { - result: proxyAction(request: $request) - } -`; -export type ProxyActionMutationFn = Apollo.MutationFunction; - -/** - * __useProxyAction__ - * - * To run a mutation, you first call `useProxyAction` within a React component and pass it any options that fit your needs. - * When your component renders, `useProxyAction` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [proxyAction, { data, loading, error }] = useProxyAction({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useProxyAction( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation(ProxyActionDocument, options); -} -export type ProxyActionHookResult = ReturnType; -export type ProxyActionMutationResult = Apollo.MutationResult; -export type ProxyActionMutationOptions = Apollo.BaseMutationOptions< - ProxyActionData, - ProxyActionVariables ->; -export const GetPublicationDocument = /*#__PURE__*/ gql` - query GetPublication( - $request: PublicationQueryRequest! - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: publication(request: $request) { - ... on Post { - ...Post - } - ... on Mirror { - ...Mirror - } - ... on Comment { - ...Comment - } - } - } - ${FragmentPost} - ${FragmentMirror} - ${FragmentComment} -`; - -/** - * __useGetPublication__ - * - * To run a query within a React component, call `useGetPublication` and pass it any options that fit your needs. - * When your component renders, `useGetPublication` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useGetPublication({ - * variables: { - * request: // value for 'request' - * observerId: // value for 'observerId' - * sources: // value for 'sources' - * mediaTransformPublicationSmall: // value for 'mediaTransformPublicationSmall' - * mediaTransformPublicationMedium: // value for 'mediaTransformPublicationMedium' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useGetPublication( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - GetPublicationDocument, - options, - ); -} -export function useGetPublicationLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - GetPublicationDocument, - options, - ); -} -export type GetPublicationHookResult = ReturnType; -export type GetPublicationLazyQueryHookResult = ReturnType; -export type GetPublicationQueryResult = Apollo.QueryResult< - GetPublicationData, - GetPublicationVariables ->; -export const HidePublicationDocument = /*#__PURE__*/ gql` - mutation HidePublication($publicationId: InternalPublicationId!) { - hidePublication(request: { publicationId: $publicationId }) - } -`; -export type HidePublicationMutationFn = Apollo.MutationFunction< - HidePublicationData, - HidePublicationVariables ->; - -/** - * __useHidePublication__ - * - * To run a mutation, you first call `useHidePublication` within a React component and pass it any options that fit your needs. - * When your component renders, `useHidePublication` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [hidePublication, { data, loading, error }] = useHidePublication({ - * variables: { - * publicationId: // value for 'publicationId' - * }, - * }); - */ -export function useHidePublication( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - HidePublicationDocument, - options, - ); -} -export type HidePublicationHookResult = ReturnType; -export type HidePublicationMutationResult = Apollo.MutationResult; -export type HidePublicationMutationOptions = Apollo.BaseMutationOptions< - HidePublicationData, - HidePublicationVariables ->; -export const AddNotInterestedDocument = /*#__PURE__*/ gql` - mutation AddNotInterested($request: PublicationProfileNotInterestedRequest!) { - result: addPublicationProfileNotInterested(request: $request) - } -`; -export type AddNotInterestedMutationFn = Apollo.MutationFunction< - AddNotInterestedData, - AddNotInterestedVariables ->; - -/** - * __useAddNotInterested__ - * - * To run a mutation, you first call `useAddNotInterested` within a React component and pass it any options that fit your needs. - * When your component renders, `useAddNotInterested` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [addNotInterested, { data, loading, error }] = useAddNotInterested({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useAddNotInterested( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - AddNotInterestedDocument, - options, - ); -} -export type AddNotInterestedHookResult = ReturnType; -export type AddNotInterestedMutationResult = Apollo.MutationResult; -export type AddNotInterestedMutationOptions = Apollo.BaseMutationOptions< - AddNotInterestedData, - AddNotInterestedVariables ->; -export const RemoveNotInterestedDocument = /*#__PURE__*/ gql` - mutation RemoveNotInterested($request: PublicationProfileNotInterestedRequest!) { - result: removePublicationProfileNotInterested(request: $request) - } -`; -export type RemoveNotInterestedMutationFn = Apollo.MutationFunction< - RemoveNotInterestedData, - RemoveNotInterestedVariables ->; - -/** - * __useRemoveNotInterested__ - * - * To run a mutation, you first call `useRemoveNotInterested` within a React component and pass it any options that fit your needs. - * When your component renders, `useRemoveNotInterested` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [removeNotInterested, { data, loading, error }] = useRemoveNotInterested({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useRemoveNotInterested( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - RemoveNotInterestedDocument, - options, - ); -} -export type RemoveNotInterestedHookResult = ReturnType; -export type RemoveNotInterestedMutationResult = Apollo.MutationResult; -export type RemoveNotInterestedMutationOptions = Apollo.BaseMutationOptions< - RemoveNotInterestedData, - RemoveNotInterestedVariables ->; -export const AddToMyBookmarksDocument = /*#__PURE__*/ gql` - mutation AddToMyBookmarks($request: PublicationProfileBookmarkRequest!) { - result: addPublicationProfileBookmark(request: $request) - } -`; -export type AddToMyBookmarksMutationFn = Apollo.MutationFunction< - AddToMyBookmarksData, - AddToMyBookmarksVariables ->; - -/** - * __useAddToMyBookmarks__ - * - * To run a mutation, you first call `useAddToMyBookmarks` within a React component and pass it any options that fit your needs. - * When your component renders, `useAddToMyBookmarks` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [addToMyBookmarks, { data, loading, error }] = useAddToMyBookmarks({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useAddToMyBookmarks( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - AddToMyBookmarksDocument, - options, - ); -} -export type AddToMyBookmarksHookResult = ReturnType; -export type AddToMyBookmarksMutationResult = Apollo.MutationResult; -export type AddToMyBookmarksMutationOptions = Apollo.BaseMutationOptions< - AddToMyBookmarksData, - AddToMyBookmarksVariables ->; -export const RemoveFromMyBookmarksDocument = /*#__PURE__*/ gql` - mutation RemoveFromMyBookmarks($request: PublicationProfileBookmarkRequest!) { - result: removePublicationProfileBookmark(request: $request) - } -`; -export type RemoveFromMyBookmarksMutationFn = Apollo.MutationFunction< - RemoveFromMyBookmarksData, - RemoveFromMyBookmarksVariables ->; - -/** - * __useRemoveFromMyBookmarks__ - * - * To run a mutation, you first call `useRemoveFromMyBookmarks` within a React component and pass it any options that fit your needs. - * When your component renders, `useRemoveFromMyBookmarks` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [removeFromMyBookmarks, { data, loading, error }] = useRemoveFromMyBookmarks({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useRemoveFromMyBookmarks( - baseOptions?: Apollo.MutationHookOptions< - RemoveFromMyBookmarksData, - RemoveFromMyBookmarksVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - RemoveFromMyBookmarksDocument, - options, - ); -} -export type RemoveFromMyBookmarksHookResult = ReturnType; -export type RemoveFromMyBookmarksMutationResult = Apollo.MutationResult; -export type RemoveFromMyBookmarksMutationOptions = Apollo.BaseMutationOptions< - RemoveFromMyBookmarksData, - RemoveFromMyBookmarksVariables ->; -export const GetPublicationsDocument = /*#__PURE__*/ gql` - query GetPublications( - $profileId: ProfileId - $profileIds: [ProfileId!] - $publicationIds: [InternalPublicationId!] - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $publicationTypes: [PublicationTypes!] - $sources: [Sources!]! - $metadata: PublicationMetadataFilters - $commentsOf: InternalPublicationId - $commentsOfOrdering: CommentOrderingTypes - $commentsRankingFilter: CommentRankingFilter - $walletAddress: EthereumAddress - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: publications( - request: { - profileId: $profileId - profileIds: $profileIds - publicationIds: $publicationIds - limit: $limit - collectedBy: $walletAddress - cursor: $cursor - publicationTypes: $publicationTypes - commentsOf: $commentsOf - commentsOfOrdering: $commentsOfOrdering - commentsRankingFilter: $commentsRankingFilter - sources: $sources - metadata: $metadata - } - ) { - items { - ... on Post { - ...Post - } - ... on Mirror { - ...Mirror - } - ... on Comment { - ...Comment - } - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentPost} - ${FragmentMirror} - ${FragmentComment} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useGetPublications__ - * - * To run a query within a React component, call `useGetPublications` and pass it any options that fit your needs. - * When your component renders, `useGetPublications` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useGetPublications({ - * variables: { - * profileId: // value for 'profileId' - * profileIds: // value for 'profileIds' - * publicationIds: // value for 'publicationIds' - * observerId: // value for 'observerId' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * publicationTypes: // value for 'publicationTypes' - * sources: // value for 'sources' - * metadata: // value for 'metadata' - * commentsOf: // value for 'commentsOf' - * commentsOfOrdering: // value for 'commentsOfOrdering' - * commentsRankingFilter: // value for 'commentsRankingFilter' - * walletAddress: // value for 'walletAddress' - * mediaTransformPublicationSmall: // value for 'mediaTransformPublicationSmall' - * mediaTransformPublicationMedium: // value for 'mediaTransformPublicationMedium' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useGetPublications( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - GetPublicationsDocument, - options, - ); -} -export function useGetPublicationsLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - GetPublicationsDocument, - options, - ); -} -export type GetPublicationsHookResult = ReturnType; -export type GetPublicationsLazyQueryHookResult = ReturnType; -export type GetPublicationsQueryResult = Apollo.QueryResult< - GetPublicationsData, - GetPublicationsVariables ->; -export const ExplorePublicationsDocument = /*#__PURE__*/ gql` - query ExplorePublications( - $cursor: Cursor - $excludeProfileIds: [ProfileId!] - $limit: LimitScalar! - $metadata: PublicationMetadataFilters - $observerId: ProfileId - $publicationTypes: [PublicationTypes!] - $sortCriteria: PublicationSortCriteria! - $sources: [Sources!]! - $timestamp: TimestampScalar - $noRandomize: Boolean - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: explorePublications( - request: { - cursor: $cursor - excludeProfileIds: $excludeProfileIds - limit: $limit - metadata: $metadata - publicationTypes: $publicationTypes - sortCriteria: $sortCriteria - sources: $sources - timestamp: $timestamp - noRandomize: $noRandomize - } - ) { - items { - ... on Post { - ...Post - } - ... on Mirror { - ...Mirror - } - ... on Comment { - ...Comment - } - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentPost} - ${FragmentMirror} - ${FragmentComment} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useExplorePublications__ - * - * To run a query within a React component, call `useExplorePublications` and pass it any options that fit your needs. - * When your component renders, `useExplorePublications` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useExplorePublications({ - * variables: { - * cursor: // value for 'cursor' - * excludeProfileIds: // value for 'excludeProfileIds' - * limit: // value for 'limit' - * metadata: // value for 'metadata' - * observerId: // value for 'observerId' - * publicationTypes: // value for 'publicationTypes' - * sortCriteria: // value for 'sortCriteria' - * sources: // value for 'sources' - * timestamp: // value for 'timestamp' - * noRandomize: // value for 'noRandomize' - * mediaTransformPublicationSmall: // value for 'mediaTransformPublicationSmall' - * mediaTransformPublicationMedium: // value for 'mediaTransformPublicationMedium' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useExplorePublications( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - ExplorePublicationsDocument, - options, - ); -} -export function useExplorePublicationsLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - ExplorePublicationsDocument, - options, - ); -} -export type ExplorePublicationsHookResult = ReturnType; -export type ExplorePublicationsLazyQueryHookResult = ReturnType< - typeof useExplorePublicationsLazyQuery ->; -export type ExplorePublicationsQueryResult = Apollo.QueryResult< - ExplorePublicationsData, - ExplorePublicationsVariables ->; -export const WhoCollectedPublicationDocument = /*#__PURE__*/ gql` - query WhoCollectedPublication( - $publicationId: InternalPublicationId! - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: whoCollectedPublication( - request: { publicationId: $publicationId, limit: $limit, cursor: $cursor } - ) { - items { - ...Wallet - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentWallet} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useWhoCollectedPublication__ - * - * To run a query within a React component, call `useWhoCollectedPublication` and pass it any options that fit your needs. - * When your component renders, `useWhoCollectedPublication` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useWhoCollectedPublication({ - * variables: { - * publicationId: // value for 'publicationId' - * observerId: // value for 'observerId' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * sources: // value for 'sources' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useWhoCollectedPublication( - baseOptions: Apollo.QueryHookOptions< - WhoCollectedPublicationData, - WhoCollectedPublicationVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - WhoCollectedPublicationDocument, - options, - ); -} -export function useWhoCollectedPublicationLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - WhoCollectedPublicationData, - WhoCollectedPublicationVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - WhoCollectedPublicationDocument, - options, - ); -} -export type WhoCollectedPublicationHookResult = ReturnType; -export type WhoCollectedPublicationLazyQueryHookResult = ReturnType< - typeof useWhoCollectedPublicationLazyQuery ->; -export type WhoCollectedPublicationQueryResult = Apollo.QueryResult< - WhoCollectedPublicationData, - WhoCollectedPublicationVariables ->; -export const ProfilePublicationsForSaleDocument = /*#__PURE__*/ gql` - query ProfilePublicationsForSale( - $profileId: ProfileId! - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!]! - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: profilePublicationsForSale( - request: { profileId: $profileId, limit: $limit, cursor: $cursor, sources: $sources } - ) { - items { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentPost} - ${FragmentComment} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useProfilePublicationsForSale__ - * - * To run a query within a React component, call `useProfilePublicationsForSale` and pass it any options that fit your needs. - * When your component renders, `useProfilePublicationsForSale` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useProfilePublicationsForSale({ - * variables: { - * profileId: // value for 'profileId' - * observerId: // value for 'observerId' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * sources: // value for 'sources' - * mediaTransformPublicationSmall: // value for 'mediaTransformPublicationSmall' - * mediaTransformPublicationMedium: // value for 'mediaTransformPublicationMedium' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useProfilePublicationsForSale( - baseOptions: Apollo.QueryHookOptions< - ProfilePublicationsForSaleData, - ProfilePublicationsForSaleVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - ProfilePublicationsForSaleDocument, - options, - ); -} -export function useProfilePublicationsForSaleLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - ProfilePublicationsForSaleData, - ProfilePublicationsForSaleVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - ProfilePublicationsForSaleDocument, - options, - ); -} -export type ProfilePublicationsForSaleHookResult = ReturnType; -export type ProfilePublicationsForSaleLazyQueryHookResult = ReturnType< - typeof useProfilePublicationsForSaleLazyQuery ->; -export type ProfilePublicationsForSaleQueryResult = Apollo.QueryResult< - ProfilePublicationsForSaleData, - ProfilePublicationsForSaleVariables ->; -export const GetProfileBookmarksDocument = /*#__PURE__*/ gql` - query GetProfileBookmarks( - $profileId: ProfileId! - $limit: LimitScalar! - $sources: [Sources!]! - $metadata: PublicationMetadataFilters - $cursor: Cursor - $observerId: ProfileId - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: publicationsProfileBookmarks( - request: { - cursor: $cursor - limit: $limit - metadata: $metadata - profileId: $profileId - sources: $sources - } - ) { - items { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentPost} - ${FragmentComment} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useGetProfileBookmarks__ - * - * To run a query within a React component, call `useGetProfileBookmarks` and pass it any options that fit your needs. - * When your component renders, `useGetProfileBookmarks` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useGetProfileBookmarks({ - * variables: { - * profileId: // value for 'profileId' - * limit: // value for 'limit' - * sources: // value for 'sources' - * metadata: // value for 'metadata' - * cursor: // value for 'cursor' - * observerId: // value for 'observerId' - * mediaTransformPublicationSmall: // value for 'mediaTransformPublicationSmall' - * mediaTransformPublicationMedium: // value for 'mediaTransformPublicationMedium' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useGetProfileBookmarks( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - GetProfileBookmarksDocument, - options, - ); -} -export function useGetProfileBookmarksLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - GetProfileBookmarksDocument, - options, - ); -} -export type GetProfileBookmarksHookResult = ReturnType; -export type GetProfileBookmarksLazyQueryHookResult = ReturnType< - typeof useGetProfileBookmarksLazyQuery ->; -export type GetProfileBookmarksQueryResult = Apollo.QueryResult< - GetProfileBookmarksData, - GetProfileBookmarksVariables ->; -export const AddReactionDocument = /*#__PURE__*/ gql` - mutation AddReaction( - $publicationId: InternalPublicationId! - $reaction: ReactionTypes! - $profileId: ProfileId! - ) { - addReaction( - request: { publicationId: $publicationId, reaction: $reaction, profileId: $profileId } - ) - } -`; -export type AddReactionMutationFn = Apollo.MutationFunction; - -/** - * __useAddReaction__ - * - * To run a mutation, you first call `useAddReaction` within a React component and pass it any options that fit your needs. - * When your component renders, `useAddReaction` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [addReaction, { data, loading, error }] = useAddReaction({ - * variables: { - * publicationId: // value for 'publicationId' - * reaction: // value for 'reaction' - * profileId: // value for 'profileId' - * }, - * }); - */ -export function useAddReaction( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation(AddReactionDocument, options); -} -export type AddReactionHookResult = ReturnType; -export type AddReactionMutationResult = Apollo.MutationResult; -export type AddReactionMutationOptions = Apollo.BaseMutationOptions< - AddReactionData, - AddReactionVariables ->; -export const RemoveReactionDocument = /*#__PURE__*/ gql` - mutation RemoveReaction( - $publicationId: InternalPublicationId! - $reaction: ReactionTypes! - $profileId: ProfileId! - ) { - removeReaction( - request: { publicationId: $publicationId, reaction: $reaction, profileId: $profileId } - ) - } -`; -export type RemoveReactionMutationFn = Apollo.MutationFunction< - RemoveReactionData, - RemoveReactionVariables ->; - -/** - * __useRemoveReaction__ - * - * To run a mutation, you first call `useRemoveReaction` within a React component and pass it any options that fit your needs. - * When your component renders, `useRemoveReaction` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [removeReaction, { data, loading, error }] = useRemoveReaction({ - * variables: { - * publicationId: // value for 'publicationId' - * reaction: // value for 'reaction' - * profileId: // value for 'profileId' - * }, - * }); - */ -export function useRemoveReaction( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - RemoveReactionDocument, - options, - ); -} -export type RemoveReactionHookResult = ReturnType; -export type RemoveReactionMutationResult = Apollo.MutationResult; -export type RemoveReactionMutationOptions = Apollo.BaseMutationOptions< - RemoveReactionData, - RemoveReactionVariables ->; -export const WhoReactedPublicationDocument = /*#__PURE__*/ gql` - query WhoReactedPublication( - $limit: LimitScalar - $cursor: Cursor - $publicationId: InternalPublicationId! - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: whoReactedPublication( - request: { limit: $limit, cursor: $cursor, publicationId: $publicationId } - ) { - items { - ...WhoReactedResult - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentWhoReactedResult} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useWhoReactedPublication__ - * - * To run a query within a React component, call `useWhoReactedPublication` and pass it any options that fit your needs. - * When your component renders, `useWhoReactedPublication` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useWhoReactedPublication({ - * variables: { - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * publicationId: // value for 'publicationId' - * observerId: // value for 'observerId' - * sources: // value for 'sources' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useWhoReactedPublication( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - WhoReactedPublicationDocument, - options, - ); -} -export function useWhoReactedPublicationLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - WhoReactedPublicationData, - WhoReactedPublicationVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - WhoReactedPublicationDocument, - options, - ); -} -export type WhoReactedPublicationHookResult = ReturnType; -export type WhoReactedPublicationLazyQueryHookResult = ReturnType< - typeof useWhoReactedPublicationLazyQuery ->; -export type WhoReactedPublicationQueryResult = Apollo.QueryResult< - WhoReactedPublicationData, - WhoReactedPublicationVariables ->; -export const ReportPublicationDocument = /*#__PURE__*/ gql` - mutation ReportPublication( - $publicationId: InternalPublicationId! - $reason: ReportingReasonInputParams! - $additionalComments: String - ) { - reportPublication( - request: { - publicationId: $publicationId - reason: $reason - additionalComments: $additionalComments - } - ) - } -`; -export type ReportPublicationMutationFn = Apollo.MutationFunction< - ReportPublicationData, - ReportPublicationVariables ->; - -/** - * __useReportPublication__ - * - * To run a mutation, you first call `useReportPublication` within a React component and pass it any options that fit your needs. - * When your component renders, `useReportPublication` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [reportPublication, { data, loading, error }] = useReportPublication({ - * variables: { - * publicationId: // value for 'publicationId' - * reason: // value for 'reason' - * additionalComments: // value for 'additionalComments' - * }, - * }); - */ -export function useReportPublication( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - ReportPublicationDocument, - options, - ); -} -export type ReportPublicationHookResult = ReturnType; -export type ReportPublicationMutationResult = Apollo.MutationResult; -export type ReportPublicationMutationOptions = Apollo.BaseMutationOptions< - ReportPublicationData, - ReportPublicationVariables ->; -export const GetPublicationRevenueDocument = /*#__PURE__*/ gql` - query GetPublicationRevenue( - $publicationId: InternalPublicationId! - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: publicationRevenue(request: { publicationId: $publicationId }) { - ...PublicationRevenue - } - } - ${FragmentPublicationRevenue} -`; - -/** - * __useGetPublicationRevenue__ - * - * To run a query within a React component, call `useGetPublicationRevenue` and pass it any options that fit your needs. - * When your component renders, `useGetPublicationRevenue` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useGetPublicationRevenue({ - * variables: { - * publicationId: // value for 'publicationId' - * observerId: // value for 'observerId' - * sources: // value for 'sources' - * mediaTransformPublicationSmall: // value for 'mediaTransformPublicationSmall' - * mediaTransformPublicationMedium: // value for 'mediaTransformPublicationMedium' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useGetPublicationRevenue( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - GetPublicationRevenueDocument, - options, - ); -} -export function useGetPublicationRevenueLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - GetPublicationRevenueData, - GetPublicationRevenueVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - GetPublicationRevenueDocument, - options, - ); -} -export type GetPublicationRevenueHookResult = ReturnType; -export type GetPublicationRevenueLazyQueryHookResult = ReturnType< - typeof useGetPublicationRevenueLazyQuery ->; -export type GetPublicationRevenueQueryResult = Apollo.QueryResult< - GetPublicationRevenueData, - GetPublicationRevenueVariables ->; -export const GetProfilePublicationRevenueDocument = /*#__PURE__*/ gql` - query GetProfilePublicationRevenue( - $profileId: ProfileId! - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $publicationTypes: [PublicationTypes!] - $sources: [Sources!]! - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: profilePublicationRevenue( - request: { - profileId: $profileId - limit: $limit - cursor: $cursor - types: $publicationTypes - sources: $sources - } - ) { - items { - ...PublicationRevenue - } - pageInfo { - ...PaginatedResultInfo - } - } - } - ${FragmentPublicationRevenue} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useGetProfilePublicationRevenue__ - * - * To run a query within a React component, call `useGetProfilePublicationRevenue` and pass it any options that fit your needs. - * When your component renders, `useGetProfilePublicationRevenue` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useGetProfilePublicationRevenue({ - * variables: { - * profileId: // value for 'profileId' - * observerId: // value for 'observerId' - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * publicationTypes: // value for 'publicationTypes' - * sources: // value for 'sources' - * mediaTransformPublicationSmall: // value for 'mediaTransformPublicationSmall' - * mediaTransformPublicationMedium: // value for 'mediaTransformPublicationMedium' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useGetProfilePublicationRevenue( - baseOptions: Apollo.QueryHookOptions< - GetProfilePublicationRevenueData, - GetProfilePublicationRevenueVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - GetProfilePublicationRevenueDocument, - options, - ); -} -export function useGetProfilePublicationRevenueLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - GetProfilePublicationRevenueData, - GetProfilePublicationRevenueVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery< - GetProfilePublicationRevenueData, - GetProfilePublicationRevenueVariables - >(GetProfilePublicationRevenueDocument, options); -} -export type GetProfilePublicationRevenueHookResult = ReturnType< - typeof useGetProfilePublicationRevenue ->; -export type GetProfilePublicationRevenueLazyQueryHookResult = ReturnType< - typeof useGetProfilePublicationRevenueLazyQuery ->; -export type GetProfilePublicationRevenueQueryResult = Apollo.QueryResult< - GetProfilePublicationRevenueData, - GetProfilePublicationRevenueVariables ->; -export const ProfileFollowRevenueDocument = /*#__PURE__*/ gql` - query ProfileFollowRevenue($profileId: ProfileId!) { - result: profileFollowRevenue(request: { profileId: $profileId }) { - ...ProfileFollowRevenue - } - } - ${FragmentProfileFollowRevenue} -`; - -/** - * __useProfileFollowRevenue__ - * - * To run a query within a React component, call `useProfileFollowRevenue` and pass it any options that fit your needs. - * When your component renders, `useProfileFollowRevenue` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useProfileFollowRevenue({ - * variables: { - * profileId: // value for 'profileId' - * }, - * }); - */ -export function useProfileFollowRevenue( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - ProfileFollowRevenueDocument, - options, - ); -} -export function useProfileFollowRevenueLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - ProfileFollowRevenueData, - ProfileFollowRevenueVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - ProfileFollowRevenueDocument, - options, - ); -} -export type ProfileFollowRevenueHookResult = ReturnType; -export type ProfileFollowRevenueLazyQueryHookResult = ReturnType< - typeof useProfileFollowRevenueLazyQuery ->; -export type ProfileFollowRevenueQueryResult = Apollo.QueryResult< - ProfileFollowRevenueData, - ProfileFollowRevenueVariables ->; -export const SearchPublicationsDocument = /*#__PURE__*/ gql` - query SearchPublications( - $limit: LimitScalar - $cursor: Cursor - $query: Search! - $sources: [Sources!]! - $observerId: ProfileId - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: search( - request: { - query: $query - type: PUBLICATION - limit: $limit - cursor: $cursor - sources: $sources - } - ) { - ... on PublicationSearchResult { - __typename - items { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - } - pageInfo { - ...PaginatedResultInfo - } - } - } - } - ${FragmentPost} - ${FragmentComment} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useSearchPublications__ - * - * To run a query within a React component, call `useSearchPublications` and pass it any options that fit your needs. - * When your component renders, `useSearchPublications` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useSearchPublications({ - * variables: { - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * query: // value for 'query' - * sources: // value for 'sources' - * observerId: // value for 'observerId' - * mediaTransformPublicationSmall: // value for 'mediaTransformPublicationSmall' - * mediaTransformPublicationMedium: // value for 'mediaTransformPublicationMedium' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useSearchPublications( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - SearchPublicationsDocument, - options, - ); -} -export function useSearchPublicationsLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - SearchPublicationsDocument, - options, - ); -} -export type SearchPublicationsHookResult = ReturnType; -export type SearchPublicationsLazyQueryHookResult = ReturnType< - typeof useSearchPublicationsLazyQuery ->; -export type SearchPublicationsQueryResult = Apollo.QueryResult< - SearchPublicationsData, - SearchPublicationsVariables ->; -export const SearchProfilesDocument = /*#__PURE__*/ gql` - query SearchProfiles( - $limit: LimitScalar! - $cursor: Cursor - $query: Search! - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} - ) { - result: search(request: { query: $query, type: PROFILE, limit: $limit, cursor: $cursor }) { - ... on ProfileSearchResult { - __typename - items { - ...Profile - } - pageInfo { - ...PaginatedResultInfo - } - } - } - } - ${FragmentProfile} - ${FragmentPaginatedResultInfo} -`; - -/** - * __useSearchProfiles__ - * - * To run a query within a React component, call `useSearchProfiles` and pass it any options that fit your needs. - * When your component renders, `useSearchProfiles` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useSearchProfiles({ - * variables: { - * limit: // value for 'limit' - * cursor: // value for 'cursor' - * query: // value for 'query' - * observerId: // value for 'observerId' - * sources: // value for 'sources' - * mediaTransformProfileThumbnail: // value for 'mediaTransformProfileThumbnail' - * }, - * }); - */ -export function useSearchProfiles( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - SearchProfilesDocument, - options, - ); -} -export function useSearchProfilesLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - SearchProfilesDocument, - options, - ); -} -export type SearchProfilesHookResult = ReturnType; -export type SearchProfilesLazyQueryHookResult = ReturnType; -export type SearchProfilesQueryResult = Apollo.QueryResult< - SearchProfilesData, - SearchProfilesVariables ->; -export const HasTxHashBeenIndexedDocument = /*#__PURE__*/ gql` - query HasTxHashBeenIndexed($request: HasTxHashBeenIndexedRequest!) { - result: hasTxHashBeenIndexed(request: $request) { - ... on TransactionIndexedResult { - ...TransactionIndexedResult - } - ... on TransactionError { - ...TransactionError - } - } - } - ${FragmentTransactionIndexedResult} - ${FragmentTransactionError} -`; - -/** - * __useHasTxHashBeenIndexed__ - * - * To run a query within a React component, call `useHasTxHashBeenIndexed` and pass it any options that fit your needs. - * When your component renders, `useHasTxHashBeenIndexed` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useHasTxHashBeenIndexed({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useHasTxHashBeenIndexed( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - HasTxHashBeenIndexedDocument, - options, - ); -} -export function useHasTxHashBeenIndexedLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions< - HasTxHashBeenIndexedData, - HasTxHashBeenIndexedVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - HasTxHashBeenIndexedDocument, - options, - ); -} -export type HasTxHashBeenIndexedHookResult = ReturnType; -export type HasTxHashBeenIndexedLazyQueryHookResult = ReturnType< - typeof useHasTxHashBeenIndexedLazyQuery ->; -export type HasTxHashBeenIndexedQueryResult = Apollo.QueryResult< - HasTxHashBeenIndexedData, - HasTxHashBeenIndexedVariables ->; -export const BroadcastOnChainDocument = /*#__PURE__*/ gql` - mutation BroadcastOnChain($request: BroadcastRequest!) { - result: broadcast(request: $request) { - ...BroadcastOnChainResult - } - } - ${FragmentBroadcastOnChainResult} -`; -export type BroadcastOnChainMutationFn = Apollo.MutationFunction< - BroadcastOnChainData, - BroadcastOnChainVariables ->; - -/** - * __useBroadcastOnChain__ - * - * To run a mutation, you first call `useBroadcastOnChain` within a React component and pass it any options that fit your needs. - * When your component renders, `useBroadcastOnChain` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [broadcastOnChain, { data, loading, error }] = useBroadcastOnChain({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useBroadcastOnChain( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - BroadcastOnChainDocument, - options, - ); -} -export type BroadcastOnChainHookResult = ReturnType; -export type BroadcastOnChainMutationResult = Apollo.MutationResult; -export type BroadcastOnChainMutationOptions = Apollo.BaseMutationOptions< - BroadcastOnChainData, - BroadcastOnChainVariables ->; -export const BroadcastOffChainDocument = /*#__PURE__*/ gql` - mutation BroadcastOffChain($request: BroadcastRequest!) { - result: broadcastDataAvailability(request: $request) { - ...BroadcastOffChainResult - } - } - ${FragmentBroadcastOffChainResult} -`; -export type BroadcastOffChainMutationFn = Apollo.MutationFunction< - BroadcastOffChainData, - BroadcastOffChainVariables ->; - -/** - * __useBroadcastOffChain__ - * - * To run a mutation, you first call `useBroadcastOffChain` within a React component and pass it any options that fit your needs. - * When your component renders, `useBroadcastOffChain` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [broadcastOffChain, { data, loading, error }] = useBroadcastOffChain({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useBroadcastOffChain( - baseOptions?: Apollo.MutationHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - BroadcastOffChainDocument, - options, - ); -} -export type BroadcastOffChainHookResult = ReturnType; -export type BroadcastOffChainMutationResult = Apollo.MutationResult; -export type BroadcastOffChainMutationOptions = Apollo.BaseMutationOptions< - BroadcastOffChainData, - BroadcastOffChainVariables ->; -export const CreateUnfollowTypedDataDocument = /*#__PURE__*/ gql` - mutation CreateUnfollowTypedData($request: UnfollowRequest!) { - result: createUnfollowTypedData(request: $request) { - id - expiresAt - typedData { - types { - BurnWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - tokenId - } - } - } - } - ${FragmentEip712TypedDataDomain} -`; -export type CreateUnfollowTypedDataMutationFn = Apollo.MutationFunction< - CreateUnfollowTypedDataData, - CreateUnfollowTypedDataVariables ->; - -/** - * __useCreateUnfollowTypedData__ - * - * To run a mutation, you first call `useCreateUnfollowTypedData` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateUnfollowTypedData` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [createUnfollowTypedData, { data, loading, error }] = useCreateUnfollowTypedData({ - * variables: { - * request: // value for 'request' - * }, - * }); - */ -export function useCreateUnfollowTypedData( - baseOptions?: Apollo.MutationHookOptions< - CreateUnfollowTypedDataData, - CreateUnfollowTypedDataVariables - >, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useMutation( - CreateUnfollowTypedDataDocument, - options, - ); -} -export type CreateUnfollowTypedDataHookResult = ReturnType; -export type CreateUnfollowTypedDataMutationResult = - Apollo.MutationResult; -export type CreateUnfollowTypedDataMutationOptions = Apollo.BaseMutationOptions< - CreateUnfollowTypedDataData, - CreateUnfollowTypedDataVariables ->; -export type AaveFeeCollectModuleSettingsKeySpecifier = ( - | 'amount' - | 'collectLimit' - | 'contractAddress' - | 'endTimestamp' - | 'followerOnly' - | 'recipient' - | 'referralFee' - | 'type' - | AaveFeeCollectModuleSettingsKeySpecifier -)[]; -export type AaveFeeCollectModuleSettingsFieldPolicy = { - amount?: FieldPolicy | FieldReadFunction; - collectLimit?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - endTimestamp?: FieldPolicy | FieldReadFunction; - followerOnly?: FieldPolicy | FieldReadFunction; - recipient?: FieldPolicy | FieldReadFunction; - referralFee?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type AccessConditionOutputKeySpecifier = ( - | 'and' - | 'collect' - | 'eoa' - | 'follow' - | 'nft' - | 'or' - | 'profile' - | 'token' - | AccessConditionOutputKeySpecifier -)[]; -export type AccessConditionOutputFieldPolicy = { - and?: FieldPolicy | FieldReadFunction; - collect?: FieldPolicy | FieldReadFunction; - eoa?: FieldPolicy | FieldReadFunction; - follow?: FieldPolicy | FieldReadFunction; - nft?: FieldPolicy | FieldReadFunction; - or?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - token?: FieldPolicy | FieldReadFunction; -}; -export type AndConditionOutputKeySpecifier = ('criteria' | AndConditionOutputKeySpecifier)[]; -export type AndConditionOutputFieldPolicy = { - criteria?: FieldPolicy | FieldReadFunction; -}; -export type ApprovedAllowanceAmountKeySpecifier = ( - | 'allowance' - | 'contractAddress' - | 'currency' - | 'module' - | ApprovedAllowanceAmountKeySpecifier -)[]; -export type ApprovedAllowanceAmountFieldPolicy = { - allowance?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - currency?: FieldPolicy | FieldReadFunction; - module?: FieldPolicy | FieldReadFunction; -}; -export type AttributeKeySpecifier = ( - | 'displayType' - | 'key' - | 'traitType' - | 'value' - | AttributeKeySpecifier -)[]; -export type AttributeFieldPolicy = { - displayType?: FieldPolicy | FieldReadFunction; - key?: FieldPolicy | FieldReadFunction; - traitType?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type AuthChallengeResultKeySpecifier = ('text' | AuthChallengeResultKeySpecifier)[]; -export type AuthChallengeResultFieldPolicy = { - text?: FieldPolicy | FieldReadFunction; -}; -export type AuthenticationResultKeySpecifier = ( - | 'accessToken' - | 'refreshToken' - | AuthenticationResultKeySpecifier -)[]; -export type AuthenticationResultFieldPolicy = { - accessToken?: FieldPolicy | FieldReadFunction; - refreshToken?: FieldPolicy | FieldReadFunction; -}; -export type CanCommentResponseKeySpecifier = ('result' | CanCommentResponseKeySpecifier)[]; -export type CanCommentResponseFieldPolicy = { - result?: FieldPolicy | FieldReadFunction; -}; -export type CanDecryptResponseKeySpecifier = ( - | 'extraDetails' - | 'reasons' - | 'result' - | CanDecryptResponseKeySpecifier -)[]; -export type CanDecryptResponseFieldPolicy = { - extraDetails?: FieldPolicy | FieldReadFunction; - reasons?: FieldPolicy | FieldReadFunction; - result?: FieldPolicy | FieldReadFunction; -}; -export type CanMirrorResponseKeySpecifier = ('result' | CanMirrorResponseKeySpecifier)[]; -export type CanMirrorResponseFieldPolicy = { - result?: FieldPolicy | FieldReadFunction; -}; -export type ClaimableHandlesKeySpecifier = ( - | 'canClaimFreeTextHandle' - | 'reservedHandles' - | ClaimableHandlesKeySpecifier -)[]; -export type ClaimableHandlesFieldPolicy = { - canClaimFreeTextHandle?: FieldPolicy | FieldReadFunction; - reservedHandles?: FieldPolicy | FieldReadFunction; -}; -export type CollectConditionOutputKeySpecifier = ( - | 'publicationId' - | 'thisPublication' - | CollectConditionOutputKeySpecifier -)[]; -export type CollectConditionOutputFieldPolicy = { - publicationId?: FieldPolicy | FieldReadFunction; - thisPublication?: FieldPolicy | FieldReadFunction; -}; -export type CollectedEventKeySpecifier = ('profile' | 'timestamp' | CollectedEventKeySpecifier)[]; -export type CollectedEventFieldPolicy = { - profile?: FieldPolicy | FieldReadFunction; - timestamp?: FieldPolicy | FieldReadFunction; -}; -export type CommentKeySpecifier = ( - | 'appId' - | 'bookmarked' - | 'canComment' - | 'canDecrypt' - | 'canMirror' - | 'collectModule' - | 'collectNftAddress' - | 'collectPolicy' - | 'collectedBy' - | 'commentOn' - | 'contentInsight' - | 'createdAt' - | 'dataAvailabilityProofs' - | 'decryptionCriteria' - | 'firstComment' - | 'hasCollectedByMe' - | 'hasOptimisticCollectedByMe' - | 'hidden' - | 'id' - | 'isDataAvailability' - | 'isGated' - | 'isMirroredByMe' - | 'isOptimisticMirroredByMe' - | 'mainPost' - | 'metadata' - | 'mirrors' - | 'notInterested' - | 'observedBy' - | 'onChainContentURI' - | 'profile' - | 'rankingScore' - | 'reaction' - | 'referenceModule' - | 'referencePolicy' - | 'stats' - | CommentKeySpecifier -)[]; -export type CommentFieldPolicy = { - appId?: FieldPolicy | FieldReadFunction; - bookmarked?: FieldPolicy | FieldReadFunction; - canComment?: FieldPolicy | FieldReadFunction; - canDecrypt?: FieldPolicy | FieldReadFunction; - canMirror?: FieldPolicy | FieldReadFunction; - collectModule?: FieldPolicy | FieldReadFunction; - collectNftAddress?: FieldPolicy | FieldReadFunction; - collectPolicy?: FieldPolicy | FieldReadFunction; - collectedBy?: FieldPolicy | FieldReadFunction; - commentOn?: FieldPolicy | FieldReadFunction; - contentInsight?: FieldPolicy | FieldReadFunction; - createdAt?: FieldPolicy | FieldReadFunction; - dataAvailabilityProofs?: FieldPolicy | FieldReadFunction; - decryptionCriteria?: FieldPolicy | FieldReadFunction; - firstComment?: FieldPolicy | FieldReadFunction; - hasCollectedByMe?: FieldPolicy | FieldReadFunction; - hasOptimisticCollectedByMe?: FieldPolicy | FieldReadFunction; - hidden?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - isDataAvailability?: FieldPolicy | FieldReadFunction; - isGated?: FieldPolicy | FieldReadFunction; - isMirroredByMe?: FieldPolicy | FieldReadFunction; - isOptimisticMirroredByMe?: FieldPolicy | FieldReadFunction; - mainPost?: FieldPolicy | FieldReadFunction; - metadata?: FieldPolicy | FieldReadFunction; - mirrors?: FieldPolicy | FieldReadFunction; - notInterested?: FieldPolicy | FieldReadFunction; - observedBy?: FieldPolicy | FieldReadFunction; - onChainContentURI?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - rankingScore?: FieldPolicy | FieldReadFunction; - reaction?: FieldPolicy | FieldReadFunction; - referenceModule?: FieldPolicy | FieldReadFunction; - referencePolicy?: FieldPolicy | FieldReadFunction; - stats?: FieldPolicy | FieldReadFunction; -}; -export type CreateBurnEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateBurnEIP712TypedDataKeySpecifier -)[]; -export type CreateBurnEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateBurnEIP712TypedDataTypesKeySpecifier = ( - | 'BurnWithSig' - | CreateBurnEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateBurnEIP712TypedDataTypesFieldPolicy = { - BurnWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateBurnEIP712TypedDataValueKeySpecifier = ( - | 'deadline' - | 'nonce' - | 'tokenId' - | CreateBurnEIP712TypedDataValueKeySpecifier -)[]; -export type CreateBurnEIP712TypedDataValueFieldPolicy = { - deadline?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - tokenId?: FieldPolicy | FieldReadFunction; -}; -export type CreateBurnProfileBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateBurnProfileBroadcastItemResultKeySpecifier -)[]; -export type CreateBurnProfileBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateCollectBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateCollectBroadcastItemResultKeySpecifier -)[]; -export type CreateCollectBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateCollectEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateCollectEIP712TypedDataKeySpecifier -)[]; -export type CreateCollectEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateCollectEIP712TypedDataTypesKeySpecifier = ( - | 'CollectWithSig' - | CreateCollectEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateCollectEIP712TypedDataTypesFieldPolicy = { - CollectWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateCollectEIP712TypedDataValueKeySpecifier = ( - | 'data' - | 'deadline' - | 'nonce' - | 'profileId' - | 'pubId' - | CreateCollectEIP712TypedDataValueKeySpecifier -)[]; -export type CreateCollectEIP712TypedDataValueFieldPolicy = { - data?: FieldPolicy | FieldReadFunction; - deadline?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; - pubId?: FieldPolicy | FieldReadFunction; -}; -export type CreateCommentBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateCommentBroadcastItemResultKeySpecifier -)[]; -export type CreateCommentBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateCommentEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateCommentEIP712TypedDataKeySpecifier -)[]; -export type CreateCommentEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateCommentEIP712TypedDataTypesKeySpecifier = ( - | 'CommentWithSig' - | CreateCommentEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateCommentEIP712TypedDataTypesFieldPolicy = { - CommentWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateCommentEIP712TypedDataValueKeySpecifier = ( - | 'collectModule' - | 'collectModuleInitData' - | 'contentURI' - | 'deadline' - | 'nonce' - | 'profileId' - | 'profileIdPointed' - | 'pubIdPointed' - | 'referenceModule' - | 'referenceModuleData' - | 'referenceModuleInitData' - | CreateCommentEIP712TypedDataValueKeySpecifier -)[]; -export type CreateCommentEIP712TypedDataValueFieldPolicy = { - collectModule?: FieldPolicy | FieldReadFunction; - collectModuleInitData?: FieldPolicy | FieldReadFunction; - contentURI?: FieldPolicy | FieldReadFunction; - deadline?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; - profileIdPointed?: FieldPolicy | FieldReadFunction; - pubIdPointed?: FieldPolicy | FieldReadFunction; - referenceModule?: FieldPolicy | FieldReadFunction; - referenceModuleData?: FieldPolicy | FieldReadFunction; - referenceModuleInitData?: FieldPolicy | FieldReadFunction; -}; -export type CreateDataAvailabilityPublicationResultKeySpecifier = ( - | 'dataAvailabilityId' - | 'id' - | 'proofs' - | CreateDataAvailabilityPublicationResultKeySpecifier -)[]; -export type CreateDataAvailabilityPublicationResultFieldPolicy = { - dataAvailabilityId?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - proofs?: FieldPolicy | FieldReadFunction; -}; -export type CreateFollowBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateFollowBroadcastItemResultKeySpecifier -)[]; -export type CreateFollowBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateFollowEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateFollowEIP712TypedDataKeySpecifier -)[]; -export type CreateFollowEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateFollowEIP712TypedDataTypesKeySpecifier = ( - | 'FollowWithSig' - | CreateFollowEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateFollowEIP712TypedDataTypesFieldPolicy = { - FollowWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateFollowEIP712TypedDataValueKeySpecifier = ( - | 'datas' - | 'deadline' - | 'nonce' - | 'profileIds' - | CreateFollowEIP712TypedDataValueKeySpecifier -)[]; -export type CreateFollowEIP712TypedDataValueFieldPolicy = { - datas?: FieldPolicy | FieldReadFunction; - deadline?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileIds?: FieldPolicy | FieldReadFunction; -}; -export type CreateMirrorBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateMirrorBroadcastItemResultKeySpecifier -)[]; -export type CreateMirrorBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateMirrorEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateMirrorEIP712TypedDataKeySpecifier -)[]; -export type CreateMirrorEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateMirrorEIP712TypedDataTypesKeySpecifier = ( - | 'MirrorWithSig' - | CreateMirrorEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateMirrorEIP712TypedDataTypesFieldPolicy = { - MirrorWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateMirrorEIP712TypedDataValueKeySpecifier = ( - | 'deadline' - | 'nonce' - | 'profileId' - | 'profileIdPointed' - | 'pubIdPointed' - | 'referenceModule' - | 'referenceModuleData' - | 'referenceModuleInitData' - | CreateMirrorEIP712TypedDataValueKeySpecifier -)[]; -export type CreateMirrorEIP712TypedDataValueFieldPolicy = { - deadline?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; - profileIdPointed?: FieldPolicy | FieldReadFunction; - pubIdPointed?: FieldPolicy | FieldReadFunction; - referenceModule?: FieldPolicy | FieldReadFunction; - referenceModuleData?: FieldPolicy | FieldReadFunction; - referenceModuleInitData?: FieldPolicy | FieldReadFunction; -}; -export type CreatePostBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreatePostBroadcastItemResultKeySpecifier -)[]; -export type CreatePostBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreatePostEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreatePostEIP712TypedDataKeySpecifier -)[]; -export type CreatePostEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreatePostEIP712TypedDataTypesKeySpecifier = ( - | 'PostWithSig' - | CreatePostEIP712TypedDataTypesKeySpecifier -)[]; -export type CreatePostEIP712TypedDataTypesFieldPolicy = { - PostWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreatePostEIP712TypedDataValueKeySpecifier = ( - | 'collectModule' - | 'collectModuleInitData' - | 'contentURI' - | 'deadline' - | 'nonce' - | 'profileId' - | 'referenceModule' - | 'referenceModuleInitData' - | CreatePostEIP712TypedDataValueKeySpecifier -)[]; -export type CreatePostEIP712TypedDataValueFieldPolicy = { - collectModule?: FieldPolicy | FieldReadFunction; - collectModuleInitData?: FieldPolicy | FieldReadFunction; - contentURI?: FieldPolicy | FieldReadFunction; - deadline?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; - referenceModule?: FieldPolicy | FieldReadFunction; - referenceModuleInitData?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetDispatcherBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateSetDispatcherBroadcastItemResultKeySpecifier -)[]; -export type CreateSetDispatcherBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetDispatcherEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateSetDispatcherEIP712TypedDataKeySpecifier -)[]; -export type CreateSetDispatcherEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetDispatcherEIP712TypedDataTypesKeySpecifier = ( - | 'SetDispatcherWithSig' - | CreateSetDispatcherEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateSetDispatcherEIP712TypedDataTypesFieldPolicy = { - SetDispatcherWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetDispatcherEIP712TypedDataValueKeySpecifier = ( - | 'deadline' - | 'dispatcher' - | 'nonce' - | 'profileId' - | CreateSetDispatcherEIP712TypedDataValueKeySpecifier -)[]; -export type CreateSetDispatcherEIP712TypedDataValueFieldPolicy = { - deadline?: FieldPolicy | FieldReadFunction; - dispatcher?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetFollowModuleBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateSetFollowModuleBroadcastItemResultKeySpecifier -)[]; -export type CreateSetFollowModuleBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetFollowModuleEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateSetFollowModuleEIP712TypedDataKeySpecifier -)[]; -export type CreateSetFollowModuleEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetFollowModuleEIP712TypedDataTypesKeySpecifier = ( - | 'SetFollowModuleWithSig' - | CreateSetFollowModuleEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateSetFollowModuleEIP712TypedDataTypesFieldPolicy = { - SetFollowModuleWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetFollowModuleEIP712TypedDataValueKeySpecifier = ( - | 'deadline' - | 'followModule' - | 'followModuleInitData' - | 'nonce' - | 'profileId' - | CreateSetFollowModuleEIP712TypedDataValueKeySpecifier -)[]; -export type CreateSetFollowModuleEIP712TypedDataValueFieldPolicy = { - deadline?: FieldPolicy | FieldReadFunction; - followModule?: FieldPolicy | FieldReadFunction; - followModuleInitData?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetFollowNFTUriBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateSetFollowNFTUriBroadcastItemResultKeySpecifier -)[]; -export type CreateSetFollowNFTUriBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetFollowNFTUriEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateSetFollowNFTUriEIP712TypedDataKeySpecifier -)[]; -export type CreateSetFollowNFTUriEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetFollowNFTUriEIP712TypedDataTypesKeySpecifier = ( - | 'SetFollowNFTURIWithSig' - | CreateSetFollowNFTUriEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateSetFollowNFTUriEIP712TypedDataTypesFieldPolicy = { - SetFollowNFTURIWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetFollowNFTUriEIP712TypedDataValueKeySpecifier = ( - | 'deadline' - | 'followNFTURI' - | 'nonce' - | 'profileId' - | CreateSetFollowNFTUriEIP712TypedDataValueKeySpecifier -)[]; -export type CreateSetFollowNFTUriEIP712TypedDataValueFieldPolicy = { - deadline?: FieldPolicy | FieldReadFunction; - followNFTURI?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetProfileImageUriBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateSetProfileImageUriBroadcastItemResultKeySpecifier -)[]; -export type CreateSetProfileImageUriBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetProfileImageUriEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateSetProfileImageUriEIP712TypedDataKeySpecifier -)[]; -export type CreateSetProfileImageUriEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetProfileImageUriEIP712TypedDataTypesKeySpecifier = ( - | 'SetProfileImageURIWithSig' - | CreateSetProfileImageUriEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateSetProfileImageUriEIP712TypedDataTypesFieldPolicy = { - SetProfileImageURIWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetProfileImageUriEIP712TypedDataValueKeySpecifier = ( - | 'deadline' - | 'imageURI' - | 'nonce' - | 'profileId' - | CreateSetProfileImageUriEIP712TypedDataValueKeySpecifier -)[]; -export type CreateSetProfileImageUriEIP712TypedDataValueFieldPolicy = { - deadline?: FieldPolicy | FieldReadFunction; - imageURI?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetProfileMetadataURIBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateSetProfileMetadataURIBroadcastItemResultKeySpecifier -)[]; -export type CreateSetProfileMetadataURIBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetProfileMetadataURIEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateSetProfileMetadataURIEIP712TypedDataKeySpecifier -)[]; -export type CreateSetProfileMetadataURIEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetProfileMetadataURIEIP712TypedDataTypesKeySpecifier = ( - | 'SetProfileMetadataURIWithSig' - | CreateSetProfileMetadataURIEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateSetProfileMetadataURIEIP712TypedDataTypesFieldPolicy = { - SetProfileMetadataURIWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateSetProfileMetadataURIEIP712TypedDataValueKeySpecifier = ( - | 'deadline' - | 'metadata' - | 'nonce' - | 'profileId' - | CreateSetProfileMetadataURIEIP712TypedDataValueKeySpecifier -)[]; -export type CreateSetProfileMetadataURIEIP712TypedDataValueFieldPolicy = { - deadline?: FieldPolicy | FieldReadFunction; - metadata?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; -}; -export type CreateToggleFollowBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateToggleFollowBroadcastItemResultKeySpecifier -)[]; -export type CreateToggleFollowBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type CreateToggleFollowEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | CreateToggleFollowEIP712TypedDataKeySpecifier -)[]; -export type CreateToggleFollowEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type CreateToggleFollowEIP712TypedDataTypesKeySpecifier = ( - | 'ToggleFollowWithSig' - | CreateToggleFollowEIP712TypedDataTypesKeySpecifier -)[]; -export type CreateToggleFollowEIP712TypedDataTypesFieldPolicy = { - ToggleFollowWithSig?: FieldPolicy | FieldReadFunction; -}; -export type CreateToggleFollowEIP712TypedDataValueKeySpecifier = ( - | 'deadline' - | 'enables' - | 'nonce' - | 'profileIds' - | CreateToggleFollowEIP712TypedDataValueKeySpecifier -)[]; -export type CreateToggleFollowEIP712TypedDataValueFieldPolicy = { - deadline?: FieldPolicy | FieldReadFunction; - enables?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileIds?: FieldPolicy | FieldReadFunction; -}; -export type CreateUnfollowBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | CreateUnfollowBroadcastItemResultKeySpecifier -)[]; -export type CreateUnfollowBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type DataAvailabilityCommentKeySpecifier = ( - | 'appId' - | 'commentedOnProfile' - | 'commentedOnPublicationId' - | 'createdAt' - | 'profile' - | 'publicationId' - | 'submitter' - | 'transactionId' - | 'verificationStatus' - | DataAvailabilityCommentKeySpecifier -)[]; -export type DataAvailabilityCommentFieldPolicy = { - appId?: FieldPolicy | FieldReadFunction; - commentedOnProfile?: FieldPolicy | FieldReadFunction; - commentedOnPublicationId?: FieldPolicy | FieldReadFunction; - createdAt?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - publicationId?: FieldPolicy | FieldReadFunction; - submitter?: FieldPolicy | FieldReadFunction; - transactionId?: FieldPolicy | FieldReadFunction; - verificationStatus?: FieldPolicy | FieldReadFunction; -}; -export type DataAvailabilityMirrorKeySpecifier = ( - | 'appId' - | 'createdAt' - | 'mirrorOfProfile' - | 'mirrorOfPublicationId' - | 'profile' - | 'publicationId' - | 'submitter' - | 'transactionId' - | 'verificationStatus' - | DataAvailabilityMirrorKeySpecifier -)[]; -export type DataAvailabilityMirrorFieldPolicy = { - appId?: FieldPolicy | FieldReadFunction; - createdAt?: FieldPolicy | FieldReadFunction; - mirrorOfProfile?: FieldPolicy | FieldReadFunction; - mirrorOfPublicationId?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - publicationId?: FieldPolicy | FieldReadFunction; - submitter?: FieldPolicy | FieldReadFunction; - transactionId?: FieldPolicy | FieldReadFunction; - verificationStatus?: FieldPolicy | FieldReadFunction; -}; -export type DataAvailabilityPostKeySpecifier = ( - | 'appId' - | 'createdAt' - | 'profile' - | 'publicationId' - | 'submitter' - | 'transactionId' - | 'verificationStatus' - | DataAvailabilityPostKeySpecifier -)[]; -export type DataAvailabilityPostFieldPolicy = { - appId?: FieldPolicy | FieldReadFunction; - createdAt?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - publicationId?: FieldPolicy | FieldReadFunction; - submitter?: FieldPolicy | FieldReadFunction; - transactionId?: FieldPolicy | FieldReadFunction; - verificationStatus?: FieldPolicy | FieldReadFunction; -}; -export type DataAvailabilitySubmitterResultKeySpecifier = ( - | 'address' - | 'name' - | 'totalTransactions' - | DataAvailabilitySubmitterResultKeySpecifier -)[]; -export type DataAvailabilitySubmitterResultFieldPolicy = { - address?: FieldPolicy | FieldReadFunction; - name?: FieldPolicy | FieldReadFunction; - totalTransactions?: FieldPolicy | FieldReadFunction; -}; -export type DataAvailabilitySubmittersResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | DataAvailabilitySubmittersResultKeySpecifier -)[]; -export type DataAvailabilitySubmittersResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type DataAvailabilitySummaryResultKeySpecifier = ( - | 'totalTransactions' - | DataAvailabilitySummaryResultKeySpecifier -)[]; -export type DataAvailabilitySummaryResultFieldPolicy = { - totalTransactions?: FieldPolicy | FieldReadFunction; -}; -export type DataAvailabilityTransactionsResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | DataAvailabilityTransactionsResultKeySpecifier -)[]; -export type DataAvailabilityTransactionsResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type DataAvailabilityVerificationStatusFailureKeySpecifier = ( - | 'status' - | DataAvailabilityVerificationStatusFailureKeySpecifier -)[]; -export type DataAvailabilityVerificationStatusFailureFieldPolicy = { - status?: FieldPolicy | FieldReadFunction; -}; -export type DataAvailabilityVerificationStatusSuccessKeySpecifier = ( - | 'verified' - | DataAvailabilityVerificationStatusSuccessKeySpecifier -)[]; -export type DataAvailabilityVerificationStatusSuccessFieldPolicy = { - verified?: FieldPolicy | FieldReadFunction; -}; -export type DegreesOfSeparationReferenceModuleSettingsKeySpecifier = ( - | 'commentsRestricted' - | 'contractAddress' - | 'degreesOfSeparation' - | 'mirrorsRestricted' - | 'type' - | DegreesOfSeparationReferenceModuleSettingsKeySpecifier -)[]; -export type DegreesOfSeparationReferenceModuleSettingsFieldPolicy = { - commentsRestricted?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - degreesOfSeparation?: FieldPolicy | FieldReadFunction; - mirrorsRestricted?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type DispatcherKeySpecifier = ( - | 'address' - | 'canUseRelay' - | 'sponsor' - | DispatcherKeySpecifier -)[]; -export type DispatcherFieldPolicy = { - address?: FieldPolicy | FieldReadFunction; - canUseRelay?: FieldPolicy | FieldReadFunction; - sponsor?: FieldPolicy | FieldReadFunction; -}; -export type DoesFollowResponseKeySpecifier = ( - | 'followerAddress' - | 'follows' - | 'isFinalisedOnChain' - | 'profileId' - | DoesFollowResponseKeySpecifier -)[]; -export type DoesFollowResponseFieldPolicy = { - followerAddress?: FieldPolicy | FieldReadFunction; - follows?: FieldPolicy | FieldReadFunction; - isFinalisedOnChain?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; -}; -export type EIP712TypedDataDomainKeySpecifier = ( - | 'chainId' - | 'name' - | 'verifyingContract' - | 'version' - | EIP712TypedDataDomainKeySpecifier -)[]; -export type EIP712TypedDataDomainFieldPolicy = { - chainId?: FieldPolicy | FieldReadFunction; - name?: FieldPolicy | FieldReadFunction; - verifyingContract?: FieldPolicy | FieldReadFunction; - version?: FieldPolicy | FieldReadFunction; -}; -export type EIP712TypedDataFieldKeySpecifier = ( - | 'name' - | 'type' - | EIP712TypedDataFieldKeySpecifier -)[]; -export type EIP712TypedDataFieldFieldPolicy = { - name?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type ERC4626FeeCollectModuleSettingsKeySpecifier = ( - | 'amount' - | 'collectLimit' - | 'contractAddress' - | 'endTimestamp' - | 'followerOnly' - | 'recipient' - | 'referralFee' - | 'type' - | 'vault' - | ERC4626FeeCollectModuleSettingsKeySpecifier -)[]; -export type ERC4626FeeCollectModuleSettingsFieldPolicy = { - amount?: FieldPolicy | FieldReadFunction; - collectLimit?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - endTimestamp?: FieldPolicy | FieldReadFunction; - followerOnly?: FieldPolicy | FieldReadFunction; - recipient?: FieldPolicy | FieldReadFunction; - referralFee?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; - vault?: FieldPolicy | FieldReadFunction; -}; -export type ElectedMirrorKeySpecifier = ( - | 'mirrorId' - | 'profile' - | 'timestamp' - | ElectedMirrorKeySpecifier -)[]; -export type ElectedMirrorFieldPolicy = { - mirrorId?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - timestamp?: FieldPolicy | FieldReadFunction; -}; -export type EnabledModuleKeySpecifier = ( - | 'contractAddress' - | 'inputParams' - | 'moduleName' - | 'redeemParams' - | 'returnDataParms' - | EnabledModuleKeySpecifier -)[]; -export type EnabledModuleFieldPolicy = { - contractAddress?: FieldPolicy | FieldReadFunction; - inputParams?: FieldPolicy | FieldReadFunction; - moduleName?: FieldPolicy | FieldReadFunction; - redeemParams?: FieldPolicy | FieldReadFunction; - returnDataParms?: FieldPolicy | FieldReadFunction; -}; -export type EnabledModulesKeySpecifier = ( - | 'collectModules' - | 'followModules' - | 'referenceModules' - | EnabledModulesKeySpecifier -)[]; -export type EnabledModulesFieldPolicy = { - collectModules?: FieldPolicy | FieldReadFunction; - followModules?: FieldPolicy | FieldReadFunction; - referenceModules?: FieldPolicy | FieldReadFunction; -}; -export type EncryptedFieldsOutputKeySpecifier = ( - | 'animation_url' - | 'content' - | 'external_url' - | 'image' - | 'media' - | EncryptedFieldsOutputKeySpecifier -)[]; -export type EncryptedFieldsOutputFieldPolicy = { - animation_url?: FieldPolicy | FieldReadFunction; - content?: FieldPolicy | FieldReadFunction; - external_url?: FieldPolicy | FieldReadFunction; - image?: FieldPolicy | FieldReadFunction; - media?: FieldPolicy | FieldReadFunction; -}; -export type EncryptedMediaKeySpecifier = ( - | 'altTag' - | 'cover' - | 'height' - | 'mimeType' - | 'size' - | 'url' - | 'width' - | EncryptedMediaKeySpecifier -)[]; -export type EncryptedMediaFieldPolicy = { - altTag?: FieldPolicy | FieldReadFunction; - cover?: FieldPolicy | FieldReadFunction; - height?: FieldPolicy | FieldReadFunction; - mimeType?: FieldPolicy | FieldReadFunction; - size?: FieldPolicy | FieldReadFunction; - url?: FieldPolicy | FieldReadFunction; - width?: FieldPolicy | FieldReadFunction; -}; -export type EncryptedMediaSetKeySpecifier = ( - | 'medium' - | 'original' - | 'small' - | EncryptedMediaSetKeySpecifier -)[]; -export type EncryptedMediaSetFieldPolicy = { - medium?: FieldPolicy | FieldReadFunction; - original?: FieldPolicy | FieldReadFunction; - small?: FieldPolicy | FieldReadFunction; -}; -export type EncryptionParamsOutputKeySpecifier = ( - | 'accessCondition' - | 'encryptedFields' - | 'encryptionProvider' - | 'providerSpecificParams' - | EncryptionParamsOutputKeySpecifier -)[]; -export type EncryptionParamsOutputFieldPolicy = { - accessCondition?: FieldPolicy | FieldReadFunction; - encryptedFields?: FieldPolicy | FieldReadFunction; - encryptionProvider?: FieldPolicy | FieldReadFunction; - providerSpecificParams?: FieldPolicy | FieldReadFunction; -}; -export type EnsOnChainIdentityKeySpecifier = ('name' | EnsOnChainIdentityKeySpecifier)[]; -export type EnsOnChainIdentityFieldPolicy = { - name?: FieldPolicy | FieldReadFunction; -}; -export type EoaOwnershipOutputKeySpecifier = ('address' | EoaOwnershipOutputKeySpecifier)[]; -export type EoaOwnershipOutputFieldPolicy = { - address?: FieldPolicy | FieldReadFunction; -}; -export type Erc20KeySpecifier = ('address' | 'decimals' | 'name' | 'symbol' | Erc20KeySpecifier)[]; -export type Erc20FieldPolicy = { - address?: FieldPolicy | FieldReadFunction; - decimals?: FieldPolicy | FieldReadFunction; - name?: FieldPolicy | FieldReadFunction; - symbol?: FieldPolicy | FieldReadFunction; -}; -export type Erc20AmountKeySpecifier = ('asset' | 'value' | Erc20AmountKeySpecifier)[]; -export type Erc20AmountFieldPolicy = { - asset?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type Erc20OwnershipOutputKeySpecifier = ( - | 'amount' - | 'chainID' - | 'condition' - | 'contractAddress' - | 'decimals' - | 'name' - | 'symbol' - | Erc20OwnershipOutputKeySpecifier -)[]; -export type Erc20OwnershipOutputFieldPolicy = { - amount?: FieldPolicy | FieldReadFunction; - chainID?: FieldPolicy | FieldReadFunction; - condition?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - decimals?: FieldPolicy | FieldReadFunction; - name?: FieldPolicy | FieldReadFunction; - symbol?: FieldPolicy | FieldReadFunction; -}; -export type ExploreProfileResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | ExploreProfileResultKeySpecifier -)[]; -export type ExploreProfileResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type ExplorePublicationResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | ExplorePublicationResultKeySpecifier -)[]; -export type ExplorePublicationResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type FeeCollectModuleSettingsKeySpecifier = ( - | 'amount' - | 'contractAddress' - | 'followerOnly' - | 'recipient' - | 'referralFee' - | 'type' - | FeeCollectModuleSettingsKeySpecifier -)[]; -export type FeeCollectModuleSettingsFieldPolicy = { - amount?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - followerOnly?: FieldPolicy | FieldReadFunction; - recipient?: FieldPolicy | FieldReadFunction; - referralFee?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type FeeFollowModuleSettingsKeySpecifier = ( - | 'amount' - | 'contractAddress' - | 'recipient' - | 'type' - | FeeFollowModuleSettingsKeySpecifier -)[]; -export type FeeFollowModuleSettingsFieldPolicy = { - amount?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - recipient?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type FeedItemKeySpecifier = ( - | 'collects' - | 'comments' - | 'electedMirror' - | 'mirrors' - | 'reactions' - | 'root' - | FeedItemKeySpecifier -)[]; -export type FeedItemFieldPolicy = { - collects?: FieldPolicy | FieldReadFunction; - comments?: FieldPolicy | FieldReadFunction; - electedMirror?: FieldPolicy | FieldReadFunction; - mirrors?: FieldPolicy | FieldReadFunction; - reactions?: FieldPolicy | FieldReadFunction; - root?: FieldPolicy | FieldReadFunction; -}; -export type FollowConditionOutputKeySpecifier = ('profileId' | FollowConditionOutputKeySpecifier)[]; -export type FollowConditionOutputFieldPolicy = { - profileId?: FieldPolicy | FieldReadFunction; -}; -export type FollowOnlyReferenceModuleSettingsKeySpecifier = ( - | 'contractAddress' - | 'type' - | FollowOnlyReferenceModuleSettingsKeySpecifier -)[]; -export type FollowOnlyReferenceModuleSettingsFieldPolicy = { - contractAddress?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type FollowRevenueResultKeySpecifier = ('revenues' | FollowRevenueResultKeySpecifier)[]; -export type FollowRevenueResultFieldPolicy = { - revenues?: FieldPolicy | FieldReadFunction; -}; -export type FollowerKeySpecifier = ( - | 'totalAmountOfTimesFollowed' - | 'wallet' - | FollowerKeySpecifier -)[]; -export type FollowerFieldPolicy = { - totalAmountOfTimesFollowed?: FieldPolicy | FieldReadFunction; - wallet?: FieldPolicy | FieldReadFunction; -}; -export type FollowerNftOwnedTokenIdsKeySpecifier = ( - | 'followerNftAddress' - | 'tokensIds' - | FollowerNftOwnedTokenIdsKeySpecifier -)[]; -export type FollowerNftOwnedTokenIdsFieldPolicy = { - followerNftAddress?: FieldPolicy | FieldReadFunction; - tokensIds?: FieldPolicy | FieldReadFunction; -}; -export type FollowingKeySpecifier = ( - | 'profile' - | 'totalAmountOfTimesFollowing' - | FollowingKeySpecifier -)[]; -export type FollowingFieldPolicy = { - profile?: FieldPolicy | FieldReadFunction; - totalAmountOfTimesFollowing?: FieldPolicy | FieldReadFunction; -}; -export type FreeCollectModuleSettingsKeySpecifier = ( - | 'contractAddress' - | 'followerOnly' - | 'type' - | FreeCollectModuleSettingsKeySpecifier -)[]; -export type FreeCollectModuleSettingsFieldPolicy = { - contractAddress?: FieldPolicy | FieldReadFunction; - followerOnly?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type GenerateModuleCurrencyApprovalKeySpecifier = ( - | 'data' - | 'from' - | 'to' - | GenerateModuleCurrencyApprovalKeySpecifier -)[]; -export type GenerateModuleCurrencyApprovalFieldPolicy = { - data?: FieldPolicy | FieldReadFunction; - from?: FieldPolicy | FieldReadFunction; - to?: FieldPolicy | FieldReadFunction; -}; -export type GlobalProtocolStatsKeySpecifier = ( - | 'totalBurntProfiles' - | 'totalCollects' - | 'totalComments' - | 'totalFollows' - | 'totalMirrors' - | 'totalPosts' - | 'totalProfiles' - | 'totalRevenue' - | GlobalProtocolStatsKeySpecifier -)[]; -export type GlobalProtocolStatsFieldPolicy = { - totalBurntProfiles?: FieldPolicy | FieldReadFunction; - totalCollects?: FieldPolicy | FieldReadFunction; - totalComments?: FieldPolicy | FieldReadFunction; - totalFollows?: FieldPolicy | FieldReadFunction; - totalMirrors?: FieldPolicy | FieldReadFunction; - totalPosts?: FieldPolicy | FieldReadFunction; - totalProfiles?: FieldPolicy | FieldReadFunction; - totalRevenue?: FieldPolicy | FieldReadFunction; -}; -export type InternalPinResultKeySpecifier = ( - | 'ipfs' - | 'referenceItem' - | InternalPinResultKeySpecifier -)[]; -export type InternalPinResultFieldPolicy = { - ipfs?: FieldPolicy | FieldReadFunction; - referenceItem?: FieldPolicy | FieldReadFunction; -}; -export type InvitedResultKeySpecifier = ('address' | 'when' | InvitedResultKeySpecifier)[]; -export type InvitedResultFieldPolicy = { - address?: FieldPolicy | FieldReadFunction; - when?: FieldPolicy | FieldReadFunction; -}; -export type LimitedFeeCollectModuleSettingsKeySpecifier = ( - | 'amount' - | 'collectLimit' - | 'contractAddress' - | 'followerOnly' - | 'recipient' - | 'referralFee' - | 'type' - | LimitedFeeCollectModuleSettingsKeySpecifier -)[]; -export type LimitedFeeCollectModuleSettingsFieldPolicy = { - amount?: FieldPolicy | FieldReadFunction; - collectLimit?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - followerOnly?: FieldPolicy | FieldReadFunction; - recipient?: FieldPolicy | FieldReadFunction; - referralFee?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type LimitedTimedFeeCollectModuleSettingsKeySpecifier = ( - | 'amount' - | 'collectLimit' - | 'contractAddress' - | 'endTimestamp' - | 'followerOnly' - | 'recipient' - | 'referralFee' - | 'type' - | LimitedTimedFeeCollectModuleSettingsKeySpecifier -)[]; -export type LimitedTimedFeeCollectModuleSettingsFieldPolicy = { - amount?: FieldPolicy | FieldReadFunction; - collectLimit?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - endTimestamp?: FieldPolicy | FieldReadFunction; - followerOnly?: FieldPolicy | FieldReadFunction; - recipient?: FieldPolicy | FieldReadFunction; - referralFee?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type LogKeySpecifier = ( - | 'address' - | 'blockHash' - | 'blockNumber' - | 'data' - | 'logIndex' - | 'removed' - | 'topics' - | 'transactionHash' - | 'transactionIndex' - | LogKeySpecifier -)[]; -export type LogFieldPolicy = { - address?: FieldPolicy | FieldReadFunction; - blockHash?: FieldPolicy | FieldReadFunction; - blockNumber?: FieldPolicy | FieldReadFunction; - data?: FieldPolicy | FieldReadFunction; - logIndex?: FieldPolicy | FieldReadFunction; - removed?: FieldPolicy | FieldReadFunction; - topics?: FieldPolicy | FieldReadFunction; - transactionHash?: FieldPolicy | FieldReadFunction; - transactionIndex?: FieldPolicy | FieldReadFunction; -}; -export type MediaKeySpecifier = ( - | 'altTag' - | 'cover' - | 'height' - | 'mimeType' - | 'size' - | 'url' - | 'width' - | MediaKeySpecifier -)[]; -export type MediaFieldPolicy = { - altTag?: FieldPolicy | FieldReadFunction; - cover?: FieldPolicy | FieldReadFunction; - height?: FieldPolicy | FieldReadFunction; - mimeType?: FieldPolicy | FieldReadFunction; - size?: FieldPolicy | FieldReadFunction; - url?: FieldPolicy | FieldReadFunction; - width?: FieldPolicy | FieldReadFunction; -}; -export type MediaOutputKeySpecifier = ( - | 'altTag' - | 'cover' - | 'item' - | 'source' - | 'type' - | MediaOutputKeySpecifier -)[]; -export type MediaOutputFieldPolicy = { - altTag?: FieldPolicy | FieldReadFunction; - cover?: FieldPolicy | FieldReadFunction; - item?: FieldPolicy | FieldReadFunction; - source?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type MediaSetKeySpecifier = ( - | 'medium' - | 'onChain' - | 'optimized' - | 'original' - | 'small' - | 'transformed' - | MediaSetKeySpecifier -)[]; -export type MediaSetFieldPolicy = { - medium?: FieldPolicy | FieldReadFunction; - onChain?: FieldPolicy | FieldReadFunction; - optimized?: FieldPolicy | FieldReadFunction; - original?: FieldPolicy | FieldReadFunction; - small?: FieldPolicy | FieldReadFunction; - transformed?: FieldPolicy | FieldReadFunction; -}; -export type MetadataAttributeOutputKeySpecifier = ( - | 'displayType' - | 'traitType' - | 'value' - | MetadataAttributeOutputKeySpecifier -)[]; -export type MetadataAttributeOutputFieldPolicy = { - displayType?: FieldPolicy | FieldReadFunction; - traitType?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type MetadataOutputKeySpecifier = ( - | 'animatedUrl' - | 'attributes' - | 'content' - | 'contentWarning' - | 'cover' - | 'description' - | 'encryptionParams' - | 'image' - | 'locale' - | 'mainContentFocus' - | 'media' - | 'name' - | 'tags' - | MetadataOutputKeySpecifier -)[]; -export type MetadataOutputFieldPolicy = { - animatedUrl?: FieldPolicy | FieldReadFunction; - attributes?: FieldPolicy | FieldReadFunction; - content?: FieldPolicy | FieldReadFunction; - contentWarning?: FieldPolicy | FieldReadFunction; - cover?: FieldPolicy | FieldReadFunction; - description?: FieldPolicy | FieldReadFunction; - encryptionParams?: FieldPolicy | FieldReadFunction; - image?: FieldPolicy | FieldReadFunction; - locale?: FieldPolicy | FieldReadFunction; - mainContentFocus?: FieldPolicy | FieldReadFunction; - media?: FieldPolicy | FieldReadFunction; - name?: FieldPolicy | FieldReadFunction; - tags?: FieldPolicy | FieldReadFunction; -}; -export type MirrorKeySpecifier = ( - | 'appId' - | 'bookmarked' - | 'canComment' - | 'canDecrypt' - | 'canMirror' - | 'collectModule' - | 'collectNftAddress' - | 'createdAt' - | 'dataAvailabilityProofs' - | 'hasCollectedByMe' - | 'hidden' - | 'id' - | 'isDataAvailability' - | 'isGated' - | 'metadata' - | 'mirrorOf' - | 'notInterested' - | 'onChainContentURI' - | 'profile' - | 'reaction' - | 'referenceModule' - | 'stats' - | MirrorKeySpecifier -)[]; -export type MirrorFieldPolicy = { - appId?: FieldPolicy | FieldReadFunction; - bookmarked?: FieldPolicy | FieldReadFunction; - canComment?: FieldPolicy | FieldReadFunction; - canDecrypt?: FieldPolicy | FieldReadFunction; - canMirror?: FieldPolicy | FieldReadFunction; - collectModule?: FieldPolicy | FieldReadFunction; - collectNftAddress?: FieldPolicy | FieldReadFunction; - createdAt?: FieldPolicy | FieldReadFunction; - dataAvailabilityProofs?: FieldPolicy | FieldReadFunction; - hasCollectedByMe?: FieldPolicy | FieldReadFunction; - hidden?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - isDataAvailability?: FieldPolicy | FieldReadFunction; - isGated?: FieldPolicy | FieldReadFunction; - metadata?: FieldPolicy | FieldReadFunction; - mirrorOf?: FieldPolicy | FieldReadFunction; - notInterested?: FieldPolicy | FieldReadFunction; - onChainContentURI?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - reaction?: FieldPolicy | FieldReadFunction; - referenceModule?: FieldPolicy | FieldReadFunction; - stats?: FieldPolicy | FieldReadFunction; -}; -export type MirrorEventKeySpecifier = ('profile' | 'timestamp' | MirrorEventKeySpecifier)[]; -export type MirrorEventFieldPolicy = { - profile?: FieldPolicy | FieldReadFunction; - timestamp?: FieldPolicy | FieldReadFunction; -}; -export type ModuleFeeKeySpecifier = ( - | 'amount' - | 'recipient' - | 'referralFee' - | ModuleFeeKeySpecifier -)[]; -export type ModuleFeeFieldPolicy = { - amount?: FieldPolicy | FieldReadFunction; - recipient?: FieldPolicy | FieldReadFunction; - referralFee?: FieldPolicy | FieldReadFunction; -}; -export type ModuleFeeAmountKeySpecifier = ('asset' | 'value' | ModuleFeeAmountKeySpecifier)[]; -export type ModuleFeeAmountFieldPolicy = { - asset?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type ModuleInfoKeySpecifier = ('name' | 'type' | ModuleInfoKeySpecifier)[]; -export type ModuleInfoFieldPolicy = { - name?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type MultirecipientFeeCollectModuleSettingsKeySpecifier = ( - | 'amount' - | 'collectLimit' - | 'contractAddress' - | 'endTimestamp' - | 'followerOnly' - | 'recipients' - | 'referralFee' - | 'type' - | MultirecipientFeeCollectModuleSettingsKeySpecifier -)[]; -export type MultirecipientFeeCollectModuleSettingsFieldPolicy = { - amount?: FieldPolicy | FieldReadFunction; - collectLimit?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - endTimestamp?: FieldPolicy | FieldReadFunction; - followerOnly?: FieldPolicy | FieldReadFunction; - recipients?: FieldPolicy | FieldReadFunction; - referralFee?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type MutationKeySpecifier = ( - | 'ach' - | 'addProfileInterests' - | 'addPublicationProfileBookmark' - | 'addPublicationProfileNotInterested' - | 'addReaction' - | 'authenticate' - | 'broadcast' - | 'broadcastDataAvailability' - | 'claim' - | 'createAttachMediaData' - | 'createBurnProfileTypedData' - | 'createCollectTypedData' - | 'createCommentTypedData' - | 'createCommentViaDispatcher' - | 'createDataAvailabilityCommentTypedData' - | 'createDataAvailabilityCommentViaDispatcher' - | 'createDataAvailabilityMirrorTypedData' - | 'createDataAvailabilityMirrorViaDispatcher' - | 'createDataAvailabilityPostTypedData' - | 'createDataAvailabilityPostViaDispatcher' - | 'createFollowTypedData' - | 'createMirrorTypedData' - | 'createMirrorViaDispatcher' - | 'createNftGallery' - | 'createPostTypedData' - | 'createPostViaDispatcher' - | 'createProfile' - | 'createSetDefaultProfileTypedData' - | 'createSetDispatcherTypedData' - | 'createSetFollowModuleTypedData' - | 'createSetFollowNFTUriTypedData' - | 'createSetFollowNFTUriViaDispatcher' - | 'createSetProfileImageURITypedData' - | 'createSetProfileImageURIViaDispatcher' - | 'createSetProfileMetadataTypedData' - | 'createSetProfileMetadataViaDispatcher' - | 'createToggleFollowTypedData' - | 'createUnfollowTypedData' - | 'deleteNftGallery' - | 'dismissRecommendedProfiles' - | 'dss' - | 'gci' - | 'gcr' - | 'gdi' - | 'hel' - | 'hidePublication' - | 'idKitPhoneVerifyWebhook' - | 'in' - | 'invite' - | 'nni' - | 'nnv' - | 'proxyAction' - | 'refresh' - | 'removeProfileInterests' - | 'removePublicationProfileBookmark' - | 'removePublicationProfileNotInterested' - | 'removeReaction' - | 'reportPublication' - | 'updateNftGalleryInfo' - | 'updateNftGalleryItems' - | 'updateNftGalleryOrder' - | MutationKeySpecifier -)[]; -export type MutationFieldPolicy = { - ach?: FieldPolicy | FieldReadFunction; - addProfileInterests?: FieldPolicy | FieldReadFunction; - addPublicationProfileBookmark?: FieldPolicy | FieldReadFunction; - addPublicationProfileNotInterested?: FieldPolicy | FieldReadFunction; - addReaction?: FieldPolicy | FieldReadFunction; - authenticate?: FieldPolicy | FieldReadFunction; - broadcast?: FieldPolicy | FieldReadFunction; - broadcastDataAvailability?: FieldPolicy | FieldReadFunction; - claim?: FieldPolicy | FieldReadFunction; - createAttachMediaData?: FieldPolicy | FieldReadFunction; - createBurnProfileTypedData?: FieldPolicy | FieldReadFunction; - createCollectTypedData?: FieldPolicy | FieldReadFunction; - createCommentTypedData?: FieldPolicy | FieldReadFunction; - createCommentViaDispatcher?: FieldPolicy | FieldReadFunction; - createDataAvailabilityCommentTypedData?: FieldPolicy | FieldReadFunction; - createDataAvailabilityCommentViaDispatcher?: FieldPolicy | FieldReadFunction; - createDataAvailabilityMirrorTypedData?: FieldPolicy | FieldReadFunction; - createDataAvailabilityMirrorViaDispatcher?: FieldPolicy | FieldReadFunction; - createDataAvailabilityPostTypedData?: FieldPolicy | FieldReadFunction; - createDataAvailabilityPostViaDispatcher?: FieldPolicy | FieldReadFunction; - createFollowTypedData?: FieldPolicy | FieldReadFunction; - createMirrorTypedData?: FieldPolicy | FieldReadFunction; - createMirrorViaDispatcher?: FieldPolicy | FieldReadFunction; - createNftGallery?: FieldPolicy | FieldReadFunction; - createPostTypedData?: FieldPolicy | FieldReadFunction; - createPostViaDispatcher?: FieldPolicy | FieldReadFunction; - createProfile?: FieldPolicy | FieldReadFunction; - createSetDefaultProfileTypedData?: FieldPolicy | FieldReadFunction; - createSetDispatcherTypedData?: FieldPolicy | FieldReadFunction; - createSetFollowModuleTypedData?: FieldPolicy | FieldReadFunction; - createSetFollowNFTUriTypedData?: FieldPolicy | FieldReadFunction; - createSetFollowNFTUriViaDispatcher?: FieldPolicy | FieldReadFunction; - createSetProfileImageURITypedData?: FieldPolicy | FieldReadFunction; - createSetProfileImageURIViaDispatcher?: FieldPolicy | FieldReadFunction; - createSetProfileMetadataTypedData?: FieldPolicy | FieldReadFunction; - createSetProfileMetadataViaDispatcher?: FieldPolicy | FieldReadFunction; - createToggleFollowTypedData?: FieldPolicy | FieldReadFunction; - createUnfollowTypedData?: FieldPolicy | FieldReadFunction; - deleteNftGallery?: FieldPolicy | FieldReadFunction; - dismissRecommendedProfiles?: FieldPolicy | FieldReadFunction; - dss?: FieldPolicy | FieldReadFunction; - gci?: FieldPolicy | FieldReadFunction; - gcr?: FieldPolicy | FieldReadFunction; - gdi?: FieldPolicy | FieldReadFunction; - hel?: FieldPolicy | FieldReadFunction; - hidePublication?: FieldPolicy | FieldReadFunction; - idKitPhoneVerifyWebhook?: FieldPolicy | FieldReadFunction; - in?: FieldPolicy | FieldReadFunction; - invite?: FieldPolicy | FieldReadFunction; - nni?: FieldPolicy | FieldReadFunction; - nnv?: FieldPolicy | FieldReadFunction; - proxyAction?: FieldPolicy | FieldReadFunction; - refresh?: FieldPolicy | FieldReadFunction; - removeProfileInterests?: FieldPolicy | FieldReadFunction; - removePublicationProfileBookmark?: FieldPolicy | FieldReadFunction; - removePublicationProfileNotInterested?: FieldPolicy | FieldReadFunction; - removeReaction?: FieldPolicy | FieldReadFunction; - reportPublication?: FieldPolicy | FieldReadFunction; - updateNftGalleryInfo?: FieldPolicy | FieldReadFunction; - updateNftGalleryItems?: FieldPolicy | FieldReadFunction; - updateNftGalleryOrder?: FieldPolicy | FieldReadFunction; -}; -export type NFTKeySpecifier = ( - | 'chainId' - | 'collectionName' - | 'contentURI' - | 'contractAddress' - | 'contractName' - | 'description' - | 'ercType' - | 'name' - | 'originalContent' - | 'owners' - | 'symbol' - | 'tokenId' - | NFTKeySpecifier -)[]; -export type NFTFieldPolicy = { - chainId?: FieldPolicy | FieldReadFunction; - collectionName?: FieldPolicy | FieldReadFunction; - contentURI?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - contractName?: FieldPolicy | FieldReadFunction; - description?: FieldPolicy | FieldReadFunction; - ercType?: FieldPolicy | FieldReadFunction; - name?: FieldPolicy | FieldReadFunction; - originalContent?: FieldPolicy | FieldReadFunction; - owners?: FieldPolicy | FieldReadFunction; - symbol?: FieldPolicy | FieldReadFunction; - tokenId?: FieldPolicy | FieldReadFunction; -}; -export type NFTContentKeySpecifier = ( - | 'animatedUrl' - | 'metaType' - | 'uri' - | NFTContentKeySpecifier -)[]; -export type NFTContentFieldPolicy = { - animatedUrl?: FieldPolicy | FieldReadFunction; - metaType?: FieldPolicy | FieldReadFunction; - uri?: FieldPolicy | FieldReadFunction; -}; -export type NFTsResultKeySpecifier = ('items' | 'pageInfo' | NFTsResultKeySpecifier)[]; -export type NFTsResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type NewCollectNotificationKeySpecifier = ( - | 'collectedPublication' - | 'createdAt' - | 'notificationId' - | 'wallet' - | NewCollectNotificationKeySpecifier -)[]; -export type NewCollectNotificationFieldPolicy = { - collectedPublication?: FieldPolicy | FieldReadFunction; - createdAt?: FieldPolicy | FieldReadFunction; - notificationId?: FieldPolicy | FieldReadFunction; - wallet?: FieldPolicy | FieldReadFunction; -}; -export type NewCommentNotificationKeySpecifier = ( - | 'comment' - | 'createdAt' - | 'notificationId' - | 'profile' - | NewCommentNotificationKeySpecifier -)[]; -export type NewCommentNotificationFieldPolicy = { - comment?: FieldPolicy | FieldReadFunction; - createdAt?: FieldPolicy | FieldReadFunction; - notificationId?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; -}; -export type NewFollowerNotificationKeySpecifier = ( - | 'createdAt' - | 'isFollowedByMe' - | 'notificationId' - | 'wallet' - | NewFollowerNotificationKeySpecifier -)[]; -export type NewFollowerNotificationFieldPolicy = { - createdAt?: FieldPolicy | FieldReadFunction; - isFollowedByMe?: FieldPolicy | FieldReadFunction; - notificationId?: FieldPolicy | FieldReadFunction; - wallet?: FieldPolicy | FieldReadFunction; -}; -export type NewMentionNotificationKeySpecifier = ( - | 'createdAt' - | 'mentionPublication' - | 'notificationId' - | NewMentionNotificationKeySpecifier -)[]; -export type NewMentionNotificationFieldPolicy = { - createdAt?: FieldPolicy | FieldReadFunction; - mentionPublication?: FieldPolicy | FieldReadFunction; - notificationId?: FieldPolicy | FieldReadFunction; -}; -export type NewMirrorNotificationKeySpecifier = ( - | 'createdAt' - | 'notificationId' - | 'profile' - | 'publication' - | NewMirrorNotificationKeySpecifier -)[]; -export type NewMirrorNotificationFieldPolicy = { - createdAt?: FieldPolicy | FieldReadFunction; - notificationId?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - publication?: FieldPolicy | FieldReadFunction; -}; -export type NewReactionNotificationKeySpecifier = ( - | 'createdAt' - | 'notificationId' - | 'profile' - | 'publication' - | 'reaction' - | NewReactionNotificationKeySpecifier -)[]; -export type NewReactionNotificationFieldPolicy = { - createdAt?: FieldPolicy | FieldReadFunction; - notificationId?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - publication?: FieldPolicy | FieldReadFunction; - reaction?: FieldPolicy | FieldReadFunction; -}; -export type NftGalleryKeySpecifier = ( - | 'createdAt' - | 'id' - | 'items' - | 'name' - | 'profileId' - | 'updatedAt' - | NftGalleryKeySpecifier -)[]; -export type NftGalleryFieldPolicy = { - createdAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - items?: FieldPolicy | FieldReadFunction; - name?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; - updatedAt?: FieldPolicy | FieldReadFunction; -}; -export type NftImageKeySpecifier = ( - | 'chainId' - | 'contractAddress' - | 'tokenId' - | 'uri' - | 'verified' - | NftImageKeySpecifier -)[]; -export type NftImageFieldPolicy = { - chainId?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - tokenId?: FieldPolicy | FieldReadFunction; - uri?: FieldPolicy | FieldReadFunction; - verified?: FieldPolicy | FieldReadFunction; -}; -export type NftOwnershipChallengeResultKeySpecifier = ( - | 'id' - | 'text' - | 'timeout' - | NftOwnershipChallengeResultKeySpecifier -)[]; -export type NftOwnershipChallengeResultFieldPolicy = { - id?: FieldPolicy | FieldReadFunction; - text?: FieldPolicy | FieldReadFunction; - timeout?: FieldPolicy | FieldReadFunction; -}; -export type NftOwnershipOutputKeySpecifier = ( - | 'chainID' - | 'contractAddress' - | 'contractType' - | 'tokenIds' - | NftOwnershipOutputKeySpecifier -)[]; -export type NftOwnershipOutputFieldPolicy = { - chainID?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - contractType?: FieldPolicy | FieldReadFunction; - tokenIds?: FieldPolicy | FieldReadFunction; -}; -export type OnChainIdentityKeySpecifier = ( - | 'ens' - | 'proofOfHumanity' - | 'sybilDotOrg' - | 'worldcoin' - | OnChainIdentityKeySpecifier -)[]; -export type OnChainIdentityFieldPolicy = { - ens?: FieldPolicy | FieldReadFunction; - proofOfHumanity?: FieldPolicy | FieldReadFunction; - sybilDotOrg?: FieldPolicy | FieldReadFunction; - worldcoin?: FieldPolicy | FieldReadFunction; -}; -export type OrConditionOutputKeySpecifier = ('criteria' | OrConditionOutputKeySpecifier)[]; -export type OrConditionOutputFieldPolicy = { - criteria?: FieldPolicy | FieldReadFunction; -}; -export type OwnerKeySpecifier = ('address' | 'amount' | OwnerKeySpecifier)[]; -export type OwnerFieldPolicy = { - address?: FieldPolicy | FieldReadFunction; - amount?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedAllPublicationsTagsResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedAllPublicationsTagsResultKeySpecifier -)[]; -export type PaginatedAllPublicationsTagsResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedFeedResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedFeedResultKeySpecifier -)[]; -export type PaginatedFeedResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedFollowersResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedFollowersResultKeySpecifier -)[]; -export type PaginatedFollowersResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedFollowingResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedFollowingResultKeySpecifier -)[]; -export type PaginatedFollowingResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedForYouResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedForYouResultKeySpecifier -)[]; -export type PaginatedForYouResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedNotificationResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedNotificationResultKeySpecifier -)[]; -export type PaginatedNotificationResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedProfilePublicationsForSaleResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedProfilePublicationsForSaleResultKeySpecifier -)[]; -export type PaginatedProfilePublicationsForSaleResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedProfileResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedProfileResultKeySpecifier -)[]; -export type PaginatedProfileResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedPublicationResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedPublicationResultKeySpecifier -)[]; -export type PaginatedPublicationResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedResultInfoKeySpecifier = ( - | 'moreAfter' - | 'next' - | 'prev' - | 'totalCount' - | PaginatedResultInfoKeySpecifier -)[]; -export type PaginatedResultInfoFieldPolicy = { - moreAfter?: FieldPolicy | FieldReadFunction; - next?: FieldPolicy | FieldReadFunction; - prev?: FieldPolicy | FieldReadFunction; - totalCount?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedTimelineResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedTimelineResultKeySpecifier -)[]; -export type PaginatedTimelineResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedWhoCollectedResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedWhoCollectedResultKeySpecifier -)[]; -export type PaginatedWhoCollectedResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PaginatedWhoReactedResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PaginatedWhoReactedResultKeySpecifier -)[]; -export type PaginatedWhoReactedResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PendingApproveFollowsResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | PendingApproveFollowsResultKeySpecifier -)[]; -export type PendingApproveFollowsResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type PendingPostKeySpecifier = ( - | 'content' - | 'id' - | 'locale' - | 'mainContentFocus' - | 'media' - | 'profile' - | PendingPostKeySpecifier -)[]; -export type PendingPostFieldPolicy = { - content?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - locale?: FieldPolicy | FieldReadFunction; - mainContentFocus?: FieldPolicy | FieldReadFunction; - media?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; -}; -export type PostKeySpecifier = ( - | 'appId' - | 'bookmarked' - | 'canComment' - | 'canDecrypt' - | 'canMirror' - | 'collectModule' - | 'collectNftAddress' - | 'collectPolicy' - | 'collectedBy' - | 'contentInsight' - | 'createdAt' - | 'dataAvailabilityProofs' - | 'decryptionCriteria' - | 'hasCollectedByMe' - | 'hasOptimisticCollectedByMe' - | 'hidden' - | 'id' - | 'isDataAvailability' - | 'isGated' - | 'isMirroredByMe' - | 'isOptimisticMirroredByMe' - | 'metadata' - | 'mirrors' - | 'notInterested' - | 'observedBy' - | 'onChainContentURI' - | 'profile' - | 'reaction' - | 'referenceModule' - | 'referencePolicy' - | 'stats' - | PostKeySpecifier -)[]; -export type PostFieldPolicy = { - appId?: FieldPolicy | FieldReadFunction; - bookmarked?: FieldPolicy | FieldReadFunction; - canComment?: FieldPolicy | FieldReadFunction; - canDecrypt?: FieldPolicy | FieldReadFunction; - canMirror?: FieldPolicy | FieldReadFunction; - collectModule?: FieldPolicy | FieldReadFunction; - collectNftAddress?: FieldPolicy | FieldReadFunction; - collectPolicy?: FieldPolicy | FieldReadFunction; - collectedBy?: FieldPolicy | FieldReadFunction; - contentInsight?: FieldPolicy | FieldReadFunction; - createdAt?: FieldPolicy | FieldReadFunction; - dataAvailabilityProofs?: FieldPolicy | FieldReadFunction; - decryptionCriteria?: FieldPolicy | FieldReadFunction; - hasCollectedByMe?: FieldPolicy | FieldReadFunction; - hasOptimisticCollectedByMe?: FieldPolicy | FieldReadFunction; - hidden?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - isDataAvailability?: FieldPolicy | FieldReadFunction; - isGated?: FieldPolicy | FieldReadFunction; - isMirroredByMe?: FieldPolicy | FieldReadFunction; - isOptimisticMirroredByMe?: FieldPolicy | FieldReadFunction; - metadata?: FieldPolicy | FieldReadFunction; - mirrors?: FieldPolicy | FieldReadFunction; - notInterested?: FieldPolicy | FieldReadFunction; - observedBy?: FieldPolicy | FieldReadFunction; - onChainContentURI?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - reaction?: FieldPolicy | FieldReadFunction; - referenceModule?: FieldPolicy | FieldReadFunction; - referencePolicy?: FieldPolicy | FieldReadFunction; - stats?: FieldPolicy | FieldReadFunction; -}; -export type PrfResponseKeySpecifier = ('dd' | 'ss' | PrfResponseKeySpecifier)[]; -export type PrfResponseFieldPolicy = { - dd?: FieldPolicy | FieldReadFunction; - ss?: FieldPolicy | FieldReadFunction; -}; -export type ProfileKeySpecifier = ( - | 'attributes' - | 'attributesMap' - | 'bio' - | 'coverPicture' - | 'dispatcher' - | 'followModule' - | 'followNftAddress' - | 'followPolicy' - | 'followStatus' - | 'handle' - | 'id' - | 'interests' - | 'invitedBy' - | 'isDefault' - | 'isFollowedByMe' - | 'isFollowing' - | 'metadata' - | 'name' - | 'observedBy' - | 'onChainIdentity' - | 'ownedBy' - | 'ownedByMe' - | 'picture' - | 'stats' - | ProfileKeySpecifier -)[]; -export type ProfileFieldPolicy = { - attributes?: FieldPolicy | FieldReadFunction; - attributesMap?: FieldPolicy | FieldReadFunction; - bio?: FieldPolicy | FieldReadFunction; - coverPicture?: FieldPolicy | FieldReadFunction; - dispatcher?: FieldPolicy | FieldReadFunction; - followModule?: FieldPolicy | FieldReadFunction; - followNftAddress?: FieldPolicy | FieldReadFunction; - followPolicy?: FieldPolicy | FieldReadFunction; - followStatus?: FieldPolicy | FieldReadFunction; - handle?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - interests?: FieldPolicy | FieldReadFunction; - invitedBy?: FieldPolicy | FieldReadFunction; - isDefault?: FieldPolicy | FieldReadFunction; - isFollowedByMe?: FieldPolicy | FieldReadFunction; - isFollowing?: FieldPolicy | FieldReadFunction; - metadata?: FieldPolicy | FieldReadFunction; - name?: FieldPolicy | FieldReadFunction; - observedBy?: FieldPolicy | FieldReadFunction; - onChainIdentity?: FieldPolicy | FieldReadFunction; - ownedBy?: FieldPolicy | FieldReadFunction; - ownedByMe?: FieldPolicy | FieldReadFunction; - picture?: FieldPolicy | FieldReadFunction; - stats?: FieldPolicy | FieldReadFunction; -}; -export type ProfileFollowModuleSettingsKeySpecifier = ( - | 'contractAddress' - | 'type' - | ProfileFollowModuleSettingsKeySpecifier -)[]; -export type ProfileFollowModuleSettingsFieldPolicy = { - contractAddress?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type ProfileGuardianResultKeySpecifier = ( - | 'disablingProtectionTimestamp' - | 'protected' - | ProfileGuardianResultKeySpecifier -)[]; -export type ProfileGuardianResultFieldPolicy = { - disablingProtectionTimestamp?: FieldPolicy | FieldReadFunction; - protected?: FieldPolicy | FieldReadFunction; -}; -export type ProfileOwnershipOutputKeySpecifier = ( - | 'profileId' - | ProfileOwnershipOutputKeySpecifier -)[]; -export type ProfileOwnershipOutputFieldPolicy = { - profileId?: FieldPolicy | FieldReadFunction; -}; -export type ProfilePublicationRevenueResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | ProfilePublicationRevenueResultKeySpecifier -)[]; -export type ProfilePublicationRevenueResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; -}; -export type ProfileSearchResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | 'type' - | ProfileSearchResultKeySpecifier -)[]; -export type ProfileSearchResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type ProfileStatsKeySpecifier = ( - | 'commentsTotal' - | 'id' - | 'mirrorsTotal' - | 'postsTotal' - | 'publicationsTotal' - | 'totalCollects' - | 'totalComments' - | 'totalFollowers' - | 'totalFollowing' - | 'totalMirrors' - | 'totalPosts' - | 'totalPublications' - | ProfileStatsKeySpecifier -)[]; -export type ProfileStatsFieldPolicy = { - commentsTotal?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - mirrorsTotal?: FieldPolicy | FieldReadFunction; - postsTotal?: FieldPolicy | FieldReadFunction; - publicationsTotal?: FieldPolicy | FieldReadFunction; - totalCollects?: FieldPolicy | FieldReadFunction; - totalComments?: FieldPolicy | FieldReadFunction; - totalFollowers?: FieldPolicy | FieldReadFunction; - totalFollowing?: FieldPolicy | FieldReadFunction; - totalMirrors?: FieldPolicy | FieldReadFunction; - totalPosts?: FieldPolicy | FieldReadFunction; - totalPublications?: FieldPolicy | FieldReadFunction; -}; -export type ProviderSpecificParamsOutputKeySpecifier = ( - | 'encryptionKey' - | ProviderSpecificParamsOutputKeySpecifier -)[]; -export type ProviderSpecificParamsOutputFieldPolicy = { - encryptionKey?: FieldPolicy | FieldReadFunction; -}; -export type ProxyActionErrorKeySpecifier = ( - | 'lastKnownTxId' - | 'reason' - | ProxyActionErrorKeySpecifier -)[]; -export type ProxyActionErrorFieldPolicy = { - lastKnownTxId?: FieldPolicy | FieldReadFunction; - reason?: FieldPolicy | FieldReadFunction; -}; -export type ProxyActionQueuedKeySpecifier = ('queuedAt' | ProxyActionQueuedKeySpecifier)[]; -export type ProxyActionQueuedFieldPolicy = { - queuedAt?: FieldPolicy | FieldReadFunction; -}; -export type ProxyActionStatusResultKeySpecifier = ( - | 'status' - | 'txHash' - | 'txId' - | ProxyActionStatusResultKeySpecifier -)[]; -export type ProxyActionStatusResultFieldPolicy = { - status?: FieldPolicy | FieldReadFunction; - txHash?: FieldPolicy | FieldReadFunction; - txId?: FieldPolicy | FieldReadFunction; -}; -export type PublicMediaResultsKeySpecifier = ( - | 'media' - | 'signedUrl' - | PublicMediaResultsKeySpecifier -)[]; -export type PublicMediaResultsFieldPolicy = { - media?: FieldPolicy | FieldReadFunction; - signedUrl?: FieldPolicy | FieldReadFunction; -}; -export type PublicationMetadataStatusKeySpecifier = ( - | 'reason' - | 'status' - | PublicationMetadataStatusKeySpecifier -)[]; -export type PublicationMetadataStatusFieldPolicy = { - reason?: FieldPolicy | FieldReadFunction; - status?: FieldPolicy | FieldReadFunction; -}; -export type PublicationRevenueKeySpecifier = ( - | 'publication' - | 'revenue' - | PublicationRevenueKeySpecifier -)[]; -export type PublicationRevenueFieldPolicy = { - publication?: FieldPolicy | FieldReadFunction; - revenue?: FieldPolicy | FieldReadFunction; -}; -export type PublicationSearchResultKeySpecifier = ( - | 'items' - | 'pageInfo' - | 'type' - | PublicationSearchResultKeySpecifier -)[]; -export type PublicationSearchResultFieldPolicy = { - items?: FieldPolicy | FieldReadFunction; - pageInfo?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type PublicationStatsKeySpecifier = ( - | 'commentsTotal' - | 'id' - | 'totalAmountOfCollects' - | 'totalAmountOfComments' - | 'totalAmountOfMirrors' - | 'totalBookmarks' - | 'totalDownvotes' - | 'totalUpvotes' - | PublicationStatsKeySpecifier -)[]; -export type PublicationStatsFieldPolicy = { - commentsTotal?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - totalAmountOfCollects?: FieldPolicy | FieldReadFunction; - totalAmountOfComments?: FieldPolicy | FieldReadFunction; - totalAmountOfMirrors?: FieldPolicy | FieldReadFunction; - totalBookmarks?: FieldPolicy | FieldReadFunction; - totalDownvotes?: FieldPolicy | FieldReadFunction; - totalUpvotes?: FieldPolicy | FieldReadFunction; -}; -export type PublicationValidateMetadataResultKeySpecifier = ( - | 'reason' - | 'valid' - | PublicationValidateMetadataResultKeySpecifier -)[]; -export type PublicationValidateMetadataResultFieldPolicy = { - reason?: FieldPolicy | FieldReadFunction; - valid?: FieldPolicy | FieldReadFunction; -}; -export type QueryKeySpecifier = ( - | 'allPublicationsTags' - | 'alreadyInvited' - | 'approvedModuleAllowanceAmount' - | 'challenge' - | 'claimableHandles' - | 'claimableStatus' - | 'cur' - | 'dataAvailabilitySubmitters' - | 'dataAvailabilitySummary' - | 'dataAvailabilityTransaction' - | 'dataAvailabilityTransactions' - | 'defaultProfile' - | 'doesFollow' - | 'enabledModuleCurrencies' - | 'enabledModules' - | 'exploreProfiles' - | 'explorePublications' - | 'feed' - | 'feedHighlights' - | 'followerNftOwnedTokenIds' - | 'followers' - | 'following' - | 'forYou' - | 'gct' - | 'gdm' - | 'generateModuleCurrencyApprovalData' - | 'globalProtocolStats' - | 'hasTxHashBeenIndexed' - | 'internalPin' - | 'intotal' - | 'invited' - | 'invitesLeft' - | 'isIDKitPhoneVerified' - | 'iss' - | 'mutualFollowersProfiles' - | 'nftGalleries' - | 'nftOwnershipChallenge' - | 'nfts' - | 'notifications' - | 'pendingApprovalFollows' - | 'ping' - | 'profile' - | 'profileFollowModuleBeenRedeemed' - | 'profileFollowRevenue' - | 'profileGuardianInformation' - | 'profileInterests' - | 'profileOnChainIdentity' - | 'profilePublicationRevenue' - | 'profilePublicationsForSale' - | 'profiles' - | 'proxyActionStatus' - | 'publication' - | 'publicationMetadataStatus' - | 'publicationRevenue' - | 'publications' - | 'publicationsProfileBookmarks' - | 'recommendedProfiles' - | 'rel' - | 'relayQueues' - | 'search' - | 'searchNfts' - | 'txIdToTxHash' - | 'unknownEnabledModules' - | 'userSigNonces' - | 'validatePublicationMetadata' - | 'verify' - | 'whoCollectedPublication' - | 'whoReactedPublication' - | QueryKeySpecifier -)[]; -export type QueryFieldPolicy = { - allPublicationsTags?: FieldPolicy | FieldReadFunction; - alreadyInvited?: FieldPolicy | FieldReadFunction; - approvedModuleAllowanceAmount?: FieldPolicy | FieldReadFunction; - challenge?: FieldPolicy | FieldReadFunction; - claimableHandles?: FieldPolicy | FieldReadFunction; - claimableStatus?: FieldPolicy | FieldReadFunction; - cur?: FieldPolicy | FieldReadFunction; - dataAvailabilitySubmitters?: FieldPolicy | FieldReadFunction; - dataAvailabilitySummary?: FieldPolicy | FieldReadFunction; - dataAvailabilityTransaction?: FieldPolicy | FieldReadFunction; - dataAvailabilityTransactions?: FieldPolicy | FieldReadFunction; - defaultProfile?: FieldPolicy | FieldReadFunction; - doesFollow?: FieldPolicy | FieldReadFunction; - enabledModuleCurrencies?: FieldPolicy | FieldReadFunction; - enabledModules?: FieldPolicy | FieldReadFunction; - exploreProfiles?: FieldPolicy | FieldReadFunction; - explorePublications?: FieldPolicy | FieldReadFunction; - feed?: FieldPolicy | FieldReadFunction; - feedHighlights?: FieldPolicy | FieldReadFunction; - followerNftOwnedTokenIds?: FieldPolicy | FieldReadFunction; - followers?: FieldPolicy | FieldReadFunction; - following?: FieldPolicy | FieldReadFunction; - forYou?: FieldPolicy | FieldReadFunction; - gct?: FieldPolicy | FieldReadFunction; - gdm?: FieldPolicy | FieldReadFunction; - generateModuleCurrencyApprovalData?: FieldPolicy | FieldReadFunction; - globalProtocolStats?: FieldPolicy | FieldReadFunction; - hasTxHashBeenIndexed?: FieldPolicy | FieldReadFunction; - internalPin?: FieldPolicy | FieldReadFunction; - intotal?: FieldPolicy | FieldReadFunction; - invited?: FieldPolicy | FieldReadFunction; - invitesLeft?: FieldPolicy | FieldReadFunction; - isIDKitPhoneVerified?: FieldPolicy | FieldReadFunction; - iss?: FieldPolicy | FieldReadFunction; - mutualFollowersProfiles?: FieldPolicy | FieldReadFunction; - nftGalleries?: FieldPolicy | FieldReadFunction; - nftOwnershipChallenge?: FieldPolicy | FieldReadFunction; - nfts?: FieldPolicy | FieldReadFunction; - notifications?: FieldPolicy | FieldReadFunction; - pendingApprovalFollows?: FieldPolicy | FieldReadFunction; - ping?: FieldPolicy | FieldReadFunction; - profile?: FieldPolicy | FieldReadFunction; - profileFollowModuleBeenRedeemed?: FieldPolicy | FieldReadFunction; - profileFollowRevenue?: FieldPolicy | FieldReadFunction; - profileGuardianInformation?: FieldPolicy | FieldReadFunction; - profileInterests?: FieldPolicy | FieldReadFunction; - profileOnChainIdentity?: FieldPolicy | FieldReadFunction; - profilePublicationRevenue?: FieldPolicy | FieldReadFunction; - profilePublicationsForSale?: FieldPolicy | FieldReadFunction; - profiles?: FieldPolicy | FieldReadFunction; - proxyActionStatus?: FieldPolicy | FieldReadFunction; - publication?: FieldPolicy | FieldReadFunction; - publicationMetadataStatus?: FieldPolicy | FieldReadFunction; - publicationRevenue?: FieldPolicy | FieldReadFunction; - publications?: FieldPolicy | FieldReadFunction; - publicationsProfileBookmarks?: FieldPolicy | FieldReadFunction; - recommendedProfiles?: FieldPolicy | FieldReadFunction; - rel?: FieldPolicy | FieldReadFunction; - relayQueues?: FieldPolicy | FieldReadFunction; - search?: FieldPolicy | FieldReadFunction; - searchNfts?: FieldPolicy | FieldReadFunction; - txIdToTxHash?: FieldPolicy | FieldReadFunction; - unknownEnabledModules?: FieldPolicy | FieldReadFunction; - userSigNonces?: FieldPolicy | FieldReadFunction; - validatePublicationMetadata?: FieldPolicy | FieldReadFunction; - verify?: FieldPolicy | FieldReadFunction; - whoCollectedPublication?: FieldPolicy | FieldReadFunction; - whoReactedPublication?: FieldPolicy | FieldReadFunction; -}; -export type ReactionEventKeySpecifier = ( - | 'profile' - | 'reaction' - | 'timestamp' - | ReactionEventKeySpecifier -)[]; -export type ReactionEventFieldPolicy = { - profile?: FieldPolicy | FieldReadFunction; - reaction?: FieldPolicy | FieldReadFunction; - timestamp?: FieldPolicy | FieldReadFunction; -}; -export type RecipientDataOutputKeySpecifier = ( - | 'recipient' - | 'split' - | RecipientDataOutputKeySpecifier -)[]; -export type RecipientDataOutputFieldPolicy = { - recipient?: FieldPolicy | FieldReadFunction; - split?: FieldPolicy | FieldReadFunction; -}; -export type RelayErrorKeySpecifier = ('reason' | RelayErrorKeySpecifier)[]; -export type RelayErrorFieldPolicy = { - reason?: FieldPolicy | FieldReadFunction; -}; -export type RelayQueueResultKeySpecifier = ( - | 'address' - | 'queue' - | 'relayer' - | RelayQueueResultKeySpecifier -)[]; -export type RelayQueueResultFieldPolicy = { - address?: FieldPolicy | FieldReadFunction; - queue?: FieldPolicy | FieldReadFunction; - relayer?: FieldPolicy | FieldReadFunction; -}; -export type RelayerResultKeySpecifier = ('txHash' | 'txId' | RelayerResultKeySpecifier)[]; -export type RelayerResultFieldPolicy = { - txHash?: FieldPolicy | FieldReadFunction; - txId?: FieldPolicy | FieldReadFunction; -}; -export type ReservedClaimableHandleKeySpecifier = ( - | 'expiry' - | 'handle' - | 'id' - | 'source' - | ReservedClaimableHandleKeySpecifier -)[]; -export type ReservedClaimableHandleFieldPolicy = { - expiry?: FieldPolicy | FieldReadFunction; - handle?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - source?: FieldPolicy | FieldReadFunction; -}; -export type RevenueAggregateKeySpecifier = ( - | 'total' - | 'totalAmount' - | RevenueAggregateKeySpecifier -)[]; -export type RevenueAggregateFieldPolicy = { - total?: FieldPolicy | FieldReadFunction; - totalAmount?: FieldPolicy | FieldReadFunction; -}; -export type RevertCollectModuleSettingsKeySpecifier = ( - | 'contractAddress' - | 'type' - | RevertCollectModuleSettingsKeySpecifier -)[]; -export type RevertCollectModuleSettingsFieldPolicy = { - contractAddress?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type RevertFollowModuleSettingsKeySpecifier = ( - | 'contractAddress' - | 'type' - | RevertFollowModuleSettingsKeySpecifier -)[]; -export type RevertFollowModuleSettingsFieldPolicy = { - contractAddress?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type SetDefaultProfileBroadcastItemResultKeySpecifier = ( - | 'expiresAt' - | 'id' - | 'typedData' - | SetDefaultProfileBroadcastItemResultKeySpecifier -)[]; -export type SetDefaultProfileBroadcastItemResultFieldPolicy = { - expiresAt?: FieldPolicy | FieldReadFunction; - id?: FieldPolicy | FieldReadFunction; - typedData?: FieldPolicy | FieldReadFunction; -}; -export type SetDefaultProfileEIP712TypedDataKeySpecifier = ( - | 'domain' - | 'types' - | 'value' - | SetDefaultProfileEIP712TypedDataKeySpecifier -)[]; -export type SetDefaultProfileEIP712TypedDataFieldPolicy = { - domain?: FieldPolicy | FieldReadFunction; - types?: FieldPolicy | FieldReadFunction; - value?: FieldPolicy | FieldReadFunction; -}; -export type SetDefaultProfileEIP712TypedDataTypesKeySpecifier = ( - | 'SetDefaultProfileWithSig' - | SetDefaultProfileEIP712TypedDataTypesKeySpecifier -)[]; -export type SetDefaultProfileEIP712TypedDataTypesFieldPolicy = { - SetDefaultProfileWithSig?: FieldPolicy | FieldReadFunction; -}; -export type SetDefaultProfileEIP712TypedDataValueKeySpecifier = ( - | 'deadline' - | 'nonce' - | 'profileId' - | 'wallet' - | SetDefaultProfileEIP712TypedDataValueKeySpecifier -)[]; -export type SetDefaultProfileEIP712TypedDataValueFieldPolicy = { - deadline?: FieldPolicy | FieldReadFunction; - nonce?: FieldPolicy | FieldReadFunction; - profileId?: FieldPolicy | FieldReadFunction; - wallet?: FieldPolicy | FieldReadFunction; -}; -export type SimpleCollectModuleSettingsKeySpecifier = ( - | 'collectLimit' - | 'contractAddress' - | 'endTimestamp' - | 'fee' - | 'followerOnly' - | 'type' - | SimpleCollectModuleSettingsKeySpecifier -)[]; -export type SimpleCollectModuleSettingsFieldPolicy = { - collectLimit?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - endTimestamp?: FieldPolicy | FieldReadFunction; - fee?: FieldPolicy | FieldReadFunction; - followerOnly?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type SubscriptionKeySpecifier = ( - | 'newDataAvailabilityTransaction' - | SubscriptionKeySpecifier -)[]; -export type SubscriptionFieldPolicy = { - newDataAvailabilityTransaction?: FieldPolicy | FieldReadFunction; -}; -export type SybilDotOrgIdentityKeySpecifier = ( - | 'source' - | 'verified' - | SybilDotOrgIdentityKeySpecifier -)[]; -export type SybilDotOrgIdentityFieldPolicy = { - source?: FieldPolicy | FieldReadFunction; - verified?: FieldPolicy | FieldReadFunction; -}; -export type SybilDotOrgIdentitySourceKeySpecifier = ( - | 'twitter' - | SybilDotOrgIdentitySourceKeySpecifier -)[]; -export type SybilDotOrgIdentitySourceFieldPolicy = { - twitter?: FieldPolicy | FieldReadFunction; -}; -export type SybilDotOrgTwitterIdentityKeySpecifier = ( - | 'handle' - | SybilDotOrgTwitterIdentityKeySpecifier -)[]; -export type SybilDotOrgTwitterIdentityFieldPolicy = { - handle?: FieldPolicy | FieldReadFunction; -}; -export type TagResultKeySpecifier = ('tag' | 'total' | TagResultKeySpecifier)[]; -export type TagResultFieldPolicy = { - tag?: FieldPolicy | FieldReadFunction; - total?: FieldPolicy | FieldReadFunction; -}; -export type TimedFeeCollectModuleSettingsKeySpecifier = ( - | 'amount' - | 'contractAddress' - | 'endTimestamp' - | 'followerOnly' - | 'recipient' - | 'referralFee' - | 'type' - | TimedFeeCollectModuleSettingsKeySpecifier -)[]; -export type TimedFeeCollectModuleSettingsFieldPolicy = { - amount?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - endTimestamp?: FieldPolicy | FieldReadFunction; - followerOnly?: FieldPolicy | FieldReadFunction; - recipient?: FieldPolicy | FieldReadFunction; - referralFee?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type TransactionErrorKeySpecifier = ( - | 'reason' - | 'txReceipt' - | TransactionErrorKeySpecifier -)[]; -export type TransactionErrorFieldPolicy = { - reason?: FieldPolicy | FieldReadFunction; - txReceipt?: FieldPolicy | FieldReadFunction; -}; -export type TransactionIndexedResultKeySpecifier = ( - | 'indexed' - | 'metadataStatus' - | 'txHash' - | 'txReceipt' - | TransactionIndexedResultKeySpecifier -)[]; -export type TransactionIndexedResultFieldPolicy = { - indexed?: FieldPolicy | FieldReadFunction; - metadataStatus?: FieldPolicy | FieldReadFunction; - txHash?: FieldPolicy | FieldReadFunction; - txReceipt?: FieldPolicy | FieldReadFunction; -}; -export type TransactionReceiptKeySpecifier = ( - | 'blockHash' - | 'blockNumber' - | 'byzantium' - | 'confirmations' - | 'contractAddress' - | 'cumulativeGasUsed' - | 'effectiveGasPrice' - | 'from' - | 'gasUsed' - | 'logs' - | 'logsBloom' - | 'root' - | 'status' - | 'to' - | 'transactionHash' - | 'transactionIndex' - | 'type' - | TransactionReceiptKeySpecifier -)[]; -export type TransactionReceiptFieldPolicy = { - blockHash?: FieldPolicy | FieldReadFunction; - blockNumber?: FieldPolicy | FieldReadFunction; - byzantium?: FieldPolicy | FieldReadFunction; - confirmations?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - cumulativeGasUsed?: FieldPolicy | FieldReadFunction; - effectiveGasPrice?: FieldPolicy | FieldReadFunction; - from?: FieldPolicy | FieldReadFunction; - gasUsed?: FieldPolicy | FieldReadFunction; - logs?: FieldPolicy | FieldReadFunction; - logsBloom?: FieldPolicy | FieldReadFunction; - root?: FieldPolicy | FieldReadFunction; - status?: FieldPolicy | FieldReadFunction; - to?: FieldPolicy | FieldReadFunction; - transactionHash?: FieldPolicy | FieldReadFunction; - transactionIndex?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type UnknownCollectModuleSettingsKeySpecifier = ( - | 'collectModuleReturnData' - | 'contractAddress' - | 'type' - | UnknownCollectModuleSettingsKeySpecifier -)[]; -export type UnknownCollectModuleSettingsFieldPolicy = { - collectModuleReturnData?: FieldPolicy | FieldReadFunction; - contractAddress?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type UnknownFollowModuleSettingsKeySpecifier = ( - | 'contractAddress' - | 'followModuleReturnData' - | 'type' - | UnknownFollowModuleSettingsKeySpecifier -)[]; -export type UnknownFollowModuleSettingsFieldPolicy = { - contractAddress?: FieldPolicy | FieldReadFunction; - followModuleReturnData?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type UnknownReferenceModuleSettingsKeySpecifier = ( - | 'contractAddress' - | 'referenceModuleReturnData' - | 'type' - | UnknownReferenceModuleSettingsKeySpecifier -)[]; -export type UnknownReferenceModuleSettingsFieldPolicy = { - contractAddress?: FieldPolicy | FieldReadFunction; - referenceModuleReturnData?: FieldPolicy | FieldReadFunction; - type?: FieldPolicy | FieldReadFunction; -}; -export type UserSigNoncesKeySpecifier = ( - | 'lensHubOnChainSigNonce' - | 'peripheryOnChainSigNonce' - | UserSigNoncesKeySpecifier -)[]; -export type UserSigNoncesFieldPolicy = { - lensHubOnChainSigNonce?: FieldPolicy | FieldReadFunction; - peripheryOnChainSigNonce?: FieldPolicy | FieldReadFunction; -}; -export type WalletKeySpecifier = ('address' | 'defaultProfile' | WalletKeySpecifier)[]; -export type WalletFieldPolicy = { - address?: FieldPolicy | FieldReadFunction; - defaultProfile?: FieldPolicy | FieldReadFunction; -}; -export type WhoReactedResultKeySpecifier = ( - | 'profile' - | 'reaction' - | 'reactionAt' - | 'reactionId' - | WhoReactedResultKeySpecifier -)[]; -export type WhoReactedResultFieldPolicy = { - profile?: FieldPolicy | FieldReadFunction; - reaction?: FieldPolicy | FieldReadFunction; - reactionAt?: FieldPolicy | FieldReadFunction; - reactionId?: FieldPolicy | FieldReadFunction; -}; -export type WorldcoinIdentityKeySpecifier = ('isHuman' | WorldcoinIdentityKeySpecifier)[]; -export type WorldcoinIdentityFieldPolicy = { - isHuman?: FieldPolicy | FieldReadFunction; -}; -export type StrictTypedTypePolicies = { - AaveFeeCollectModuleSettings?: Omit & { - keyFields?: - | false - | AaveFeeCollectModuleSettingsKeySpecifier - | (() => undefined | AaveFeeCollectModuleSettingsKeySpecifier); - fields?: AaveFeeCollectModuleSettingsFieldPolicy; - }; - AccessConditionOutput?: Omit & { - keyFields?: - | false - | AccessConditionOutputKeySpecifier - | (() => undefined | AccessConditionOutputKeySpecifier); - fields?: AccessConditionOutputFieldPolicy; - }; - AndConditionOutput?: Omit & { - keyFields?: - | false - | AndConditionOutputKeySpecifier - | (() => undefined | AndConditionOutputKeySpecifier); - fields?: AndConditionOutputFieldPolicy; - }; - ApprovedAllowanceAmount?: Omit & { - keyFields?: - | false - | ApprovedAllowanceAmountKeySpecifier - | (() => undefined | ApprovedAllowanceAmountKeySpecifier); - fields?: ApprovedAllowanceAmountFieldPolicy; - }; - Attribute?: Omit & { - keyFields?: false | AttributeKeySpecifier | (() => undefined | AttributeKeySpecifier); - fields?: AttributeFieldPolicy; - }; - AuthChallengeResult?: Omit & { - keyFields?: - | false - | AuthChallengeResultKeySpecifier - | (() => undefined | AuthChallengeResultKeySpecifier); - fields?: AuthChallengeResultFieldPolicy; - }; - AuthenticationResult?: Omit & { - keyFields?: - | false - | AuthenticationResultKeySpecifier - | (() => undefined | AuthenticationResultKeySpecifier); - fields?: AuthenticationResultFieldPolicy; - }; - CanCommentResponse?: Omit & { - keyFields?: - | false - | CanCommentResponseKeySpecifier - | (() => undefined | CanCommentResponseKeySpecifier); - fields?: CanCommentResponseFieldPolicy; - }; - CanDecryptResponse?: Omit & { - keyFields?: - | false - | CanDecryptResponseKeySpecifier - | (() => undefined | CanDecryptResponseKeySpecifier); - fields?: CanDecryptResponseFieldPolicy; - }; - CanMirrorResponse?: Omit & { - keyFields?: - | false - | CanMirrorResponseKeySpecifier - | (() => undefined | CanMirrorResponseKeySpecifier); - fields?: CanMirrorResponseFieldPolicy; - }; - ClaimableHandles?: Omit & { - keyFields?: - | false - | ClaimableHandlesKeySpecifier - | (() => undefined | ClaimableHandlesKeySpecifier); - fields?: ClaimableHandlesFieldPolicy; - }; - CollectConditionOutput?: Omit & { - keyFields?: - | false - | CollectConditionOutputKeySpecifier - | (() => undefined | CollectConditionOutputKeySpecifier); - fields?: CollectConditionOutputFieldPolicy; - }; - CollectedEvent?: Omit & { - keyFields?: false | CollectedEventKeySpecifier | (() => undefined | CollectedEventKeySpecifier); - fields?: CollectedEventFieldPolicy; - }; - Comment?: Omit & { - keyFields?: false | CommentKeySpecifier | (() => undefined | CommentKeySpecifier); - fields?: CommentFieldPolicy; - }; - CreateBurnEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateBurnEIP712TypedDataKeySpecifier - | (() => undefined | CreateBurnEIP712TypedDataKeySpecifier); - fields?: CreateBurnEIP712TypedDataFieldPolicy; - }; - CreateBurnEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateBurnEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateBurnEIP712TypedDataTypesKeySpecifier); - fields?: CreateBurnEIP712TypedDataTypesFieldPolicy; - }; - CreateBurnEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateBurnEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateBurnEIP712TypedDataValueKeySpecifier); - fields?: CreateBurnEIP712TypedDataValueFieldPolicy; - }; - CreateBurnProfileBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateBurnProfileBroadcastItemResultKeySpecifier - | (() => undefined | CreateBurnProfileBroadcastItemResultKeySpecifier); - fields?: CreateBurnProfileBroadcastItemResultFieldPolicy; - }; - CreateCollectBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateCollectBroadcastItemResultKeySpecifier - | (() => undefined | CreateCollectBroadcastItemResultKeySpecifier); - fields?: CreateCollectBroadcastItemResultFieldPolicy; - }; - CreateCollectEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateCollectEIP712TypedDataKeySpecifier - | (() => undefined | CreateCollectEIP712TypedDataKeySpecifier); - fields?: CreateCollectEIP712TypedDataFieldPolicy; - }; - CreateCollectEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateCollectEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateCollectEIP712TypedDataTypesKeySpecifier); - fields?: CreateCollectEIP712TypedDataTypesFieldPolicy; - }; - CreateCollectEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateCollectEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateCollectEIP712TypedDataValueKeySpecifier); - fields?: CreateCollectEIP712TypedDataValueFieldPolicy; - }; - CreateCommentBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateCommentBroadcastItemResultKeySpecifier - | (() => undefined | CreateCommentBroadcastItemResultKeySpecifier); - fields?: CreateCommentBroadcastItemResultFieldPolicy; - }; - CreateCommentEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateCommentEIP712TypedDataKeySpecifier - | (() => undefined | CreateCommentEIP712TypedDataKeySpecifier); - fields?: CreateCommentEIP712TypedDataFieldPolicy; - }; - CreateCommentEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateCommentEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateCommentEIP712TypedDataTypesKeySpecifier); - fields?: CreateCommentEIP712TypedDataTypesFieldPolicy; - }; - CreateCommentEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateCommentEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateCommentEIP712TypedDataValueKeySpecifier); - fields?: CreateCommentEIP712TypedDataValueFieldPolicy; - }; - CreateDataAvailabilityPublicationResult?: Omit & { - keyFields?: - | false - | CreateDataAvailabilityPublicationResultKeySpecifier - | (() => undefined | CreateDataAvailabilityPublicationResultKeySpecifier); - fields?: CreateDataAvailabilityPublicationResultFieldPolicy; - }; - CreateFollowBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateFollowBroadcastItemResultKeySpecifier - | (() => undefined | CreateFollowBroadcastItemResultKeySpecifier); - fields?: CreateFollowBroadcastItemResultFieldPolicy; - }; - CreateFollowEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateFollowEIP712TypedDataKeySpecifier - | (() => undefined | CreateFollowEIP712TypedDataKeySpecifier); - fields?: CreateFollowEIP712TypedDataFieldPolicy; - }; - CreateFollowEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateFollowEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateFollowEIP712TypedDataTypesKeySpecifier); - fields?: CreateFollowEIP712TypedDataTypesFieldPolicy; - }; - CreateFollowEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateFollowEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateFollowEIP712TypedDataValueKeySpecifier); - fields?: CreateFollowEIP712TypedDataValueFieldPolicy; - }; - CreateMirrorBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateMirrorBroadcastItemResultKeySpecifier - | (() => undefined | CreateMirrorBroadcastItemResultKeySpecifier); - fields?: CreateMirrorBroadcastItemResultFieldPolicy; - }; - CreateMirrorEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateMirrorEIP712TypedDataKeySpecifier - | (() => undefined | CreateMirrorEIP712TypedDataKeySpecifier); - fields?: CreateMirrorEIP712TypedDataFieldPolicy; - }; - CreateMirrorEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateMirrorEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateMirrorEIP712TypedDataTypesKeySpecifier); - fields?: CreateMirrorEIP712TypedDataTypesFieldPolicy; - }; - CreateMirrorEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateMirrorEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateMirrorEIP712TypedDataValueKeySpecifier); - fields?: CreateMirrorEIP712TypedDataValueFieldPolicy; - }; - CreatePostBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreatePostBroadcastItemResultKeySpecifier - | (() => undefined | CreatePostBroadcastItemResultKeySpecifier); - fields?: CreatePostBroadcastItemResultFieldPolicy; - }; - CreatePostEIP712TypedData?: Omit & { - keyFields?: - | false - | CreatePostEIP712TypedDataKeySpecifier - | (() => undefined | CreatePostEIP712TypedDataKeySpecifier); - fields?: CreatePostEIP712TypedDataFieldPolicy; - }; - CreatePostEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreatePostEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreatePostEIP712TypedDataTypesKeySpecifier); - fields?: CreatePostEIP712TypedDataTypesFieldPolicy; - }; - CreatePostEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreatePostEIP712TypedDataValueKeySpecifier - | (() => undefined | CreatePostEIP712TypedDataValueKeySpecifier); - fields?: CreatePostEIP712TypedDataValueFieldPolicy; - }; - CreateSetDispatcherBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateSetDispatcherBroadcastItemResultKeySpecifier - | (() => undefined | CreateSetDispatcherBroadcastItemResultKeySpecifier); - fields?: CreateSetDispatcherBroadcastItemResultFieldPolicy; - }; - CreateSetDispatcherEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateSetDispatcherEIP712TypedDataKeySpecifier - | (() => undefined | CreateSetDispatcherEIP712TypedDataKeySpecifier); - fields?: CreateSetDispatcherEIP712TypedDataFieldPolicy; - }; - CreateSetDispatcherEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateSetDispatcherEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateSetDispatcherEIP712TypedDataTypesKeySpecifier); - fields?: CreateSetDispatcherEIP712TypedDataTypesFieldPolicy; - }; - CreateSetDispatcherEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateSetDispatcherEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateSetDispatcherEIP712TypedDataValueKeySpecifier); - fields?: CreateSetDispatcherEIP712TypedDataValueFieldPolicy; - }; - CreateSetFollowModuleBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateSetFollowModuleBroadcastItemResultKeySpecifier - | (() => undefined | CreateSetFollowModuleBroadcastItemResultKeySpecifier); - fields?: CreateSetFollowModuleBroadcastItemResultFieldPolicy; - }; - CreateSetFollowModuleEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateSetFollowModuleEIP712TypedDataKeySpecifier - | (() => undefined | CreateSetFollowModuleEIP712TypedDataKeySpecifier); - fields?: CreateSetFollowModuleEIP712TypedDataFieldPolicy; - }; - CreateSetFollowModuleEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateSetFollowModuleEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateSetFollowModuleEIP712TypedDataTypesKeySpecifier); - fields?: CreateSetFollowModuleEIP712TypedDataTypesFieldPolicy; - }; - CreateSetFollowModuleEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateSetFollowModuleEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateSetFollowModuleEIP712TypedDataValueKeySpecifier); - fields?: CreateSetFollowModuleEIP712TypedDataValueFieldPolicy; - }; - CreateSetFollowNFTUriBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateSetFollowNFTUriBroadcastItemResultKeySpecifier - | (() => undefined | CreateSetFollowNFTUriBroadcastItemResultKeySpecifier); - fields?: CreateSetFollowNFTUriBroadcastItemResultFieldPolicy; - }; - CreateSetFollowNFTUriEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateSetFollowNFTUriEIP712TypedDataKeySpecifier - | (() => undefined | CreateSetFollowNFTUriEIP712TypedDataKeySpecifier); - fields?: CreateSetFollowNFTUriEIP712TypedDataFieldPolicy; - }; - CreateSetFollowNFTUriEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateSetFollowNFTUriEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateSetFollowNFTUriEIP712TypedDataTypesKeySpecifier); - fields?: CreateSetFollowNFTUriEIP712TypedDataTypesFieldPolicy; - }; - CreateSetFollowNFTUriEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateSetFollowNFTUriEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateSetFollowNFTUriEIP712TypedDataValueKeySpecifier); - fields?: CreateSetFollowNFTUriEIP712TypedDataValueFieldPolicy; - }; - CreateSetProfileImageUriBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateSetProfileImageUriBroadcastItemResultKeySpecifier - | (() => undefined | CreateSetProfileImageUriBroadcastItemResultKeySpecifier); - fields?: CreateSetProfileImageUriBroadcastItemResultFieldPolicy; - }; - CreateSetProfileImageUriEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateSetProfileImageUriEIP712TypedDataKeySpecifier - | (() => undefined | CreateSetProfileImageUriEIP712TypedDataKeySpecifier); - fields?: CreateSetProfileImageUriEIP712TypedDataFieldPolicy; - }; - CreateSetProfileImageUriEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateSetProfileImageUriEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateSetProfileImageUriEIP712TypedDataTypesKeySpecifier); - fields?: CreateSetProfileImageUriEIP712TypedDataTypesFieldPolicy; - }; - CreateSetProfileImageUriEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateSetProfileImageUriEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateSetProfileImageUriEIP712TypedDataValueKeySpecifier); - fields?: CreateSetProfileImageUriEIP712TypedDataValueFieldPolicy; - }; - CreateSetProfileMetadataURIBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateSetProfileMetadataURIBroadcastItemResultKeySpecifier - | (() => undefined | CreateSetProfileMetadataURIBroadcastItemResultKeySpecifier); - fields?: CreateSetProfileMetadataURIBroadcastItemResultFieldPolicy; - }; - CreateSetProfileMetadataURIEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateSetProfileMetadataURIEIP712TypedDataKeySpecifier - | (() => undefined | CreateSetProfileMetadataURIEIP712TypedDataKeySpecifier); - fields?: CreateSetProfileMetadataURIEIP712TypedDataFieldPolicy; - }; - CreateSetProfileMetadataURIEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateSetProfileMetadataURIEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateSetProfileMetadataURIEIP712TypedDataTypesKeySpecifier); - fields?: CreateSetProfileMetadataURIEIP712TypedDataTypesFieldPolicy; - }; - CreateSetProfileMetadataURIEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateSetProfileMetadataURIEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateSetProfileMetadataURIEIP712TypedDataValueKeySpecifier); - fields?: CreateSetProfileMetadataURIEIP712TypedDataValueFieldPolicy; - }; - CreateToggleFollowBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateToggleFollowBroadcastItemResultKeySpecifier - | (() => undefined | CreateToggleFollowBroadcastItemResultKeySpecifier); - fields?: CreateToggleFollowBroadcastItemResultFieldPolicy; - }; - CreateToggleFollowEIP712TypedData?: Omit & { - keyFields?: - | false - | CreateToggleFollowEIP712TypedDataKeySpecifier - | (() => undefined | CreateToggleFollowEIP712TypedDataKeySpecifier); - fields?: CreateToggleFollowEIP712TypedDataFieldPolicy; - }; - CreateToggleFollowEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | CreateToggleFollowEIP712TypedDataTypesKeySpecifier - | (() => undefined | CreateToggleFollowEIP712TypedDataTypesKeySpecifier); - fields?: CreateToggleFollowEIP712TypedDataTypesFieldPolicy; - }; - CreateToggleFollowEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | CreateToggleFollowEIP712TypedDataValueKeySpecifier - | (() => undefined | CreateToggleFollowEIP712TypedDataValueKeySpecifier); - fields?: CreateToggleFollowEIP712TypedDataValueFieldPolicy; - }; - CreateUnfollowBroadcastItemResult?: Omit & { - keyFields?: - | false - | CreateUnfollowBroadcastItemResultKeySpecifier - | (() => undefined | CreateUnfollowBroadcastItemResultKeySpecifier); - fields?: CreateUnfollowBroadcastItemResultFieldPolicy; - }; - DataAvailabilityComment?: Omit & { - keyFields?: - | false - | DataAvailabilityCommentKeySpecifier - | (() => undefined | DataAvailabilityCommentKeySpecifier); - fields?: DataAvailabilityCommentFieldPolicy; - }; - DataAvailabilityMirror?: Omit & { - keyFields?: - | false - | DataAvailabilityMirrorKeySpecifier - | (() => undefined | DataAvailabilityMirrorKeySpecifier); - fields?: DataAvailabilityMirrorFieldPolicy; - }; - DataAvailabilityPost?: Omit & { - keyFields?: - | false - | DataAvailabilityPostKeySpecifier - | (() => undefined | DataAvailabilityPostKeySpecifier); - fields?: DataAvailabilityPostFieldPolicy; - }; - DataAvailabilitySubmitterResult?: Omit & { - keyFields?: - | false - | DataAvailabilitySubmitterResultKeySpecifier - | (() => undefined | DataAvailabilitySubmitterResultKeySpecifier); - fields?: DataAvailabilitySubmitterResultFieldPolicy; - }; - DataAvailabilitySubmittersResult?: Omit & { - keyFields?: - | false - | DataAvailabilitySubmittersResultKeySpecifier - | (() => undefined | DataAvailabilitySubmittersResultKeySpecifier); - fields?: DataAvailabilitySubmittersResultFieldPolicy; - }; - DataAvailabilitySummaryResult?: Omit & { - keyFields?: - | false - | DataAvailabilitySummaryResultKeySpecifier - | (() => undefined | DataAvailabilitySummaryResultKeySpecifier); - fields?: DataAvailabilitySummaryResultFieldPolicy; - }; - DataAvailabilityTransactionsResult?: Omit & { - keyFields?: - | false - | DataAvailabilityTransactionsResultKeySpecifier - | (() => undefined | DataAvailabilityTransactionsResultKeySpecifier); - fields?: DataAvailabilityTransactionsResultFieldPolicy; - }; - DataAvailabilityVerificationStatusFailure?: Omit & { - keyFields?: - | false - | DataAvailabilityVerificationStatusFailureKeySpecifier - | (() => undefined | DataAvailabilityVerificationStatusFailureKeySpecifier); - fields?: DataAvailabilityVerificationStatusFailureFieldPolicy; - }; - DataAvailabilityVerificationStatusSuccess?: Omit & { - keyFields?: - | false - | DataAvailabilityVerificationStatusSuccessKeySpecifier - | (() => undefined | DataAvailabilityVerificationStatusSuccessKeySpecifier); - fields?: DataAvailabilityVerificationStatusSuccessFieldPolicy; - }; - DegreesOfSeparationReferenceModuleSettings?: Omit & { - keyFields?: - | false - | DegreesOfSeparationReferenceModuleSettingsKeySpecifier - | (() => undefined | DegreesOfSeparationReferenceModuleSettingsKeySpecifier); - fields?: DegreesOfSeparationReferenceModuleSettingsFieldPolicy; - }; - Dispatcher?: Omit & { - keyFields?: false | DispatcherKeySpecifier | (() => undefined | DispatcherKeySpecifier); - fields?: DispatcherFieldPolicy; - }; - DoesFollowResponse?: Omit & { - keyFields?: - | false - | DoesFollowResponseKeySpecifier - | (() => undefined | DoesFollowResponseKeySpecifier); - fields?: DoesFollowResponseFieldPolicy; - }; - EIP712TypedDataDomain?: Omit & { - keyFields?: - | false - | EIP712TypedDataDomainKeySpecifier - | (() => undefined | EIP712TypedDataDomainKeySpecifier); - fields?: EIP712TypedDataDomainFieldPolicy; - }; - EIP712TypedDataField?: Omit & { - keyFields?: - | false - | EIP712TypedDataFieldKeySpecifier - | (() => undefined | EIP712TypedDataFieldKeySpecifier); - fields?: EIP712TypedDataFieldFieldPolicy; - }; - ERC4626FeeCollectModuleSettings?: Omit & { - keyFields?: - | false - | ERC4626FeeCollectModuleSettingsKeySpecifier - | (() => undefined | ERC4626FeeCollectModuleSettingsKeySpecifier); - fields?: ERC4626FeeCollectModuleSettingsFieldPolicy; - }; - ElectedMirror?: Omit & { - keyFields?: false | ElectedMirrorKeySpecifier | (() => undefined | ElectedMirrorKeySpecifier); - fields?: ElectedMirrorFieldPolicy; - }; - EnabledModule?: Omit & { - keyFields?: false | EnabledModuleKeySpecifier | (() => undefined | EnabledModuleKeySpecifier); - fields?: EnabledModuleFieldPolicy; - }; - EnabledModules?: Omit & { - keyFields?: false | EnabledModulesKeySpecifier | (() => undefined | EnabledModulesKeySpecifier); - fields?: EnabledModulesFieldPolicy; - }; - EncryptedFieldsOutput?: Omit & { - keyFields?: - | false - | EncryptedFieldsOutputKeySpecifier - | (() => undefined | EncryptedFieldsOutputKeySpecifier); - fields?: EncryptedFieldsOutputFieldPolicy; - }; - EncryptedMedia?: Omit & { - keyFields?: false | EncryptedMediaKeySpecifier | (() => undefined | EncryptedMediaKeySpecifier); - fields?: EncryptedMediaFieldPolicy; - }; - EncryptedMediaSet?: Omit & { - keyFields?: - | false - | EncryptedMediaSetKeySpecifier - | (() => undefined | EncryptedMediaSetKeySpecifier); - fields?: EncryptedMediaSetFieldPolicy; - }; - EncryptionParamsOutput?: Omit & { - keyFields?: - | false - | EncryptionParamsOutputKeySpecifier - | (() => undefined | EncryptionParamsOutputKeySpecifier); - fields?: EncryptionParamsOutputFieldPolicy; - }; - EnsOnChainIdentity?: Omit & { - keyFields?: - | false - | EnsOnChainIdentityKeySpecifier - | (() => undefined | EnsOnChainIdentityKeySpecifier); - fields?: EnsOnChainIdentityFieldPolicy; - }; - EoaOwnershipOutput?: Omit & { - keyFields?: - | false - | EoaOwnershipOutputKeySpecifier - | (() => undefined | EoaOwnershipOutputKeySpecifier); - fields?: EoaOwnershipOutputFieldPolicy; - }; - Erc20?: Omit & { - keyFields?: false | Erc20KeySpecifier | (() => undefined | Erc20KeySpecifier); - fields?: Erc20FieldPolicy; - }; - Erc20Amount?: Omit & { - keyFields?: false | Erc20AmountKeySpecifier | (() => undefined | Erc20AmountKeySpecifier); - fields?: Erc20AmountFieldPolicy; - }; - Erc20OwnershipOutput?: Omit & { - keyFields?: - | false - | Erc20OwnershipOutputKeySpecifier - | (() => undefined | Erc20OwnershipOutputKeySpecifier); - fields?: Erc20OwnershipOutputFieldPolicy; - }; - ExploreProfileResult?: Omit & { - keyFields?: - | false - | ExploreProfileResultKeySpecifier - | (() => undefined | ExploreProfileResultKeySpecifier); - fields?: ExploreProfileResultFieldPolicy; - }; - ExplorePublicationResult?: Omit & { - keyFields?: - | false - | ExplorePublicationResultKeySpecifier - | (() => undefined | ExplorePublicationResultKeySpecifier); - fields?: ExplorePublicationResultFieldPolicy; - }; - FeeCollectModuleSettings?: Omit & { - keyFields?: - | false - | FeeCollectModuleSettingsKeySpecifier - | (() => undefined | FeeCollectModuleSettingsKeySpecifier); - fields?: FeeCollectModuleSettingsFieldPolicy; - }; - FeeFollowModuleSettings?: Omit & { - keyFields?: - | false - | FeeFollowModuleSettingsKeySpecifier - | (() => undefined | FeeFollowModuleSettingsKeySpecifier); - fields?: FeeFollowModuleSettingsFieldPolicy; - }; - FeedItem?: Omit & { - keyFields?: false | FeedItemKeySpecifier | (() => undefined | FeedItemKeySpecifier); - fields?: FeedItemFieldPolicy; - }; - FollowConditionOutput?: Omit & { - keyFields?: - | false - | FollowConditionOutputKeySpecifier - | (() => undefined | FollowConditionOutputKeySpecifier); - fields?: FollowConditionOutputFieldPolicy; - }; - FollowOnlyReferenceModuleSettings?: Omit & { - keyFields?: - | false - | FollowOnlyReferenceModuleSettingsKeySpecifier - | (() => undefined | FollowOnlyReferenceModuleSettingsKeySpecifier); - fields?: FollowOnlyReferenceModuleSettingsFieldPolicy; - }; - FollowRevenueResult?: Omit & { - keyFields?: - | false - | FollowRevenueResultKeySpecifier - | (() => undefined | FollowRevenueResultKeySpecifier); - fields?: FollowRevenueResultFieldPolicy; - }; - Follower?: Omit & { - keyFields?: false | FollowerKeySpecifier | (() => undefined | FollowerKeySpecifier); - fields?: FollowerFieldPolicy; - }; - FollowerNftOwnedTokenIds?: Omit & { - keyFields?: - | false - | FollowerNftOwnedTokenIdsKeySpecifier - | (() => undefined | FollowerNftOwnedTokenIdsKeySpecifier); - fields?: FollowerNftOwnedTokenIdsFieldPolicy; - }; - Following?: Omit & { - keyFields?: false | FollowingKeySpecifier | (() => undefined | FollowingKeySpecifier); - fields?: FollowingFieldPolicy; - }; - FreeCollectModuleSettings?: Omit & { - keyFields?: - | false - | FreeCollectModuleSettingsKeySpecifier - | (() => undefined | FreeCollectModuleSettingsKeySpecifier); - fields?: FreeCollectModuleSettingsFieldPolicy; - }; - GenerateModuleCurrencyApproval?: Omit & { - keyFields?: - | false - | GenerateModuleCurrencyApprovalKeySpecifier - | (() => undefined | GenerateModuleCurrencyApprovalKeySpecifier); - fields?: GenerateModuleCurrencyApprovalFieldPolicy; - }; - GlobalProtocolStats?: Omit & { - keyFields?: - | false - | GlobalProtocolStatsKeySpecifier - | (() => undefined | GlobalProtocolStatsKeySpecifier); - fields?: GlobalProtocolStatsFieldPolicy; - }; - InternalPinResult?: Omit & { - keyFields?: - | false - | InternalPinResultKeySpecifier - | (() => undefined | InternalPinResultKeySpecifier); - fields?: InternalPinResultFieldPolicy; - }; - InvitedResult?: Omit & { - keyFields?: false | InvitedResultKeySpecifier | (() => undefined | InvitedResultKeySpecifier); - fields?: InvitedResultFieldPolicy; - }; - LimitedFeeCollectModuleSettings?: Omit & { - keyFields?: - | false - | LimitedFeeCollectModuleSettingsKeySpecifier - | (() => undefined | LimitedFeeCollectModuleSettingsKeySpecifier); - fields?: LimitedFeeCollectModuleSettingsFieldPolicy; - }; - LimitedTimedFeeCollectModuleSettings?: Omit & { - keyFields?: - | false - | LimitedTimedFeeCollectModuleSettingsKeySpecifier - | (() => undefined | LimitedTimedFeeCollectModuleSettingsKeySpecifier); - fields?: LimitedTimedFeeCollectModuleSettingsFieldPolicy; - }; - Log?: Omit & { - keyFields?: false | LogKeySpecifier | (() => undefined | LogKeySpecifier); - fields?: LogFieldPolicy; - }; - Media?: Omit & { - keyFields?: false | MediaKeySpecifier | (() => undefined | MediaKeySpecifier); - fields?: MediaFieldPolicy; - }; - MediaOutput?: Omit & { - keyFields?: false | MediaOutputKeySpecifier | (() => undefined | MediaOutputKeySpecifier); - fields?: MediaOutputFieldPolicy; - }; - MediaSet?: Omit & { - keyFields?: false | MediaSetKeySpecifier | (() => undefined | MediaSetKeySpecifier); - fields?: MediaSetFieldPolicy; - }; - MetadataAttributeOutput?: Omit & { - keyFields?: - | false - | MetadataAttributeOutputKeySpecifier - | (() => undefined | MetadataAttributeOutputKeySpecifier); - fields?: MetadataAttributeOutputFieldPolicy; - }; - MetadataOutput?: Omit & { - keyFields?: false | MetadataOutputKeySpecifier | (() => undefined | MetadataOutputKeySpecifier); - fields?: MetadataOutputFieldPolicy; - }; - Mirror?: Omit & { - keyFields?: false | MirrorKeySpecifier | (() => undefined | MirrorKeySpecifier); - fields?: MirrorFieldPolicy; - }; - MirrorEvent?: Omit & { - keyFields?: false | MirrorEventKeySpecifier | (() => undefined | MirrorEventKeySpecifier); - fields?: MirrorEventFieldPolicy; - }; - ModuleFee?: Omit & { - keyFields?: false | ModuleFeeKeySpecifier | (() => undefined | ModuleFeeKeySpecifier); - fields?: ModuleFeeFieldPolicy; - }; - ModuleFeeAmount?: Omit & { - keyFields?: - | false - | ModuleFeeAmountKeySpecifier - | (() => undefined | ModuleFeeAmountKeySpecifier); - fields?: ModuleFeeAmountFieldPolicy; - }; - ModuleInfo?: Omit & { - keyFields?: false | ModuleInfoKeySpecifier | (() => undefined | ModuleInfoKeySpecifier); - fields?: ModuleInfoFieldPolicy; - }; - MultirecipientFeeCollectModuleSettings?: Omit & { - keyFields?: - | false - | MultirecipientFeeCollectModuleSettingsKeySpecifier - | (() => undefined | MultirecipientFeeCollectModuleSettingsKeySpecifier); - fields?: MultirecipientFeeCollectModuleSettingsFieldPolicy; - }; - Mutation?: Omit & { - keyFields?: false | MutationKeySpecifier | (() => undefined | MutationKeySpecifier); - fields?: MutationFieldPolicy; - }; - NFT?: Omit & { - keyFields?: false | NFTKeySpecifier | (() => undefined | NFTKeySpecifier); - fields?: NFTFieldPolicy; - }; - NFTContent?: Omit & { - keyFields?: false | NFTContentKeySpecifier | (() => undefined | NFTContentKeySpecifier); - fields?: NFTContentFieldPolicy; - }; - NFTsResult?: Omit & { - keyFields?: false | NFTsResultKeySpecifier | (() => undefined | NFTsResultKeySpecifier); - fields?: NFTsResultFieldPolicy; - }; - NewCollectNotification?: Omit & { - keyFields?: - | false - | NewCollectNotificationKeySpecifier - | (() => undefined | NewCollectNotificationKeySpecifier); - fields?: NewCollectNotificationFieldPolicy; - }; - NewCommentNotification?: Omit & { - keyFields?: - | false - | NewCommentNotificationKeySpecifier - | (() => undefined | NewCommentNotificationKeySpecifier); - fields?: NewCommentNotificationFieldPolicy; - }; - NewFollowerNotification?: Omit & { - keyFields?: - | false - | NewFollowerNotificationKeySpecifier - | (() => undefined | NewFollowerNotificationKeySpecifier); - fields?: NewFollowerNotificationFieldPolicy; - }; - NewMentionNotification?: Omit & { - keyFields?: - | false - | NewMentionNotificationKeySpecifier - | (() => undefined | NewMentionNotificationKeySpecifier); - fields?: NewMentionNotificationFieldPolicy; - }; - NewMirrorNotification?: Omit & { - keyFields?: - | false - | NewMirrorNotificationKeySpecifier - | (() => undefined | NewMirrorNotificationKeySpecifier); - fields?: NewMirrorNotificationFieldPolicy; - }; - NewReactionNotification?: Omit & { - keyFields?: - | false - | NewReactionNotificationKeySpecifier - | (() => undefined | NewReactionNotificationKeySpecifier); - fields?: NewReactionNotificationFieldPolicy; - }; - NftGallery?: Omit & { - keyFields?: false | NftGalleryKeySpecifier | (() => undefined | NftGalleryKeySpecifier); - fields?: NftGalleryFieldPolicy; - }; - NftImage?: Omit & { - keyFields?: false | NftImageKeySpecifier | (() => undefined | NftImageKeySpecifier); - fields?: NftImageFieldPolicy; - }; - NftOwnershipChallengeResult?: Omit & { - keyFields?: - | false - | NftOwnershipChallengeResultKeySpecifier - | (() => undefined | NftOwnershipChallengeResultKeySpecifier); - fields?: NftOwnershipChallengeResultFieldPolicy; - }; - NftOwnershipOutput?: Omit & { - keyFields?: - | false - | NftOwnershipOutputKeySpecifier - | (() => undefined | NftOwnershipOutputKeySpecifier); - fields?: NftOwnershipOutputFieldPolicy; - }; - OnChainIdentity?: Omit & { - keyFields?: - | false - | OnChainIdentityKeySpecifier - | (() => undefined | OnChainIdentityKeySpecifier); - fields?: OnChainIdentityFieldPolicy; - }; - OrConditionOutput?: Omit & { - keyFields?: - | false - | OrConditionOutputKeySpecifier - | (() => undefined | OrConditionOutputKeySpecifier); - fields?: OrConditionOutputFieldPolicy; - }; - Owner?: Omit & { - keyFields?: false | OwnerKeySpecifier | (() => undefined | OwnerKeySpecifier); - fields?: OwnerFieldPolicy; - }; - PaginatedAllPublicationsTagsResult?: Omit & { - keyFields?: - | false - | PaginatedAllPublicationsTagsResultKeySpecifier - | (() => undefined | PaginatedAllPublicationsTagsResultKeySpecifier); - fields?: PaginatedAllPublicationsTagsResultFieldPolicy; - }; - PaginatedFeedResult?: Omit & { - keyFields?: - | false - | PaginatedFeedResultKeySpecifier - | (() => undefined | PaginatedFeedResultKeySpecifier); - fields?: PaginatedFeedResultFieldPolicy; - }; - PaginatedFollowersResult?: Omit & { - keyFields?: - | false - | PaginatedFollowersResultKeySpecifier - | (() => undefined | PaginatedFollowersResultKeySpecifier); - fields?: PaginatedFollowersResultFieldPolicy; - }; - PaginatedFollowingResult?: Omit & { - keyFields?: - | false - | PaginatedFollowingResultKeySpecifier - | (() => undefined | PaginatedFollowingResultKeySpecifier); - fields?: PaginatedFollowingResultFieldPolicy; - }; - PaginatedForYouResult?: Omit & { - keyFields?: - | false - | PaginatedForYouResultKeySpecifier - | (() => undefined | PaginatedForYouResultKeySpecifier); - fields?: PaginatedForYouResultFieldPolicy; - }; - PaginatedNotificationResult?: Omit & { - keyFields?: - | false - | PaginatedNotificationResultKeySpecifier - | (() => undefined | PaginatedNotificationResultKeySpecifier); - fields?: PaginatedNotificationResultFieldPolicy; - }; - PaginatedProfilePublicationsForSaleResult?: Omit & { - keyFields?: - | false - | PaginatedProfilePublicationsForSaleResultKeySpecifier - | (() => undefined | PaginatedProfilePublicationsForSaleResultKeySpecifier); - fields?: PaginatedProfilePublicationsForSaleResultFieldPolicy; - }; - PaginatedProfileResult?: Omit & { - keyFields?: - | false - | PaginatedProfileResultKeySpecifier - | (() => undefined | PaginatedProfileResultKeySpecifier); - fields?: PaginatedProfileResultFieldPolicy; - }; - PaginatedPublicationResult?: Omit & { - keyFields?: - | false - | PaginatedPublicationResultKeySpecifier - | (() => undefined | PaginatedPublicationResultKeySpecifier); - fields?: PaginatedPublicationResultFieldPolicy; - }; - PaginatedResultInfo?: Omit & { - keyFields?: - | false - | PaginatedResultInfoKeySpecifier - | (() => undefined | PaginatedResultInfoKeySpecifier); - fields?: PaginatedResultInfoFieldPolicy; - }; - PaginatedTimelineResult?: Omit & { - keyFields?: - | false - | PaginatedTimelineResultKeySpecifier - | (() => undefined | PaginatedTimelineResultKeySpecifier); - fields?: PaginatedTimelineResultFieldPolicy; - }; - PaginatedWhoCollectedResult?: Omit & { - keyFields?: - | false - | PaginatedWhoCollectedResultKeySpecifier - | (() => undefined | PaginatedWhoCollectedResultKeySpecifier); - fields?: PaginatedWhoCollectedResultFieldPolicy; - }; - PaginatedWhoReactedResult?: Omit & { - keyFields?: - | false - | PaginatedWhoReactedResultKeySpecifier - | (() => undefined | PaginatedWhoReactedResultKeySpecifier); - fields?: PaginatedWhoReactedResultFieldPolicy; - }; - PendingApproveFollowsResult?: Omit & { - keyFields?: - | false - | PendingApproveFollowsResultKeySpecifier - | (() => undefined | PendingApproveFollowsResultKeySpecifier); - fields?: PendingApproveFollowsResultFieldPolicy; - }; - PendingPost?: Omit & { - keyFields?: false | PendingPostKeySpecifier | (() => undefined | PendingPostKeySpecifier); - fields?: PendingPostFieldPolicy; - }; - Post?: Omit & { - keyFields?: false | PostKeySpecifier | (() => undefined | PostKeySpecifier); - fields?: PostFieldPolicy; - }; - PrfResponse?: Omit & { - keyFields?: false | PrfResponseKeySpecifier | (() => undefined | PrfResponseKeySpecifier); - fields?: PrfResponseFieldPolicy; - }; - Profile?: Omit & { - keyFields?: false | ProfileKeySpecifier | (() => undefined | ProfileKeySpecifier); - fields?: ProfileFieldPolicy; - }; - ProfileFollowModuleSettings?: Omit & { - keyFields?: - | false - | ProfileFollowModuleSettingsKeySpecifier - | (() => undefined | ProfileFollowModuleSettingsKeySpecifier); - fields?: ProfileFollowModuleSettingsFieldPolicy; - }; - ProfileGuardianResult?: Omit & { - keyFields?: - | false - | ProfileGuardianResultKeySpecifier - | (() => undefined | ProfileGuardianResultKeySpecifier); - fields?: ProfileGuardianResultFieldPolicy; - }; - ProfileOwnershipOutput?: Omit & { - keyFields?: - | false - | ProfileOwnershipOutputKeySpecifier - | (() => undefined | ProfileOwnershipOutputKeySpecifier); - fields?: ProfileOwnershipOutputFieldPolicy; - }; - ProfilePublicationRevenueResult?: Omit & { - keyFields?: - | false - | ProfilePublicationRevenueResultKeySpecifier - | (() => undefined | ProfilePublicationRevenueResultKeySpecifier); - fields?: ProfilePublicationRevenueResultFieldPolicy; - }; - ProfileSearchResult?: Omit & { - keyFields?: - | false - | ProfileSearchResultKeySpecifier - | (() => undefined | ProfileSearchResultKeySpecifier); - fields?: ProfileSearchResultFieldPolicy; - }; - ProfileStats?: Omit & { - keyFields?: false | ProfileStatsKeySpecifier | (() => undefined | ProfileStatsKeySpecifier); - fields?: ProfileStatsFieldPolicy; - }; - ProviderSpecificParamsOutput?: Omit & { - keyFields?: - | false - | ProviderSpecificParamsOutputKeySpecifier - | (() => undefined | ProviderSpecificParamsOutputKeySpecifier); - fields?: ProviderSpecificParamsOutputFieldPolicy; - }; - ProxyActionError?: Omit & { - keyFields?: - | false - | ProxyActionErrorKeySpecifier - | (() => undefined | ProxyActionErrorKeySpecifier); - fields?: ProxyActionErrorFieldPolicy; - }; - ProxyActionQueued?: Omit & { - keyFields?: - | false - | ProxyActionQueuedKeySpecifier - | (() => undefined | ProxyActionQueuedKeySpecifier); - fields?: ProxyActionQueuedFieldPolicy; - }; - ProxyActionStatusResult?: Omit & { - keyFields?: - | false - | ProxyActionStatusResultKeySpecifier - | (() => undefined | ProxyActionStatusResultKeySpecifier); - fields?: ProxyActionStatusResultFieldPolicy; - }; - PublicMediaResults?: Omit & { - keyFields?: - | false - | PublicMediaResultsKeySpecifier - | (() => undefined | PublicMediaResultsKeySpecifier); - fields?: PublicMediaResultsFieldPolicy; - }; - PublicationMetadataStatus?: Omit & { - keyFields?: - | false - | PublicationMetadataStatusKeySpecifier - | (() => undefined | PublicationMetadataStatusKeySpecifier); - fields?: PublicationMetadataStatusFieldPolicy; - }; - PublicationRevenue?: Omit & { - keyFields?: - | false - | PublicationRevenueKeySpecifier - | (() => undefined | PublicationRevenueKeySpecifier); - fields?: PublicationRevenueFieldPolicy; - }; - PublicationSearchResult?: Omit & { - keyFields?: - | false - | PublicationSearchResultKeySpecifier - | (() => undefined | PublicationSearchResultKeySpecifier); - fields?: PublicationSearchResultFieldPolicy; - }; - PublicationStats?: Omit & { - keyFields?: - | false - | PublicationStatsKeySpecifier - | (() => undefined | PublicationStatsKeySpecifier); - fields?: PublicationStatsFieldPolicy; - }; - PublicationValidateMetadataResult?: Omit & { - keyFields?: - | false - | PublicationValidateMetadataResultKeySpecifier - | (() => undefined | PublicationValidateMetadataResultKeySpecifier); - fields?: PublicationValidateMetadataResultFieldPolicy; - }; - Query?: Omit & { - keyFields?: false | QueryKeySpecifier | (() => undefined | QueryKeySpecifier); - fields?: QueryFieldPolicy; - }; - ReactionEvent?: Omit & { - keyFields?: false | ReactionEventKeySpecifier | (() => undefined | ReactionEventKeySpecifier); - fields?: ReactionEventFieldPolicy; - }; - RecipientDataOutput?: Omit & { - keyFields?: - | false - | RecipientDataOutputKeySpecifier - | (() => undefined | RecipientDataOutputKeySpecifier); - fields?: RecipientDataOutputFieldPolicy; - }; - RelayError?: Omit & { - keyFields?: false | RelayErrorKeySpecifier | (() => undefined | RelayErrorKeySpecifier); - fields?: RelayErrorFieldPolicy; - }; - RelayQueueResult?: Omit & { - keyFields?: - | false - | RelayQueueResultKeySpecifier - | (() => undefined | RelayQueueResultKeySpecifier); - fields?: RelayQueueResultFieldPolicy; - }; - RelayerResult?: Omit & { - keyFields?: false | RelayerResultKeySpecifier | (() => undefined | RelayerResultKeySpecifier); - fields?: RelayerResultFieldPolicy; - }; - ReservedClaimableHandle?: Omit & { - keyFields?: - | false - | ReservedClaimableHandleKeySpecifier - | (() => undefined | ReservedClaimableHandleKeySpecifier); - fields?: ReservedClaimableHandleFieldPolicy; - }; - RevenueAggregate?: Omit & { - keyFields?: - | false - | RevenueAggregateKeySpecifier - | (() => undefined | RevenueAggregateKeySpecifier); - fields?: RevenueAggregateFieldPolicy; - }; - RevertCollectModuleSettings?: Omit & { - keyFields?: - | false - | RevertCollectModuleSettingsKeySpecifier - | (() => undefined | RevertCollectModuleSettingsKeySpecifier); - fields?: RevertCollectModuleSettingsFieldPolicy; - }; - RevertFollowModuleSettings?: Omit & { - keyFields?: - | false - | RevertFollowModuleSettingsKeySpecifier - | (() => undefined | RevertFollowModuleSettingsKeySpecifier); - fields?: RevertFollowModuleSettingsFieldPolicy; - }; - SetDefaultProfileBroadcastItemResult?: Omit & { - keyFields?: - | false - | SetDefaultProfileBroadcastItemResultKeySpecifier - | (() => undefined | SetDefaultProfileBroadcastItemResultKeySpecifier); - fields?: SetDefaultProfileBroadcastItemResultFieldPolicy; - }; - SetDefaultProfileEIP712TypedData?: Omit & { - keyFields?: - | false - | SetDefaultProfileEIP712TypedDataKeySpecifier - | (() => undefined | SetDefaultProfileEIP712TypedDataKeySpecifier); - fields?: SetDefaultProfileEIP712TypedDataFieldPolicy; - }; - SetDefaultProfileEIP712TypedDataTypes?: Omit & { - keyFields?: - | false - | SetDefaultProfileEIP712TypedDataTypesKeySpecifier - | (() => undefined | SetDefaultProfileEIP712TypedDataTypesKeySpecifier); - fields?: SetDefaultProfileEIP712TypedDataTypesFieldPolicy; - }; - SetDefaultProfileEIP712TypedDataValue?: Omit & { - keyFields?: - | false - | SetDefaultProfileEIP712TypedDataValueKeySpecifier - | (() => undefined | SetDefaultProfileEIP712TypedDataValueKeySpecifier); - fields?: SetDefaultProfileEIP712TypedDataValueFieldPolicy; - }; - SimpleCollectModuleSettings?: Omit & { - keyFields?: - | false - | SimpleCollectModuleSettingsKeySpecifier - | (() => undefined | SimpleCollectModuleSettingsKeySpecifier); - fields?: SimpleCollectModuleSettingsFieldPolicy; - }; - Subscription?: Omit & { - keyFields?: false | SubscriptionKeySpecifier | (() => undefined | SubscriptionKeySpecifier); - fields?: SubscriptionFieldPolicy; - }; - SybilDotOrgIdentity?: Omit & { - keyFields?: - | false - | SybilDotOrgIdentityKeySpecifier - | (() => undefined | SybilDotOrgIdentityKeySpecifier); - fields?: SybilDotOrgIdentityFieldPolicy; - }; - SybilDotOrgIdentitySource?: Omit & { - keyFields?: - | false - | SybilDotOrgIdentitySourceKeySpecifier - | (() => undefined | SybilDotOrgIdentitySourceKeySpecifier); - fields?: SybilDotOrgIdentitySourceFieldPolicy; - }; - SybilDotOrgTwitterIdentity?: Omit & { - keyFields?: - | false - | SybilDotOrgTwitterIdentityKeySpecifier - | (() => undefined | SybilDotOrgTwitterIdentityKeySpecifier); - fields?: SybilDotOrgTwitterIdentityFieldPolicy; - }; - TagResult?: Omit & { - keyFields?: false | TagResultKeySpecifier | (() => undefined | TagResultKeySpecifier); - fields?: TagResultFieldPolicy; - }; - TimedFeeCollectModuleSettings?: Omit & { - keyFields?: - | false - | TimedFeeCollectModuleSettingsKeySpecifier - | (() => undefined | TimedFeeCollectModuleSettingsKeySpecifier); - fields?: TimedFeeCollectModuleSettingsFieldPolicy; - }; - TransactionError?: Omit & { - keyFields?: - | false - | TransactionErrorKeySpecifier - | (() => undefined | TransactionErrorKeySpecifier); - fields?: TransactionErrorFieldPolicy; - }; - TransactionIndexedResult?: Omit & { - keyFields?: - | false - | TransactionIndexedResultKeySpecifier - | (() => undefined | TransactionIndexedResultKeySpecifier); - fields?: TransactionIndexedResultFieldPolicy; - }; - TransactionReceipt?: Omit & { - keyFields?: - | false - | TransactionReceiptKeySpecifier - | (() => undefined | TransactionReceiptKeySpecifier); - fields?: TransactionReceiptFieldPolicy; - }; - UnknownCollectModuleSettings?: Omit & { - keyFields?: - | false - | UnknownCollectModuleSettingsKeySpecifier - | (() => undefined | UnknownCollectModuleSettingsKeySpecifier); - fields?: UnknownCollectModuleSettingsFieldPolicy; - }; - UnknownFollowModuleSettings?: Omit & { - keyFields?: - | false - | UnknownFollowModuleSettingsKeySpecifier - | (() => undefined | UnknownFollowModuleSettingsKeySpecifier); - fields?: UnknownFollowModuleSettingsFieldPolicy; - }; - UnknownReferenceModuleSettings?: Omit & { - keyFields?: - | false - | UnknownReferenceModuleSettingsKeySpecifier - | (() => undefined | UnknownReferenceModuleSettingsKeySpecifier); - fields?: UnknownReferenceModuleSettingsFieldPolicy; - }; - UserSigNonces?: Omit & { - keyFields?: false | UserSigNoncesKeySpecifier | (() => undefined | UserSigNoncesKeySpecifier); - fields?: UserSigNoncesFieldPolicy; - }; - Wallet?: Omit & { - keyFields?: false | WalletKeySpecifier | (() => undefined | WalletKeySpecifier); - fields?: WalletFieldPolicy; - }; - WhoReactedResult?: Omit & { - keyFields?: - | false - | WhoReactedResultKeySpecifier - | (() => undefined | WhoReactedResultKeySpecifier); - fields?: WhoReactedResultFieldPolicy; - }; - WorldcoinIdentity?: Omit & { - keyFields?: - | false - | WorldcoinIdentityKeySpecifier - | (() => undefined | WorldcoinIdentityKeySpecifier); - fields?: WorldcoinIdentityFieldPolicy; - }; -}; -export type TypedTypePolicies = StrictTypedTypePolicies & TypePolicies; - -export interface PossibleTypesResultData { - possibleTypes: { - [key: string]: string[]; - }; -} -const result: PossibleTypesResultData = { - possibleTypes: { - BroadcastDataAvailabilityUnion: ['CreateDataAvailabilityPublicationResult', 'RelayError'], - CollectModule: [ - 'AaveFeeCollectModuleSettings', - 'ERC4626FeeCollectModuleSettings', - 'FeeCollectModuleSettings', - 'FreeCollectModuleSettings', - 'LimitedFeeCollectModuleSettings', - 'LimitedTimedFeeCollectModuleSettings', - 'MultirecipientFeeCollectModuleSettings', - 'RevertCollectModuleSettings', - 'SimpleCollectModuleSettings', - 'TimedFeeCollectModuleSettings', - 'UnknownCollectModuleSettings', - ], - DataAvailabilityTransactionUnion: [ - 'DataAvailabilityComment', - 'DataAvailabilityMirror', - 'DataAvailabilityPost', - ], - DataAvailabilityVerificationStatusUnion: [ - 'DataAvailabilityVerificationStatusFailure', - 'DataAvailabilityVerificationStatusSuccess', - ], - FeedItemRoot: ['Comment', 'Post'], - FollowModule: [ - 'FeeFollowModuleSettings', - 'ProfileFollowModuleSettings', - 'RevertFollowModuleSettings', - 'UnknownFollowModuleSettings', - ], - MainPostReference: ['Mirror', 'Post'], - MentionPublication: ['Comment', 'Post'], - MirrorablePublication: ['Comment', 'Post'], - Notification: [ - 'NewCollectNotification', - 'NewCommentNotification', - 'NewFollowerNotification', - 'NewMentionNotification', - 'NewMirrorNotification', - 'NewReactionNotification', - ], - ProfileMedia: ['MediaSet', 'NftImage'], - ProxyActionStatusResultUnion: [ - 'ProxyActionError', - 'ProxyActionQueued', - 'ProxyActionStatusResult', - ], - Publication: ['Comment', 'Mirror', 'Post'], - PublicationForSale: ['Comment', 'Post'], - PublicationSearchResultItem: ['Comment', 'Post'], - ReferenceModule: [ - 'DegreesOfSeparationReferenceModuleSettings', - 'FollowOnlyReferenceModuleSettings', - 'UnknownReferenceModuleSettings', - ], - RelayDataAvailabilityResult: ['CreateDataAvailabilityPublicationResult', 'RelayError'], - RelayResult: ['RelayError', 'RelayerResult'], - SearchResult: ['ProfileSearchResult', 'PublicationSearchResult'], - TransactionResult: ['TransactionError', 'TransactionIndexedResult'], - }, -}; -export default result; diff --git a/packages/api-bindings-v1/src/lens/index.ts b/packages/api-bindings-v1/src/lens/index.ts deleted file mode 100644 index c3160ce120..0000000000 --- a/packages/api-bindings-v1/src/lens/index.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { QueryHookOptions, StoreValue, useQuery } from '@apollo/client'; -import { ProfileId, PublicationId } from '@lens-protocol/domain/entities'; - -import { Cursor } from './Cursor'; -import { MediaTransformParams } from './ImageSizeTransform'; -import { - Comment, - PaginatedResultInfo, - Exact, - GetPublicationsDocument, - InputMaybe, - Profile, - PublicationMetadataFilters, - SearchProfilesDocument, - SearchProfilesVariables, - SearchPublicationsDocument, - SearchPublicationsVariables, - GetProfileBookmarksVariables, - GetProfileBookmarksDocument, -} from './generated'; -import { Sources } from './sources'; -import { ContentPublication } from './utils'; - -export * from './CollectPolicy'; -export * from './ContentEncryptionKey'; -export * from './ContentInsight'; -export * from './Cursor'; -export * from './FollowPolicy'; -export * from './FollowStatus'; -export * from './generated'; -export type { - Digit, - ImageSizeTransform, - MediaTransformParams, // overwrite the generated one - Percentage, - Pixel, -} from './ImageSizeTransform'; -export * from './ProfileAttributeReader'; -export * from './ProfileAttributes'; -export * from './ReferencePolicy'; -export * from './sources'; -export * from './utils'; - -export type CursorBasedPaginatedResult = { - items: T[]; - pageInfo: PaginatedResultInfo; -}; - -export type GetCommentsVariables = Exact<{ - commentsOf: PublicationId; - limit: number; - sources: Sources; - cursor?: InputMaybe; - metadata?: InputMaybe; - observerId?: InputMaybe; - mediaTransformPublicationSmall?: InputMaybe; - mediaTransformPublicationMedium?: InputMaybe; - mediaTransformProfileThumbnail?: InputMaybe; -}>; - -export type GetCommentsData = { - result: { - items: Array; - pageInfo: PaginatedResultInfo; - }; -}; - -/** - * This hooks uses the codegen generated GetPublications query hook so that it - * can returns paginated results of Comment in a type safe way. - */ -export function useGetComments(options: QueryHookOptions) { - return useQuery(GetPublicationsDocument, options); -} - -export type SearchProfilesData = { - result: { - __typename: 'ProfileSearchResult'; - items: Array; - pageInfo: PaginatedResultInfo; - }; -}; - -/** - * This is a patched version of the codegen generated useSearchProfilesQuery hook. - * It is patched to return paginated results of Profile instead of union with `{}` type. - * - * See: https://github.com/dotansimha/graphql-code-generator/discussions/5567 - */ -export function useSearchProfiles( - options: QueryHookOptions, -) { - return useQuery(SearchProfilesDocument, options); -} - -export type SearchPublicationsData = { - result: { - __typename: 'PublicationSearchResult'; - items: Array; - pageInfo: PaginatedResultInfo; - }; -}; - -/** - * This is a patched version of the codegen generated useSearchPublicationsQuery hook. - * It is patched to return paginated results of ContentPublication instead of union with `{}` type. - * - * See: https://github.com/dotansimha/graphql-code-generator/discussions/5567 - */ -export function useSearchPublications( - options: QueryHookOptions, -) { - return useQuery( - SearchPublicationsDocument, - options, - ); -} - -export type GetProfileBookmarksData = { - result: { - items: Array; - pageInfo: PaginatedResultInfo; - }; -}; - -/** - * This is a patched version of the codegen generated useGetProfileBookmarks hook. - * It is patched to return paginated results of ContentPublication instead of union with `{}` type. - * - * See: https://github.com/dotansimha/graphql-code-generator/discussions/5567 - */ -export function useGetProfileBookmarks( - options: QueryHookOptions, -) { - return useQuery( - GetProfileBookmarksDocument, - options, - ); -} diff --git a/packages/api-bindings-v1/src/lens/mirror.graphql b/packages/api-bindings-v1/src/lens/mirror.graphql deleted file mode 100644 index e54265690b..0000000000 --- a/packages/api-bindings-v1/src/lens/mirror.graphql +++ /dev/null @@ -1,53 +0,0 @@ -fragment CreateMirrorEIP712TypedData on CreateMirrorEIP712TypedData { - types { - MirrorWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - profileId - profileIdPointed - pubIdPointed - referenceModuleData - referenceModule - referenceModuleInitData - } -} - -mutation CreateMirrorTypedData($request: CreateMirrorRequest!, $options: TypedDataOptions) { - result: createMirrorTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - ...CreateMirrorEIP712TypedData - } - } -} - -mutation CreateMirrorViaDispatcher($request: CreateMirrorRequest!) { - result: createMirrorViaDispatcher(request: $request) { - ...BroadcastOnChainResult - } -} - -mutation CreateDataAvailabilityMirrorTypedData($request: CreateDataAvailabilityMirrorRequest!) { - result: createDataAvailabilityMirrorTypedData(request: $request) { - id - expiresAt - typedData { - ...CreateMirrorEIP712TypedData - } - } -} - -mutation CreateDataAvailabilityMirrorViaDispatcher($request: CreateDataAvailabilityMirrorRequest!) { - result: createDataAvailabilityMirrorViaDispatcher(request: $request) { - ...BroadcastOffChainResult - } -} diff --git a/packages/api-bindings-v1/src/lens/modules.graphql b/packages/api-bindings-v1/src/lens/modules.graphql deleted file mode 100644 index 78b98d098e..0000000000 --- a/packages/api-bindings-v1/src/lens/modules.graphql +++ /dev/null @@ -1,39 +0,0 @@ -fragment ModuleInfo on ModuleInfo { - __typename - name - type -} - -fragment EnabledModule on EnabledModule { - __typename - moduleName - contractAddress - inputParams { - ...ModuleInfo - } - redeemParams { - ...ModuleInfo - } - returnDataParams: returnDataParms { - ...ModuleInfo - } -} - -fragment EnabledModules on EnabledModules { - __typename - collectModules { - ...EnabledModule - } - followModules { - ...EnabledModule - } - referenceModules { - ...EnabledModule - } -} - -query EnabledModules { - result: enabledModules { - ...EnabledModules - } -} diff --git a/packages/api-bindings-v1/src/lens/notification.graphql b/packages/api-bindings-v1/src/lens/notification.graphql deleted file mode 100644 index 1a6d2db0df..0000000000 --- a/packages/api-bindings-v1/src/lens/notification.graphql +++ /dev/null @@ -1,160 +0,0 @@ -fragment NewFollowerNotification on NewFollowerNotification { - __typename - notificationId - createdAt - isFollowedByMe - wallet { - ...Wallet - } -} - -fragment NewCollectNotification on NewCollectNotification { - __typename - notificationId - createdAt - wallet { - ...Wallet - } - collectedPublication { - ... on Post { - ...Post - } - - ... on Mirror { - ...Mirror - } - - ... on Comment { - ...Comment - } - } -} - -fragment NewMirrorNotification on NewMirrorNotification { - __typename - notificationId - createdAt - profile { - ...Profile - } - publication { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - } -} - -fragment NewCommentNotification on NewCommentNotification { - __typename - notificationId - createdAt - profile { - ...Profile - } - comment { - ...Comment - } -} - -fragment NewMentionNotification on NewMentionNotification { - __typename - notificationId - createdAt - mentionPublication { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - } -} - -fragment NewReactionNotification on NewReactionNotification { - __typename - notificationId - createdAt - profile { - ...Profile - } - reaction - publication { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - ... on Mirror { - ...Mirror - } - } -} - -query Notifications( - $observerId: ProfileId! - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!]! - $notificationTypes: [NotificationTypes!] - $highSignalFilter: Boolean! - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: notifications( - request: { - profileId: $observerId - limit: $limit - cursor: $cursor - sources: $sources - notificationTypes: $notificationTypes - highSignalFilter: $highSignalFilter - } - ) { - items { - ... on NewFollowerNotification { - ...NewFollowerNotification - } - - ... on NewMirrorNotification { - ...NewMirrorNotification - } - - ... on NewCollectNotification { - ...NewCollectNotification - } - - ... on NewCommentNotification { - ...NewCommentNotification - } - - ... on NewMentionNotification { - ...NewMentionNotification - } - ... on NewReactionNotification { - ...NewReactionNotification - } - } - pageInfo { - ...PaginatedResultInfo - } - } -} - -query UnreadNotificationCount( - $profileId: ProfileId! - $sources: [Sources!] - $notificationTypes: [NotificationTypes!] -) { - result: notifications( - request: { profileId: $profileId, sources: $sources, notificationTypes: $notificationTypes } - ) { - pageInfo { - totalCount - } - } -} diff --git a/packages/api-bindings-v1/src/lens/post.graphql b/packages/api-bindings-v1/src/lens/post.graphql deleted file mode 100644 index dfaac29ac1..0000000000 --- a/packages/api-bindings-v1/src/lens/post.graphql +++ /dev/null @@ -1,53 +0,0 @@ -fragment CreatePostEIP712TypedData on CreatePostEIP712TypedData { - types { - PostWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - profileId - contentURI - collectModule - collectModuleInitData - referenceModule - referenceModuleInitData - } -} - -mutation CreatePostTypedData($request: CreatePublicPostRequest!, $options: TypedDataOptions) { - result: createPostTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - ...CreatePostEIP712TypedData - } - } -} - -mutation CreatePostViaDispatcher($request: CreatePublicPostRequest!) { - result: createPostViaDispatcher(request: $request) { - ...BroadcastOnChainResult - } -} - -mutation CreateDataAvailabilityPostTypedData($request: CreateDataAvailabilityPostRequest!) { - result: createDataAvailabilityPostTypedData(request: $request) { - id - expiresAt - typedData { - ...CreatePostEIP712TypedData - } - } -} - -mutation CreateDataAvailabilityPostViaDispatcher($request: CreateDataAvailabilityPostRequest!) { - result: createDataAvailabilityPostViaDispatcher(request: $request) { - ...BroadcastOffChainResult - } -} diff --git a/packages/api-bindings-v1/src/lens/profile-dispatcher.graphql b/packages/api-bindings-v1/src/lens/profile-dispatcher.graphql deleted file mode 100644 index 0632cb2d8e..0000000000 --- a/packages/api-bindings-v1/src/lens/profile-dispatcher.graphql +++ /dev/null @@ -1,26 +0,0 @@ -mutation CreateSetDispatcherTypedData($request: SetDispatcherRequest!, $options: TypedDataOptions) { - result: createSetDispatcherTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - SetDispatcherWithSig { - name - type - } - } - domain { - name - chainId - version - verifyingContract - } - message: value { - nonce - deadline - profileId - dispatcher - } - } - } -} diff --git a/packages/api-bindings-v1/src/lens/profile-guardian.graphql b/packages/api-bindings-v1/src/lens/profile-guardian.graphql deleted file mode 100644 index 906363c2e0..0000000000 --- a/packages/api-bindings-v1/src/lens/profile-guardian.graphql +++ /dev/null @@ -1,10 +0,0 @@ -fragment ProfileGuardianResult on ProfileGuardianResult { - protected - disablingProtectionTimestamp -} - -query ProfileGuardian($request: ProfileGuardianRequest!) { - result: profileGuardianInformation(request: $request) { - ...ProfileGuardianResult - } -} diff --git a/packages/api-bindings-v1/src/lens/profile.graphql b/packages/api-bindings-v1/src/lens/profile.graphql deleted file mode 100644 index e4109fbd48..0000000000 --- a/packages/api-bindings-v1/src/lens/profile.graphql +++ /dev/null @@ -1,338 +0,0 @@ -fragment FeeFollowModuleSettings on FeeFollowModuleSettings { - __typename - amount { - ...ModuleFeeAmount - } - contractAddress - recipient -} - -fragment ProfileFollowModuleSettings on ProfileFollowModuleSettings { - __typename - contractAddress -} - -fragment RevertFollowModuleSettings on RevertFollowModuleSettings { - __typename - contractAddress -} - -fragment UnknownFollowModuleSettings on UnknownFollowModuleSettings { - __typename - contractAddress -} - -fragment NftImage on NftImage { - __typename - contractAddress - tokenId - uri - verified -} - -fragment Attribute on Attribute { - __typename - displayType - key - value -} - -fragment ProfileStats on ProfileStats { - __typename - totalCollects - totalComments - totalFollowers - totalFollowing - totalMirrors - totalPosts - totalPublications - - commentsCount: commentsTotal(forSources: $sources) - postsCount: postsTotal(forSources: $sources) - mirrorsCount: mirrorsTotal(forSources: $sources) -} - -fragment ProfileFields on Profile { - __typename - id - name - bio - handle - ownedBy - interests - followNftAddress - - picture { - ... on NftImage { - ...NftImage - } - - ... on MediaSet { - ...ProfilePictureSet - } - } - - coverPicture { - ... on NftImage { - ...NftImage - } - - ... on MediaSet { - ...ProfileCoverSet - } - } - - stats { - ...ProfileStats - } - - followModule { - ... on FeeFollowModuleSettings { - ...FeeFollowModuleSettings - } - - ... on ProfileFollowModuleSettings { - ...ProfileFollowModuleSettings - } - - ... on RevertFollowModuleSettings { - ...RevertFollowModuleSettings - } - - ... on UnknownFollowModuleSettings { - ...UnknownFollowModuleSettings - } - } - - followPolicy @client - - __attributes: attributes { - ...Attribute - } - attributes: attributesMap @client - - dispatcher { - address - canUseRelay - } - - onChainIdentity { - proofOfHumanity - ens { - name - } - sybilDotOrg { - verified - source { - twitter { - handle - } - } - } - worldcoin { - isHuman - } - } - - isFollowedByMe - isFollowingObserver: isFollowing(who: $observerId) - - followStatus @client - ownedByMe @client - observedBy @client -} - -fragment Profile on Profile { - ...ProfileFields - - invitedBy { - ...ProfileFields - } -} - -query ProfilesToFollow( - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: recommendedProfiles { - ...Profile - } -} - -query GetProfile( - $request: SingleProfileQueryRequest! - $observerId: ProfileId - $sources: [Sources!] = [] - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: profile(request: $request) { - ...Profile - } -} - -query GetAllProfiles( - $byProfileIds: [ProfileId!] - $byHandles: [Handle!] - $byOwnerAddresses: [EthereumAddress!] - $byWhoMirroredPublicationId: InternalPublicationId - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!] = [] - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: profiles( - request: { - whoMirroredPublicationId: $byWhoMirroredPublicationId - ownedBy: $byOwnerAddresses - profileIds: $byProfileIds - handles: $byHandles - limit: $limit - cursor: $cursor - } - ) { - items { - ...Profile - } - pageInfo { - ...PaginatedResultInfo - } - } -} - -mutation CreateProfile($request: CreateProfileRequest!) { - result: createProfile(request: $request) { - ...BroadcastOnChainResult - } -} - -query MutualFollowersProfiles( - $observerId: ProfileId! - $viewingProfileId: ProfileId! - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: mutualFollowersProfiles( - request: { - yourProfileId: $observerId - viewingProfileId: $viewingProfileId - limit: $limit - cursor: $cursor - } - ) { - items { - ...Profile - } - pageInfo { - ...PaginatedResultInfo - } - } -} - -mutation CreateSetFollowModuleTypedData( - $request: CreateSetFollowModuleRequest! - $options: TypedDataOptions -) { - result: createSetFollowModuleTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - SetFollowModuleWithSig { - name - type - } - } - domain { - name - chainId - version - verifyingContract - } - message: value { - nonce - deadline - profileId - followModule - followModuleInitData - } - } - } -} - -mutation CreateSetProfileImageURITypedData( - $request: UpdateProfileImageRequest! - $options: TypedDataOptions -) { - result: createSetProfileImageURITypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - SetProfileImageURIWithSig { - name - type - } - } - domain { - name - chainId - version - verifyingContract - } - message: value { - nonce - deadline - profileId - imageURI - } - } - } -} - -mutation CreateSetProfileImageURIViaDispatcher($request: UpdateProfileImageRequest!) { - result: createSetProfileImageURIViaDispatcher(request: $request) { - ...BroadcastOnChainResult - } -} - -mutation CreateSetProfileMetadataTypedData( - $request: CreatePublicSetProfileMetadataURIRequest! - $options: TypedDataOptions -) { - result: createSetProfileMetadataTypedData(request: $request, options: $options) { - id - expiresAt - typedData { - types { - SetProfileMetadataURIWithSig { - name - type - } - } - domain { - name - chainId - version - verifyingContract - } - message: value { - nonce - deadline - profileId - metadata - } - } - } -} - -mutation CreateSetProfileMetadataViaDispatcher( - $request: CreatePublicSetProfileMetadataURIRequest! -) { - result: createSetProfileMetadataViaDispatcher(request: $request) { - ...BroadcastOnChainResult - } -} diff --git a/packages/api-bindings-v1/src/lens/profiles-followers-following.graphql b/packages/api-bindings-v1/src/lens/profiles-followers-following.graphql deleted file mode 100644 index 38afc2b5ec..0000000000 --- a/packages/api-bindings-v1/src/lens/profiles-followers-following.graphql +++ /dev/null @@ -1,49 +0,0 @@ -fragment Follower on Follower { - __typename - wallet { - ...Wallet - } -} - -fragment Following on Following { - __typename - profile { - ...Profile - } -} - -query ProfileFollowers( - $profileId: ProfileId! - $limit: LimitScalar! - $cursor: Cursor - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: followers(request: { profileId: $profileId, limit: $limit, cursor: $cursor }) { - items { - ...Follower - } - pageInfo { - ...PaginatedResultInfo - } - } -} - -query ProfileFollowing( - $walletAddress: EthereumAddress! - $limit: LimitScalar! - $cursor: Cursor - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: following(request: { address: $walletAddress, limit: $limit, cursor: $cursor }) { - items { - ...Following - } - pageInfo { - ...PaginatedResultInfo - } - } -} diff --git a/packages/api-bindings-v1/src/lens/proxy-actions.graphql b/packages/api-bindings-v1/src/lens/proxy-actions.graphql deleted file mode 100644 index c139db5e15..0000000000 --- a/packages/api-bindings-v1/src/lens/proxy-actions.graphql +++ /dev/null @@ -1,36 +0,0 @@ -fragment ProxyActionStatusResult on ProxyActionStatusResult { - __typename - txHash - txId - status -} - -fragment ProxyActionError on ProxyActionError { - __typename - reason - lastKnownTxId -} - -fragment ProxyActionQueued on ProxyActionQueued { - __typename - queuedAt -} - -query ProxyActionStatus($proxyActionId: ProxyActionId!) { - result: proxyActionStatus(proxyActionId: $proxyActionId) { - ... on ProxyActionStatusResult { - ...ProxyActionStatusResult - } - ... on ProxyActionError { - ...ProxyActionError - } - - ... on ProxyActionQueued { - ...ProxyActionQueued - } - } -} - -mutation ProxyAction($request: ProxyActionRequest!) { - result: proxyAction(request: $request) -} diff --git a/packages/api-bindings-v1/src/lens/publication.graphql b/packages/api-bindings-v1/src/lens/publication.graphql deleted file mode 100644 index 6010c39580..0000000000 --- a/packages/api-bindings-v1/src/lens/publication.graphql +++ /dev/null @@ -1,42 +0,0 @@ -query GetPublication( - $request: PublicationQueryRequest! - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: publication(request: $request) { - ... on Post { - ...Post - } - - ... on Mirror { - ...Mirror - } - - ... on Comment { - ...Comment - } - } -} - -mutation HidePublication($publicationId: InternalPublicationId!) { - hidePublication(request: { publicationId: $publicationId }) -} - -mutation AddNotInterested($request: PublicationProfileNotInterestedRequest!) { - result: addPublicationProfileNotInterested(request: $request) -} - -mutation RemoveNotInterested($request: PublicationProfileNotInterestedRequest!) { - result: removePublicationProfileNotInterested(request: $request) -} - -mutation AddToMyBookmarks($request: PublicationProfileBookmarkRequest!) { - result: addPublicationProfileBookmark(request: $request) -} - -mutation RemoveFromMyBookmarks($request: PublicationProfileBookmarkRequest!) { - result: removePublicationProfileBookmark(request: $request) -} diff --git a/packages/api-bindings-v1/src/lens/publications.graphql b/packages/api-bindings-v1/src/lens/publications.graphql deleted file mode 100644 index b22063df5f..0000000000 --- a/packages/api-bindings-v1/src/lens/publications.graphql +++ /dev/null @@ -1,181 +0,0 @@ -query GetPublications( - $profileId: ProfileId - $profileIds: [ProfileId!] - $publicationIds: [InternalPublicationId!] - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $publicationTypes: [PublicationTypes!] - $sources: [Sources!]! - $metadata: PublicationMetadataFilters - $commentsOf: InternalPublicationId - $commentsOfOrdering: CommentOrderingTypes - $commentsRankingFilter: CommentRankingFilter - $walletAddress: EthereumAddress - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: publications( - request: { - profileId: $profileId - profileIds: $profileIds - publicationIds: $publicationIds - limit: $limit - collectedBy: $walletAddress - cursor: $cursor - publicationTypes: $publicationTypes - commentsOf: $commentsOf - commentsOfOrdering: $commentsOfOrdering - commentsRankingFilter: $commentsRankingFilter - sources: $sources - metadata: $metadata - } - ) { - items { - ... on Post { - ...Post - } - - ... on Mirror { - ...Mirror - } - - ... on Comment { - ...Comment - } - } - pageInfo { - ...PaginatedResultInfo - } - } -} - -query ExplorePublications( - $cursor: Cursor - $excludeProfileIds: [ProfileId!] - $limit: LimitScalar! - $metadata: PublicationMetadataFilters - $observerId: ProfileId - $publicationTypes: [PublicationTypes!] - $sortCriteria: PublicationSortCriteria! - $sources: [Sources!]! - $timestamp: TimestampScalar - $noRandomize: Boolean - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: explorePublications( - request: { - cursor: $cursor - excludeProfileIds: $excludeProfileIds - limit: $limit - metadata: $metadata - publicationTypes: $publicationTypes - sortCriteria: $sortCriteria - sources: $sources - timestamp: $timestamp - noRandomize: $noRandomize - } - ) { - items { - ... on Post { - ...Post - } - - ... on Mirror { - ...Mirror - } - - ... on Comment { - ...Comment - } - } - pageInfo { - ...PaginatedResultInfo - } - } -} - -query WhoCollectedPublication( - $publicationId: InternalPublicationId! - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: whoCollectedPublication( - request: { publicationId: $publicationId, limit: $limit, cursor: $cursor } - ) { - items { - ...Wallet - } - pageInfo { - ...PaginatedResultInfo - } - } -} - -query ProfilePublicationsForSale( - $profileId: ProfileId! - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $sources: [Sources!]! - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: profilePublicationsForSale( - request: { profileId: $profileId, limit: $limit, cursor: $cursor, sources: $sources } - ) { - items { - ... on Post { - ...Post - } - ... on Comment { - ...Comment - } - } - pageInfo { - ...PaginatedResultInfo - } - } -} - -query GetProfileBookmarks( - $profileId: ProfileId! - $limit: LimitScalar! - $sources: [Sources!]! - $metadata: PublicationMetadataFilters - $cursor: Cursor - $observerId: ProfileId - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: publicationsProfileBookmarks( - request: { - cursor: $cursor - limit: $limit - metadata: $metadata - profileId: $profileId - sources: $sources - } - ) { - items { - ... on Post { - ...Post - } - - ... on Comment { - ...Comment - } - } - pageInfo { - ...PaginatedResultInfo - } - } -} diff --git a/packages/api-bindings-v1/src/lens/reactions.graphql b/packages/api-bindings-v1/src/lens/reactions.graphql deleted file mode 100644 index 2cb198d638..0000000000 --- a/packages/api-bindings-v1/src/lens/reactions.graphql +++ /dev/null @@ -1,50 +0,0 @@ -mutation AddReaction( - $publicationId: InternalPublicationId! - $reaction: ReactionTypes! - $profileId: ProfileId! -) { - addReaction( - request: { publicationId: $publicationId, reaction: $reaction, profileId: $profileId } - ) -} - -mutation RemoveReaction( - $publicationId: InternalPublicationId! - $reaction: ReactionTypes! - $profileId: ProfileId! -) { - removeReaction( - request: { publicationId: $publicationId, reaction: $reaction, profileId: $profileId } - ) -} - -fragment WhoReactedResult on WhoReactedResult { - __typename - reactionId - reaction - reactionAt - profile { - ...Profile - } -} - -query WhoReactedPublication( - $limit: LimitScalar - $cursor: Cursor - $publicationId: InternalPublicationId! - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: whoReactedPublication( - request: { limit: $limit, cursor: $cursor, publicationId: $publicationId } - ) { - items { - ...WhoReactedResult - } - - pageInfo { - ...PaginatedResultInfo - } - } -} diff --git a/packages/api-bindings-v1/src/lens/report-publication.graphql b/packages/api-bindings-v1/src/lens/report-publication.graphql deleted file mode 100644 index 079846ce51..0000000000 --- a/packages/api-bindings-v1/src/lens/report-publication.graphql +++ /dev/null @@ -1,13 +0,0 @@ -mutation ReportPublication( - $publicationId: InternalPublicationId! - $reason: ReportingReasonInputParams! - $additionalComments: String -) { - reportPublication( - request: { - publicationId: $publicationId - reason: $reason - additionalComments: $additionalComments - } - ) -} diff --git a/packages/api-bindings-v1/src/lens/revenue.graphql b/packages/api-bindings-v1/src/lens/revenue.graphql deleted file mode 100644 index 2cdceb268d..0000000000 --- a/packages/api-bindings-v1/src/lens/revenue.graphql +++ /dev/null @@ -1,85 +0,0 @@ -fragment RevenueAggregate on RevenueAggregate { - __typename - __total: total { - ...Erc20AmountFields - } - - totalAmount @client -} - -fragment PublicationRevenue on PublicationRevenue { - __typename - publication { - ... on Post { - ...Post - } - - ... on Mirror { - ...Mirror - } - - ... on Comment { - ...Comment - } - } - - revenue { - ...RevenueAggregate - } -} - -query GetPublicationRevenue( - $publicationId: InternalPublicationId! - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: publicationRevenue(request: { publicationId: $publicationId }) { - ...PublicationRevenue - } -} - -query GetProfilePublicationRevenue( - $profileId: ProfileId! - $observerId: ProfileId - $limit: LimitScalar! - $cursor: Cursor - $publicationTypes: [PublicationTypes!] - $sources: [Sources!]! - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: profilePublicationRevenue( - request: { - profileId: $profileId - limit: $limit - cursor: $cursor - types: $publicationTypes - sources: $sources - } - ) { - items { - ...PublicationRevenue - } - - pageInfo { - ...PaginatedResultInfo - } - } -} - -fragment ProfileFollowRevenue on FollowRevenueResult { - __typename - revenues { - ...RevenueAggregate - } -} - -query ProfileFollowRevenue($profileId: ProfileId!) { - result: profileFollowRevenue(request: { profileId: $profileId }) { - ...ProfileFollowRevenue - } -} diff --git a/packages/api-bindings-v1/src/lens/search.graphql b/packages/api-bindings-v1/src/lens/search.graphql deleted file mode 100644 index c0d63366cd..0000000000 --- a/packages/api-bindings-v1/src/lens/search.graphql +++ /dev/null @@ -1,51 +0,0 @@ -query SearchPublications( - $limit: LimitScalar - $cursor: Cursor - $query: Search! - $sources: [Sources!]! - $observerId: ProfileId - $mediaTransformPublicationSmall: MediaTransformParams = {} - $mediaTransformPublicationMedium: MediaTransformParams = {} - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: search( - request: { query: $query, type: PUBLICATION, limit: $limit, cursor: $cursor, sources: $sources } - ) { - ... on PublicationSearchResult { - __typename - items { - ... on Post { - ...Post - } - - ... on Comment { - ...Comment - } - } - pageInfo { - ...PaginatedResultInfo - } - } - } -} - -query SearchProfiles( - $limit: LimitScalar! - $cursor: Cursor - $query: Search! - $observerId: ProfileId - $sources: [Sources!]! - $mediaTransformProfileThumbnail: MediaTransformParams = {} -) { - result: search(request: { query: $query, type: PROFILE, limit: $limit, cursor: $cursor }) { - ... on ProfileSearchResult { - __typename - items { - ...Profile - } - pageInfo { - ...PaginatedResultInfo - } - } - } -} diff --git a/packages/api-bindings-v1/src/lens/snapshot.ts b/packages/api-bindings-v1/src/lens/snapshot.ts deleted file mode 100644 index 57a84a7c04..0000000000 --- a/packages/api-bindings-v1/src/lens/snapshot.ts +++ /dev/null @@ -1,197 +0,0 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -/** All built-in and custom scalars, mapped to their actual values */ -export type Scalars = { - ID: string; - String: string; - Boolean: boolean; - Int: number; - Float: number; - Any: unknown; -}; - -export type AliasWhere = { - address?: InputMaybe; - address_in?: InputMaybe>>; - alias?: InputMaybe; - alias_in?: InputMaybe>>; - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; -}; - -export type FollowWhere = { - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - follower?: InputMaybe; - follower_in?: InputMaybe>>; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; - space?: InputMaybe; - space_in?: InputMaybe>>; -}; - -export type MessageWhere = { - id?: InputMaybe; - id_in?: InputMaybe>>; - mci?: InputMaybe; - mci_gt?: InputMaybe; - mci_gte?: InputMaybe; - mci_in?: InputMaybe>>; - mci_lt?: InputMaybe; - mci_lte?: InputMaybe; - space?: InputMaybe; - space_in?: InputMaybe>>; - timestamp?: InputMaybe; - timestamp_gt?: InputMaybe; - timestamp_gte?: InputMaybe; - timestamp_in?: InputMaybe>>; - timestamp_lt?: InputMaybe; - timestamp_lte?: InputMaybe; - type?: InputMaybe; - type_in?: InputMaybe>>; -}; - -export enum OrderDirection { - Asc = 'asc', - Desc = 'desc', -} - -export type ProposalWhere = { - app?: InputMaybe; - app_in?: InputMaybe>>; - app_not?: InputMaybe; - app_not_in?: InputMaybe>>; - author?: InputMaybe; - author_in?: InputMaybe>>; - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - end?: InputMaybe; - end_gt?: InputMaybe; - end_gte?: InputMaybe; - end_in?: InputMaybe>>; - end_lt?: InputMaybe; - end_lte?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; - network?: InputMaybe; - network_in?: InputMaybe>>; - plugins_contains?: InputMaybe; - scores_state?: InputMaybe; - scores_state_in?: InputMaybe>>; - space?: InputMaybe; - space_in?: InputMaybe>>; - space_verified?: InputMaybe; - start?: InputMaybe; - start_gt?: InputMaybe; - start_gte?: InputMaybe; - start_in?: InputMaybe>>; - start_lt?: InputMaybe; - start_lte?: InputMaybe; - state?: InputMaybe; - strategies_contains?: InputMaybe; - title_contains?: InputMaybe; - type?: InputMaybe; - type_in?: InputMaybe>>; - validation?: InputMaybe; -}; - -export type RankingWhere = { - category?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - network?: InputMaybe; - search?: InputMaybe; -}; - -export type SpaceWhere = { - id?: InputMaybe; - id_in?: InputMaybe>>; -}; - -export type SubscriptionWhere = { - address?: InputMaybe; - address_in?: InputMaybe>>; - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; - space?: InputMaybe; - space_in?: InputMaybe>>; -}; - -export type UsersWhere = { - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; -}; - -export type VoteWhere = { - app?: InputMaybe; - app_in?: InputMaybe>>; - app_not?: InputMaybe; - app_not_in?: InputMaybe>>; - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; - proposal?: InputMaybe; - proposal_in?: InputMaybe>>; - reason?: InputMaybe; - reason_in?: InputMaybe>>; - reason_not?: InputMaybe; - reason_not_in?: InputMaybe>>; - space?: InputMaybe; - space_in?: InputMaybe>>; - voter?: InputMaybe; - voter_in?: InputMaybe>>; - vp?: InputMaybe; - vp_gt?: InputMaybe; - vp_gte?: InputMaybe; - vp_in?: InputMaybe>>; - vp_lt?: InputMaybe; - vp_lte?: InputMaybe; - vp_state?: InputMaybe; - vp_state_in?: InputMaybe>>; -}; diff --git a/packages/api-bindings-v1/src/lens/sources.ts b/packages/api-bindings-v1/src/lens/sources.ts deleted file mode 100644 index 6c088b80df..0000000000 --- a/packages/api-bindings-v1/src/lens/sources.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { AppId } from '@lens-protocol/domain/entities'; - -export type Sources = AppId[]; diff --git a/packages/api-bindings-v1/src/lens/transactions.graphql b/packages/api-bindings-v1/src/lens/transactions.graphql deleted file mode 100644 index c3836a8c6f..0000000000 --- a/packages/api-bindings-v1/src/lens/transactions.graphql +++ /dev/null @@ -1,71 +0,0 @@ -fragment RelayerResult on RelayerResult { - __typename - txHash - txId -} - -fragment RelayError on RelayError { - __typename - reason -} - -fragment BroadcastOnChainResult on RelayResult { - ... on RelayerResult { - ...RelayerResult - } - - ... on RelayError { - ...RelayError - } -} - -fragment DataAvailabilityPublicationResult on CreateDataAvailabilityPublicationResult { - __typename - id - dataAvailabilityId -} - -fragment BroadcastOffChainResult on BroadcastDataAvailabilityUnion { - ... on CreateDataAvailabilityPublicationResult { - ...DataAvailabilityPublicationResult - } - - ... on RelayError { - ...RelayError - } -} - -fragment TransactionIndexedResult on TransactionIndexedResult { - __typename - indexed - txHash -} - -fragment TransactionError on TransactionError { - __typename - reason -} - -query HasTxHashBeenIndexed($request: HasTxHashBeenIndexedRequest!) { - result: hasTxHashBeenIndexed(request: $request) { - ... on TransactionIndexedResult { - ...TransactionIndexedResult - } - - ... on TransactionError { - ...TransactionError - } - } -} - -mutation BroadcastOnChain($request: BroadcastRequest!) { - result: broadcast(request: $request) { - ...BroadcastOnChainResult - } -} - -mutation BroadcastOffChain($request: BroadcastRequest!) { - result: broadcastDataAvailability(request: $request) { - ...BroadcastOffChainResult - } -} diff --git a/packages/api-bindings-v1/src/lens/unfollow-typed-data.graphql b/packages/api-bindings-v1/src/lens/unfollow-typed-data.graphql deleted file mode 100644 index 37d22a2969..0000000000 --- a/packages/api-bindings-v1/src/lens/unfollow-typed-data.graphql +++ /dev/null @@ -1,22 +0,0 @@ -mutation CreateUnfollowTypedData($request: UnfollowRequest!) { - result: createUnfollowTypedData(request: $request) { - id - expiresAt - typedData { - types { - BurnWithSig { - name - type - } - } - domain { - ...EIP712TypedDataDomain - } - message: value { - nonce - deadline - tokenId - } - } - } -} diff --git a/packages/api-bindings-v1/src/lens/utils/__tests__/isValidHandle.spec.ts b/packages/api-bindings-v1/src/lens/utils/__tests__/isValidHandle.spec.ts deleted file mode 100644 index 535a726845..0000000000 --- a/packages/api-bindings-v1/src/lens/utils/__tests__/isValidHandle.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { faker } from '@faker-js/faker'; - -import { isValidHandle } from '../isValidHandle'; - -describe(`Given the ${isValidHandle.name} predicate`, () => { - describe('when called with a prospect Lens handle', () => { - it('should return true with valid string', () => { - expect(isValidHandle('valid')).toBe(true); - }); - - it('should return false if below 5 characters', () => { - expect(isValidHandle('less')).toBe(false); - }); - - it('should return false if above 26 characters', () => { - expect(isValidHandle(faker.datatype.string(27))).toBe(false); - }); - - it('should return false if with invalid characters', () => { - expect(isValidHandle('invalid!')).toBe(false); - }); - - it('should return false if starts with "_"', () => { - expect(isValidHandle('_invalid')).toBe(false); - }); - }); -}); diff --git a/packages/api-bindings-v1/src/lens/utils/__tests__/publication.spec.ts b/packages/api-bindings-v1/src/lens/utils/__tests__/publication.spec.ts deleted file mode 100644 index be4ebefbb3..0000000000 --- a/packages/api-bindings-v1/src/lens/utils/__tests__/publication.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { CollectPolicyType } from '@lens-protocol/domain/use-cases/publications'; - -import { CollectState } from '../../CollectPolicy'; -import { - mockNotYetKnownCollectModuleSettings, - mockPublicationStatsFragment, -} from '../../__helpers__'; -import { resolveCollectPolicy } from '../publication'; - -describe(`Given the ${resolveCollectPolicy.name} function'`, () => { - describe('when called with not yet known/supported collect module', () => { - it('should return "NO_COLLECT"', () => { - expect( - resolveCollectPolicy({ - collectModule: mockNotYetKnownCollectModuleSettings(), - isAuthorFollowedByMe: false, - publicationStats: mockPublicationStatsFragment(), - collectNftAddress: null, - }), - ).toEqual({ - type: CollectPolicyType.NO_COLLECT, - state: CollectState.CANNOT_BE_COLLECTED, - }); - }); - }); -}); diff --git a/packages/api-bindings-v1/src/lens/utils/amount.ts b/packages/api-bindings-v1/src/lens/utils/amount.ts deleted file mode 100644 index f2a5ddb109..0000000000 --- a/packages/api-bindings-v1/src/lens/utils/amount.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Amount, ChainType, Erc20, erc20, Erc20Amount } from '@lens-protocol/shared-kernel'; - -import { Erc20AmountFields, ModuleFeeAmount, ModuleFeeAmountParams } from '../generated'; - -export function erc20Amount({ from }: { from: Erc20AmountFields | ModuleFeeAmount }): Erc20Amount { - const asset = erc20({ chainType: ChainType.POLYGON, ...from.asset }); - return Amount.erc20(asset, from.value); -} - -export function moduleFeeAmountParams({ from }: { from: Amount }): ModuleFeeAmountParams { - return { - currency: from.asset.address, - value: from.toFixed(), - }; -} diff --git a/packages/api-bindings-v1/src/lens/utils/index.ts b/packages/api-bindings-v1/src/lens/utils/index.ts deleted file mode 100644 index 857ac95240..0000000000 --- a/packages/api-bindings-v1/src/lens/utils/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -// generic utils -export * from './amount'; -export * from './isValidHandle'; -export * from './omitTypename'; -export * from './profile'; -export * from './publication'; -export * from './types'; diff --git a/packages/api-bindings-v1/src/lens/utils/isValidHandle.ts b/packages/api-bindings-v1/src/lens/utils/isValidHandle.ts deleted file mode 100644 index 8e13564033..0000000000 --- a/packages/api-bindings-v1/src/lens/utils/isValidHandle.ts +++ /dev/null @@ -1,8 +0,0 @@ -const validationRegex = /^[a-z](?:[a-z0-9_]{4,25})$/; - -/** - * @group Helpers - */ -export function isValidHandle(handle: string): boolean { - return validationRegex.test(handle); -} diff --git a/packages/api-bindings-v1/src/lens/utils/omitTypename.ts b/packages/api-bindings-v1/src/lens/utils/omitTypename.ts deleted file mode 100644 index 275bf9699f..0000000000 --- a/packages/api-bindings-v1/src/lens/utils/omitTypename.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { DeepOmit, omitDeep } from '@lens-protocol/shared-kernel'; - -export function omitTypename(target: unknown) { - return omitDeep(target, '__typename'); -} - -export type OmitTypename = Omit; - -export type DeepOmitTypename = DeepOmit; diff --git a/packages/api-bindings-v1/src/lens/utils/profile.ts b/packages/api-bindings-v1/src/lens/utils/profile.ts deleted file mode 100644 index eadbe91453..0000000000 --- a/packages/api-bindings-v1/src/lens/utils/profile.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Overwrite } from '@lens-protocol/shared-kernel'; - -import { Profile, ProfileFields } from '../generated'; - -export type ProfileOwnedByMe = Overwrite; - -/** - * @group Helpers - */ -export function isProfileOwnedByMe( - profile: ProfileFields, -): profile is ProfileOwnedByMe { - return profile.ownedByMe; -} - -export type FollowModule = NonNullable; - -export type ProfilePictureMedia = NonNullable; -export type ProfileCoverMedia = NonNullable; diff --git a/packages/api-bindings-v1/src/lens/utils/publication.ts b/packages/api-bindings-v1/src/lens/utils/publication.ts deleted file mode 100644 index 7f9d81ff2d..0000000000 --- a/packages/api-bindings-v1/src/lens/utils/publication.ts +++ /dev/null @@ -1,532 +0,0 @@ -import { PublicationId, TransactionKind } from '@lens-protocol/domain/entities'; -import { - CollectPolicyType, - CollectRequest, - CollectType, -} from '@lens-protocol/domain/use-cases/publications'; -import { DateUtils, never, Overwrite, Prettify } from '@lens-protocol/shared-kernel'; - -import { - AaveFeeCollectPolicy, - CollectState, - FeeCollectPolicy, - LimitedFeeCollectPolicy, - LimitedTimedFeeCollectPolicy, - MultirecipientFeeCollectPolicy, - NoCollectPolicy, - NoFeeCollectPolicy, - TimedFeeCollectPolicy, - VaultFeeCollectPolicy, -} from '../CollectPolicy'; -import { ContentInsightType, SnapshotPoll } from '../ContentInsight'; -import { - AaveFeeCollectModuleSettings, - Comment, - Erc4626FeeCollectModuleSettings, - FeeCollectModuleSettings, - FreeCollectModuleSettings, - LimitedFeeCollectModuleSettings, - LimitedTimedFeeCollectModuleSettings, - Mirror, - MultirecipientFeeCollectModuleSettings, - Post, - PublicationStats, - SimpleCollectModuleSettings, - TimedFeeCollectModuleSettings, -} from '../generated'; -import { erc20Amount } from './amount'; -import { isProfileOwnedByMe, ProfileOwnedByMe } from './profile'; -import { PickByTypename, Typename } from './types'; - -export type CollectModule = ContentPublication['collectModule']; - -export type ReferenceModule = NonNullable; - -/** - * @group Helpers - */ -export function isPostPublication>( - publication: T, -): publication is PickByTypename { - return publication.__typename === 'Post'; -} - -/** - * @group Helpers - */ -export function isCommentPublication>( - publication: T, -): publication is PickByTypename { - return publication.__typename === 'Comment'; -} - -/** - * @group Helpers - */ -export function isMirrorPublication>( - publication: T, -): publication is PickByTypename { - return publication.__typename === 'Mirror'; -} - -/** - * @internal - */ -export function isDataAvailabilityPublicationId(publicationId: PublicationId): boolean { - return publicationId.includes('-DA-'); -} - -/** - * Any publication regardless of its type, or capabilities - */ -export type AnyPublication = Comment | Mirror | Post; - -/** - * Any publication that can be referenced other via a comment or mirror - */ -export type ContentPublication = Comment | Post; - -/** - * @internal - */ -export type Gated = Overwrite< - T, - { - isGated: true; - metadata: Overwrite< - T['metadata'], - { - encryptionParams: NonNullable; - } - >; - } ->; - -/** - * An encrypted comment - */ -export type GatedComment = Prettify>; - -/** - * An encrypted post - */ -export type GatedPost = Prettify>; - -/** - * An encrypted publication - */ -export type GatedPublication = GatedComment | GatedPost; - -/** - * @internal - */ -export type Collectable = Overwrite< - T, - { - collectPolicy: - | FeeCollectPolicy - | NoFeeCollectPolicy - | LimitedFeeCollectPolicy - | TimedFeeCollectPolicy - | LimitedTimedFeeCollectPolicy - | MultirecipientFeeCollectPolicy - | VaultFeeCollectPolicy - | AaveFeeCollectPolicy; - - collectModule: - | AaveFeeCollectModuleSettings - | Erc4626FeeCollectModuleSettings - | FeeCollectModuleSettings - | FreeCollectModuleSettings - | LimitedFeeCollectModuleSettings - | LimitedTimedFeeCollectModuleSettings - | MultirecipientFeeCollectModuleSettings - | TimedFeeCollectModuleSettings; - } ->; - -/** - * A collectable comment - */ -export type CollectableComment = Prettify>; - -/** - * A collectable mirror (i.e. a mirror of a collectable comment or post) - */ -export type CollectableMirror = Prettify>; - -/** - * A collectable post - */ -export type CollectablePost = Prettify>; - -/** - * A collectable publication - * - * It can be a comment, mirror or post - */ -export type CollectablePublication = CollectableComment | CollectableMirror | CollectablePost; - -/** - * @group Helpers - */ -export function isGatedPublication( - publication: ContentPublication, -): publication is GatedPublication { - return publication.isGated; -} - -/** - * @internal - */ -export type Poll = Overwrite< - T, - { - contentInsight: SnapshotPoll; - } ->; - -/** - * A publication with a poll in its content - * - * **Pro-tip**: use {@link isPollPublication} to check if the publication contains a poll. - */ -export type PollPublication = Prettify>; - -/** - * @group Helpers - */ -export function isPollPublication(publication: AnyPublication): publication is PollPublication { - return ( - isContentPublication(publication) && - publication.contentInsight.type === ContentInsightType.SNAPSHOT_POLL - ); -} - -/** - * @group Helpers - */ -export function isContentPublication( - publication: AnyPublication, -): publication is ContentPublication { - return isPostPublication(publication) || isCommentPublication(publication); -} - -export type PublicationOwnedByMe = Overwrite; - -/** - * @group Helpers - */ -export function isPublicationOwnedByMe( - publication: AnyPublication, -): publication is PublicationOwnedByMe { - return isProfileOwnedByMe(publication.profile); -} - -export function createCollectRequest( - publication: AnyPublication, - collector: ProfileOwnedByMe, -): CollectRequest { - const collectModule: CollectModule = - publication.__typename === 'Mirror' - ? publication.mirrorOf.collectModule - : publication.collectModule; - - switch (collectModule.__typename) { - case 'SimpleCollectModuleSettings': - if (collectModule.feeOptional) { - return { - profileId: collector.id, - kind: TransactionKind.COLLECT_PUBLICATION, - publicationId: publication.id, - type: CollectType.PAID, - fee: { - amount: erc20Amount({ from: collectModule.feeOptional.amount }), - contractAddress: collectModule.contractAddress, - }, - }; - } - return { - profileId: collector.id, - kind: TransactionKind.COLLECT_PUBLICATION, - publicationId: publication.id, - followerOnly: collectModule.followerOnly, - type: CollectType.FREE, - }; - case 'FreeCollectModuleSettings': - return { - profileId: collector.id, - kind: TransactionKind.COLLECT_PUBLICATION, - publicationId: publication.id, - followerOnly: collectModule.followerOnly, - type: CollectType.FREE, - }; - case 'FeeCollectModuleSettings': - case 'LimitedFeeCollectModuleSettings': - case 'TimedFeeCollectModuleSettings': - case 'LimitedTimedFeeCollectModuleSettings': - return { - profileId: collector.id, - kind: TransactionKind.COLLECT_PUBLICATION, - publicationId: publication.id, - type: CollectType.PAID, - fee: { - amount: erc20Amount({ from: collectModule.amount }), - contractAddress: collectModule.contractAddress, - }, - }; - case 'MultirecipientFeeCollectModuleSettings': - case 'ERC4626FeeCollectModuleSettings': - case 'AaveFeeCollectModuleSettings': - return { - profileId: collector.id, - kind: TransactionKind.COLLECT_PUBLICATION, - publicationId: publication.id, - type: CollectType.PAID, - fee: { - amount: erc20Amount({ from: collectModule.amount }), - contractAddress: collectModule.contractAddress, - }, - }; - case 'RevertCollectModuleSettings': - case 'UnknownCollectModuleSettings': - never( - `Cannot collect publication (${publication.id}) with "${ - collectModule.__typename as string - }" collect module`, - ); - } -} - -function resolveTimeLimitReached( - collectModule: LimitedTimedFeeCollectModuleSettings | TimedFeeCollectModuleSettings, -) { - if (DateUtils.unix() > DateUtils.toUnix(collectModule.endTimestamp)) { - return CollectState.COLLECT_TIME_EXPIRED; - } - return null; -} - -function resolveOptionalTimeLimitReached( - collectModule: - | MultirecipientFeeCollectModuleSettings - | Erc4626FeeCollectModuleSettings - | AaveFeeCollectModuleSettings - | SimpleCollectModuleSettings, -) { - if ( - collectModule.endTimestampOptional && - DateUtils.unix() > DateUtils.toUnix(collectModule.endTimestampOptional) - ) { - return CollectState.COLLECT_TIME_EXPIRED; - } - return null; -} - -function resolveLimitReached( - collectModule: LimitedFeeCollectModuleSettings | LimitedTimedFeeCollectModuleSettings, - publicationStats: PublicationStats, -) { - if (publicationStats.totalAmountOfCollects >= parseInt(collectModule.collectLimit)) { - return CollectState.COLLECT_LIMIT_REACHED; - } - - return null; -} - -function resolveOptionalLimitReached( - collectModule: - | MultirecipientFeeCollectModuleSettings - | Erc4626FeeCollectModuleSettings - | AaveFeeCollectModuleSettings - | SimpleCollectModuleSettings, - publicationStats: PublicationStats, -) { - if ( - collectModule.collectLimitOptional && - publicationStats.totalAmountOfCollects >= parseInt(collectModule.collectLimitOptional) - ) { - return CollectState.COLLECT_LIMIT_REACHED; - } - - return null; -} - -export type CollectableCollectModuleSettings = - | FreeCollectModuleSettings - | FeeCollectModuleSettings - | LimitedFeeCollectModuleSettings - | TimedFeeCollectModuleSettings - | LimitedTimedFeeCollectModuleSettings - | MultirecipientFeeCollectModuleSettings - | Erc4626FeeCollectModuleSettings - | AaveFeeCollectModuleSettings - | SimpleCollectModuleSettings; - -function resolveNotFollower( - collectModule: CollectableCollectModuleSettings, - isAuthorFollowedByMe: boolean, -) { - if (collectModule.followerOnly && !isAuthorFollowedByMe) { - return CollectState.NOT_A_FOLLOWER; - } - return null; -} - -export function resolveCollectPolicy({ - collectModule, - isAuthorFollowedByMe, - publicationStats, - collectNftAddress, -}: { - collectModule: CollectModule; - isAuthorFollowedByMe: boolean; - publicationStats: PublicationStats; - collectNftAddress: string | null; -}): - | FeeCollectPolicy - | NoFeeCollectPolicy - | MultirecipientFeeCollectPolicy - | VaultFeeCollectPolicy - | AaveFeeCollectPolicy - | NoCollectPolicy { - switch (collectModule.__typename) { - case 'SimpleCollectModuleSettings': { - if (collectModule.feeOptional) { - return { - type: CollectPolicyType.CHARGE, - state: - resolveNotFollower(collectModule, isAuthorFollowedByMe) ?? - resolveOptionalLimitReached(collectModule, publicationStats) ?? - resolveOptionalTimeLimitReached(collectModule) ?? - CollectState.CAN_BE_COLLECTED, - amount: erc20Amount({ from: collectModule.feeOptional.amount }), - collectLimit: collectModule.collectLimitOptional - ? parseInt(collectModule.collectLimitOptional) - : null, - collectNftAddress, - contractAddress: collectModule.contractAddress, - endTimestamp: collectModule.endTimestampOptional, - followerOnly: collectModule.followerOnly, - referralFee: collectModule.feeOptional.referralFee, - }; - } - return { - type: CollectPolicyType.FREE, - state: - resolveNotFollower(collectModule, isAuthorFollowedByMe) ?? - resolveOptionalLimitReached(collectModule, publicationStats) ?? - resolveOptionalTimeLimitReached(collectModule) ?? - CollectState.CAN_BE_COLLECTED, - contractAddress: collectModule.contractAddress, - collectLimit: collectModule.collectLimitOptional - ? parseInt(collectModule.collectLimitOptional) - : null, - collectNftAddress, - endTimestamp: collectModule.endTimestampOptional, - followerOnly: collectModule.followerOnly, - }; - } - case 'FeeCollectModuleSettings': - return { - type: CollectPolicyType.CHARGE, - state: - resolveNotFollower(collectModule, isAuthorFollowedByMe) ?? CollectState.CAN_BE_COLLECTED, - - amount: erc20Amount({ from: collectModule.amount }), - collectLimit: null, - collectNftAddress, - contractAddress: collectModule.contractAddress, - endTimestamp: null, - followerOnly: collectModule.followerOnly, - referralFee: collectModule.referralFee, - }; - case 'LimitedFeeCollectModuleSettings': - return { - type: CollectPolicyType.CHARGE, - state: - resolveNotFollower(collectModule, isAuthorFollowedByMe) ?? - resolveLimitReached(collectModule, publicationStats) ?? - CollectState.CAN_BE_COLLECTED, - amount: erc20Amount({ from: collectModule.amount }), - collectLimit: parseInt(collectModule.collectLimit), - collectNftAddress, - contractAddress: collectModule.contractAddress, - endTimestamp: null, - followerOnly: collectModule.followerOnly, - referralFee: collectModule.referralFee, - }; - case 'TimedFeeCollectModuleSettings': - return { - type: CollectPolicyType.CHARGE, - state: - resolveNotFollower(collectModule, isAuthorFollowedByMe) ?? - resolveTimeLimitReached(collectModule) ?? - CollectState.CAN_BE_COLLECTED, - amount: erc20Amount({ from: collectModule.amount }), - collectLimit: null, - collectNftAddress, - contractAddress: collectModule.contractAddress, - endTimestamp: collectModule.endTimestamp, - followerOnly: collectModule.followerOnly, - referralFee: collectModule.referralFee, - }; - case 'LimitedTimedFeeCollectModuleSettings': - return { - type: CollectPolicyType.CHARGE, - state: - resolveNotFollower(collectModule, isAuthorFollowedByMe) ?? - resolveLimitReached(collectModule, publicationStats) ?? - resolveTimeLimitReached(collectModule) ?? - CollectState.CAN_BE_COLLECTED, - amount: erc20Amount({ from: collectModule.amount }), - referralFee: collectModule.referralFee, - collectLimit: parseInt(collectModule.collectLimit), - endTimestamp: collectModule.endTimestamp, - followerOnly: collectModule.followerOnly, - collectNftAddress, - contractAddress: collectModule.contractAddress, - }; - case 'FreeCollectModuleSettings': - return { - type: CollectPolicyType.FREE, - state: - resolveNotFollower(collectModule, isAuthorFollowedByMe) ?? CollectState.CAN_BE_COLLECTED, - collectLimit: null, - collectNftAddress, - contractAddress: collectModule.contractAddress, - endTimestamp: null, - followerOnly: collectModule.followerOnly, - }; - case 'MultirecipientFeeCollectModuleSettings': - case 'ERC4626FeeCollectModuleSettings': - case 'AaveFeeCollectModuleSettings': - return { - type: CollectPolicyType.CHARGE, - state: - resolveNotFollower(collectModule, isAuthorFollowedByMe) ?? - resolveOptionalLimitReached(collectModule, publicationStats) ?? - resolveOptionalTimeLimitReached(collectModule) ?? - CollectState.CAN_BE_COLLECTED, - amount: erc20Amount({ from: collectModule.amount }), - referralFee: collectModule.referralFee, - collectLimit: collectModule.collectLimitOptional - ? parseInt(collectModule.collectLimitOptional) - : null, - endTimestamp: collectModule.endTimestampOptional, - followerOnly: collectModule.followerOnly, - collectNftAddress, - contractAddress: collectModule.contractAddress, - }; - case 'RevertCollectModuleSettings': - case 'UnknownCollectModuleSettings': - // Important: at any time backend can introduce new collect module - // that older sdk version does not know about - // eslint-disable-next-line no-fallthrough - default: - return { - type: CollectPolicyType.NO_COLLECT, - state: CollectState.CANNOT_BE_COLLECTED, - }; - } -} diff --git a/packages/api-bindings-v1/src/lens/utils/types.ts b/packages/api-bindings-v1/src/lens/utils/types.ts deleted file mode 100644 index 721a94f6c6..0000000000 --- a/packages/api-bindings-v1/src/lens/utils/types.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @internal - */ -export type Typename = { [key in '__typename']: T }; - -/** - * @internal - */ -export type JustTypename> = Pick; - -/** - * @internal - */ -export type PickByTypename, P extends T['__typename']> = T extends { - __typename?: P; -} - ? T - : never; diff --git a/packages/api-bindings-v1/src/metadata.ts b/packages/api-bindings-v1/src/metadata.ts deleted file mode 100644 index 3428878739..0000000000 --- a/packages/api-bindings-v1/src/metadata.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { DeepOmit, Overwrite, Prettify } from '@lens-protocol/shared-kernel'; - -import type { - DeepOmitTypename, - EncryptionParamsOutput, - Erc20OwnershipOutput, - LeafConditionOutput, - PublicationMetadataV2Input, -} from './lens'; - -export type PublicationMetadata = Prettify< - Overwrite ->; - -type OneOf = Omit & - { - [k in K]: Pick, k> & { - [k1 in Exclude]?: null; - }; - }[K]; - -type NonNullableFields = { - [P in keyof T]: NonNullable; -}; - -type PatchLeafConditionOutput = Overwrite< - LeafConditionOutput, - { - token: Omit | null; - } ->; - -export type LeafCondition = Prettify< - OneOf>> ->; - -export type OrCondition = { - or: { - criteria: T[]; - }; -}; - -export type AndCondition = { - and: { - criteria: T[]; - }; -}; - -export type AnyCondition = LeafCondition | OrCondition | AndCondition; - -export type AccessCondition = OrCondition; - -export type EncryptedFields = Pick< - PublicationMetadata, - 'animation_url' | 'content' | 'external_url' | 'image' | 'media' ->; - -type EncryptionParams = Prettify< - Overwrite< - DeepOmit, - { - accessCondition: AccessCondition; - encryptedFields: EncryptedFields; - } - > ->; - -export type GatedPublicationMetadata = Prettify< - Overwrite< - PublicationMetadata, - { - encryptionParams: EncryptionParams; - } - > ->; - -export type ProfileMetadataAttribute = { - displayType?: string | null; - key: string; - traitType?: string; - value: string; -}; - -export type ProfileMetadata = { - version: '1.0.0'; - metadata_id: string; - attributes: ProfileMetadataAttribute[]; - bio: string | null; - cover_picture: string | null; - name: string; -}; diff --git a/packages/api-bindings-v1/src/mocks.ts b/packages/api-bindings-v1/src/mocks.ts deleted file mode 100644 index f3f91ad4f9..0000000000 --- a/packages/api-bindings-v1/src/mocks.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './__helpers__/mocks'; -export * from './apollo/__helpers__/mocks'; -export * from './apollo/cache/__helpers__/mocks'; -export * from './apollo/cache/utils/__helpers__/mocks'; -export * from './lens/__helpers__'; -export * from './snapshot/__helpers__'; diff --git a/packages/api-bindings-v1/src/snapshot/__helpers__/fragments.ts b/packages/api-bindings-v1/src/snapshot/__helpers__/fragments.ts deleted file mode 100644 index ddc7624e51..0000000000 --- a/packages/api-bindings-v1/src/snapshot/__helpers__/fragments.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { Url } from '@lens-protocol/shared-kernel'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; - -import { SnapshotProposalId, SnapshotSpaceId } from '../../lens'; -import { SnapshotProposal } from '../generated'; - -export function mockSnapshotSpaceId(): SnapshotSpaceId { - return faker.internet.domainName() as SnapshotSpaceId; -} - -export function mockSnapshotProposalId(): SnapshotProposalId { - return faker.datatype.hexadecimal() as SnapshotProposalId; -} - -export function mockSnapshotPollUrl({ - baseUrl = 'https://snapshot.org', - spaceId = mockSnapshotSpaceId(), - proposalId = mockSnapshotProposalId(), -}: { - baseUrl?: Url; - spaceId?: SnapshotSpaceId; - proposalId?: SnapshotProposalId; -} = {}) { - return `${baseUrl}/#/${spaceId}/proposal/${proposalId}`; -} - -export function mockSnapshotProposal(overrides?: Partial): SnapshotProposal { - return { - id: mockSnapshotProposalId(), - author: mockEthereumAddress(), - state: 'active', - title: faker.lorem.sentence(), - choices: ['yes', 'no'], - scores: [1, 0], - scores_total: 1, - snapshot: '1234567890', - symbol: 'BRA', - privacy: '', - network: '1', - type: 'single-choice', - start: faker.date.past().getTime(), - end: faker.date.future().getTime(), - quorum: 1, - space: { - id: faker.internet.domainName(), - name: faker.commerce.productName(), - }, - strategies: [], - flagged: null, - ...overrides, - __typename: 'Proposal', - }; -} diff --git a/packages/api-bindings-v1/src/snapshot/__helpers__/index.ts b/packages/api-bindings-v1/src/snapshot/__helpers__/index.ts deleted file mode 100644 index dd72ac6535..0000000000 --- a/packages/api-bindings-v1/src/snapshot/__helpers__/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './fragments'; -export * from './queries'; diff --git a/packages/api-bindings-v1/src/snapshot/__helpers__/queries.ts b/packages/api-bindings-v1/src/snapshot/__helpers__/queries.ts deleted file mode 100644 index 76838b0721..0000000000 --- a/packages/api-bindings-v1/src/snapshot/__helpers__/queries.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; - -import { - GetSnapshotProposalData, - GetSnapshotProposalDocument, - SnapshotProposal, -} from '../generated'; - -export function mockGetSnapshotProposalDataResponse({ - proposal, -}: { - proposal: SnapshotProposal; -}): MockedResponse { - return { - request: { - query: GetSnapshotProposalDocument, - variables: { - proposalId: proposal.id, - spaceId: proposal.space?.id, - includeVotes: false, - voterAddress: '0x000', - }, - }, - result: { - data: { - proposal, - }, - }, - }; -} diff --git a/packages/api-bindings-v1/src/snapshot/generated.ts b/packages/api-bindings-v1/src/snapshot/generated.ts deleted file mode 100644 index d8711a8b1d..0000000000 --- a/packages/api-bindings-v1/src/snapshot/generated.ts +++ /dev/null @@ -1,370 +0,0 @@ -/** Code generated. DO NOT EDIT. */ -/* eslint-disable import/no-default-export */ -/* eslint-disable no-restricted-imports */ -import * as Apollo from '@apollo/client'; -import gql from 'graphql-tag'; -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -const defaultOptions = {} as const; -/** All built-in and custom scalars, mapped to their actual values */ -export type Scalars = { - ID: string; - String: string; - Boolean: boolean; - Int: number; - Float: number; - Any: unknown; -}; - -export type AliasWhere = { - address?: InputMaybe; - address_in?: InputMaybe>>; - alias?: InputMaybe; - alias_in?: InputMaybe>>; - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; -}; - -export type FollowWhere = { - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - follower?: InputMaybe; - follower_in?: InputMaybe>>; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; - space?: InputMaybe; - space_in?: InputMaybe>>; -}; - -export type MessageWhere = { - id?: InputMaybe; - id_in?: InputMaybe>>; - mci?: InputMaybe; - mci_gt?: InputMaybe; - mci_gte?: InputMaybe; - mci_in?: InputMaybe>>; - mci_lt?: InputMaybe; - mci_lte?: InputMaybe; - space?: InputMaybe; - space_in?: InputMaybe>>; - timestamp?: InputMaybe; - timestamp_gt?: InputMaybe; - timestamp_gte?: InputMaybe; - timestamp_in?: InputMaybe>>; - timestamp_lt?: InputMaybe; - timestamp_lte?: InputMaybe; - type?: InputMaybe; - type_in?: InputMaybe>>; -}; - -export enum OrderDirection { - Asc = 'asc', - Desc = 'desc', -} - -export type ProposalWhere = { - app?: InputMaybe; - app_in?: InputMaybe>>; - app_not?: InputMaybe; - app_not_in?: InputMaybe>>; - author?: InputMaybe; - author_in?: InputMaybe>>; - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - end?: InputMaybe; - end_gt?: InputMaybe; - end_gte?: InputMaybe; - end_in?: InputMaybe>>; - end_lt?: InputMaybe; - end_lte?: InputMaybe; - flagged?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; - network?: InputMaybe; - network_in?: InputMaybe>>; - plugins_contains?: InputMaybe; - scores_state?: InputMaybe; - scores_state_in?: InputMaybe>>; - space?: InputMaybe; - space_in?: InputMaybe>>; - space_verified?: InputMaybe; - start?: InputMaybe; - start_gt?: InputMaybe; - start_gte?: InputMaybe; - start_in?: InputMaybe>>; - start_lt?: InputMaybe; - start_lte?: InputMaybe; - state?: InputMaybe; - strategies_contains?: InputMaybe; - title_contains?: InputMaybe; - type?: InputMaybe; - type_in?: InputMaybe>>; - validation?: InputMaybe; -}; - -export type RankingWhere = { - category?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - network?: InputMaybe; - search?: InputMaybe; -}; - -export type SpaceWhere = { - id?: InputMaybe; - id_in?: InputMaybe>>; -}; - -export type StatementsWhere = { - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - delegate?: InputMaybe; - delegate_in?: InputMaybe>>; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; - space?: InputMaybe; - space_in?: InputMaybe>>; -}; - -export type SubscriptionWhere = { - address?: InputMaybe; - address_in?: InputMaybe>>; - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; - space?: InputMaybe; - space_in?: InputMaybe>>; -}; - -export type UsersWhere = { - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; -}; - -export type VoteWhere = { - app?: InputMaybe; - app_in?: InputMaybe>>; - app_not?: InputMaybe; - app_not_in?: InputMaybe>>; - created?: InputMaybe; - created_gt?: InputMaybe; - created_gte?: InputMaybe; - created_in?: InputMaybe>>; - created_lt?: InputMaybe; - created_lte?: InputMaybe; - id?: InputMaybe; - id_in?: InputMaybe>>; - ipfs?: InputMaybe; - ipfs_in?: InputMaybe>>; - proposal?: InputMaybe; - proposal_in?: InputMaybe>>; - reason?: InputMaybe; - reason_in?: InputMaybe>>; - reason_not?: InputMaybe; - reason_not_in?: InputMaybe>>; - space?: InputMaybe; - space_in?: InputMaybe>>; - voter?: InputMaybe; - voter_in?: InputMaybe>>; - vp?: InputMaybe; - vp_gt?: InputMaybe; - vp_gte?: InputMaybe; - vp_in?: InputMaybe>>; - vp_lt?: InputMaybe; - vp_lte?: InputMaybe; - vp_state?: InputMaybe; - vp_state_in?: InputMaybe>>; -}; - -export type SnapshotProposal = { - __typename: 'Proposal'; - id: string; - author: string; - state: string | null; - title: string; - choices: Array; - scores: Array | null; - scores_total: number | null; - snapshot: string | null; - symbol: string; - network: string; - type: string | null; - privacy: string | null; - start: number; - end: number; - quorum: number; - flagged: boolean | null; - space: { id: string; name: string | null } | null; - strategies: Array<{ network: string | null; name: string; params: unknown | null } | null>; -}; - -export type SnapshotVote = { __typename: 'Vote'; choice: unknown }; - -export type SnapshotVotePower = { __typename: 'Vp'; value: number | null }; - -export type GetSnapshotProposalVariables = Exact<{ - spaceId: Scalars['String']; - proposalId: Scalars['String']; - voterAddress: Scalars['String']; - includeVotes: Scalars['Boolean']; -}>; - -export type GetSnapshotProposalData = { - proposal: SnapshotProposal | null; - votes?: Array | null; - vp?: SnapshotVotePower | null; -}; - -export const FragmentSnapshotProposal = /*#__PURE__*/ gql` - fragment SnapshotProposal on Proposal { - __typename - id - author - state - title - choices - scores - scores_total - snapshot - symbol - network - type - privacy - start - end - quorum - space { - id - name - } - strategies { - network - name - params - } - flagged - } -`; -export const FragmentSnapshotVote = /*#__PURE__*/ gql` - fragment SnapshotVote on Vote { - __typename - choice - } -`; -export const FragmentSnapshotVotePower = /*#__PURE__*/ gql` - fragment SnapshotVotePower on Vp { - __typename - value: vp - } -`; -export const GetSnapshotProposalDocument = /*#__PURE__*/ gql` - query GetSnapshotProposal( - $spaceId: String! - $proposalId: String! - $voterAddress: String! - $includeVotes: Boolean! - ) { - proposal(id: $proposalId) { - ...SnapshotProposal - } - votes(where: { proposal: $proposalId, voter: $voterAddress }) @include(if: $includeVotes) { - ...SnapshotVote - } - vp(voter: $voterAddress, space: $spaceId, proposal: $proposalId) @include(if: $includeVotes) { - ...SnapshotVotePower - } - } - ${FragmentSnapshotProposal} - ${FragmentSnapshotVote} - ${FragmentSnapshotVotePower} -`; - -/** - * __useGetSnapshotProposal__ - * - * To run a query within a React component, call `useGetSnapshotProposal` and pass it any options that fit your needs. - * When your component renders, `useGetSnapshotProposal` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useGetSnapshotProposal({ - * variables: { - * spaceId: // value for 'spaceId' - * proposalId: // value for 'proposalId' - * voterAddress: // value for 'voterAddress' - * includeVotes: // value for 'includeVotes' - * }, - * }); - */ -export function useGetSnapshotProposal( - baseOptions: Apollo.QueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useQuery( - GetSnapshotProposalDocument, - options, - ); -} -export function useGetSnapshotProposalLazyQuery( - baseOptions?: Apollo.LazyQueryHookOptions, -) { - const options = { ...defaultOptions, ...baseOptions }; - return Apollo.useLazyQuery( - GetSnapshotProposalDocument, - options, - ); -} -export type GetSnapshotProposalHookResult = ReturnType; -export type GetSnapshotProposalLazyQueryHookResult = ReturnType< - typeof useGetSnapshotProposalLazyQuery ->; -export type GetSnapshotProposalQueryResult = Apollo.QueryResult< - GetSnapshotProposalData, - GetSnapshotProposalVariables ->; diff --git a/packages/api-bindings-v1/src/snapshot/index.ts b/packages/api-bindings-v1/src/snapshot/index.ts deleted file mode 100644 index 3c93eac798..0000000000 --- a/packages/api-bindings-v1/src/snapshot/index.ts +++ /dev/null @@ -1,52 +0,0 @@ -export * from './generated'; - -/** - * @experimental - */ -export enum SnapshotVotingSystem { - /** - * Each user can select only one option. - * - * The results will reflect these votes as percentages of the total voting power of all voting participants cast on the specific choice. - */ - SINGLE_CHOICE = 'single-choice', - /** - * Each user can select (approve) any number of choices. - * - * Each selected choice will receive equal voting power - * i.e. if user selects two choices, each choice will receive the total voting power of the user. - */ - APPROVAL = 'approval', - /** - * Each user can spread voting power across any number of choices. - * - * The results are calculated quadratically, thanks to which the **number of individual voters** matters more than the sum of voting power contributed. - */ - QUADRATIC = 'quadratic', - /** - * Each user has to rank all choices in a desired order. - * - * In the **first step** votes are counted for each voter's number one choice. - * If a choice receives more than 50% votes (cast on number one choices of each user), that choice wins. - * The result will show the percentages reflecting how users voted for their **first choice only**. - * - * In the **second step** if the first-choice candidate doesn't get over 50% of the total votes the choice with the **fewest** number one votes is **eliminated**. - * Voters who had chosen the defeated choice as number one now have their number two choice **counted as their number one** choice. - * - * The process continues over multiple rounds until a choice has more than half (\> 50%) of the total votes. - */ - RANKED_CHOICE = 'ranked-choice', - /** - * Each user can spread their voting power across any number of choices, from one to all. - * - * Their voting power will be divided between their chosen options according to how much - * weight they attribute to each option by increasing or decreasing the voting power fraction. - */ - WEIGHTED = 'weighted', - /** - * Each user can select one of three options: `For`, `Against`, `Abstain`. - * - * The votes cast on the `Abstain` choice are counted in calculating if the necessary quorum has been reached for a proposal to pass. - */ - BASIC = 'basic', -} diff --git a/packages/api-bindings-v1/src/snapshot/proposals.graphql b/packages/api-bindings-v1/src/snapshot/proposals.graphql deleted file mode 100644 index 27cd9cccd0..0000000000 --- a/packages/api-bindings-v1/src/snapshot/proposals.graphql +++ /dev/null @@ -1,57 +0,0 @@ -fragment SnapshotProposal on Proposal { - __typename - id - author - state - title - choices - scores - scores_total - snapshot - symbol - network - type - privacy - start - end - quorum - space { - id - name - } - strategies { - network - name - params - } - flagged -} - -fragment SnapshotVote on Vote { - __typename - choice -} - -fragment SnapshotVotePower on Vp { - __typename - value: vp -} - -query GetSnapshotProposal( - $spaceId: String! - $proposalId: String! - $voterAddress: String! - $includeVotes: Boolean! -) { - proposal(id: $proposalId) { - ...SnapshotProposal - } - - votes(where: { proposal: $proposalId, voter: $voterAddress }) @include(if: $includeVotes) { - ...SnapshotVote - } - - vp(voter: $voterAddress, space: $spaceId, proposal: $proposalId) @include(if: $includeVotes) { - ...SnapshotVotePower - } -} diff --git a/packages/api-bindings-v1/tsconfig.json b/packages/api-bindings-v1/tsconfig.json deleted file mode 100644 index edb77575a3..0000000000 --- a/packages/api-bindings-v1/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "@lens-protocol/tsconfig/base.json", - "compilerOptions": { - "jsx": "react-jsx", - "lib": ["DOM", "ESNext"], - "module": "ESNext", - "outDir": "dist" - }, - "include": ["./src"] -} diff --git a/packages/api-bindings-v1/tsdoc.json b/packages/api-bindings-v1/tsdoc.json deleted file mode 100644 index b89839ca22..0000000000 --- a/packages/api-bindings-v1/tsdoc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", - "extends": ["typedoc/tsdoc.json"] -} diff --git a/packages/domain/src/entities/Credentials.ts b/packages/domain/src/entities/Credentials.ts index 47b3ac8190..b1e38cff17 100644 --- a/packages/domain/src/entities/Credentials.ts +++ b/packages/domain/src/entities/Credentials.ts @@ -2,9 +2,7 @@ import { EvmAddress } from '@lens-protocol/shared-kernel'; import { ProfileId } from './Profile'; -export interface ICredentials { +export type Credentials = { readonly address: EvmAddress; readonly profileId?: ProfileId; - - isExpired(): boolean; -} +}; diff --git a/packages/domain/src/entities/__helpers__/mocks.ts b/packages/domain/src/entities/__helpers__/mocks.ts index 8b98acdfab..26f01de848 100644 --- a/packages/domain/src/entities/__helpers__/mocks.ts +++ b/packages/domain/src/entities/__helpers__/mocks.ts @@ -11,25 +11,25 @@ import { mock32BytesHexString, mockEvmAddress } from '@lens-protocol/shared-kern import { mock } from 'jest-mock-extended'; import { AppId } from '../AppId'; -import { ICredentials } from '../Credentials'; +import { Credentials } from '../Credentials'; import { Challenge, NftOwnershipChallenge } from '../Nft'; import { Profile, ProfileId } from '../Profile'; import { PublicationId } from '../Publication'; import { Signature } from '../Signature'; import { + AnyTransactionRequestModel, + DataTransaction, + ISignedProtocolCall, IUnsignedProtocolCall, MetaTransaction, NativeTransaction, Nonce, - ISignedProtocolCall, + ProtocolTransactionRequestModel, TransactionError, TransactionErrorReason, TransactionEvent, TransactionKind, - AnyTransactionRequestModel, UnsignedTransaction, - ProtocolTransactionRequestModel, - DataTransaction, } from '../Transactions'; import { Wallet } from '../Wallet'; import { ISignedVote, IUnsignedVote, PollId } from '../polls'; @@ -50,8 +50,8 @@ export function mockWallet({ address = mockEvmAddress() }: { address?: EvmAddres return mock({ address }); } -export function mockICredentials(overrides?: Partial) { - return mock({ +export function mockCredentials(overrides?: Partial) { + return mock({ address: mockEvmAddress(), profileId: mockProfileId(), ...overrides, diff --git a/packages/domain/src/use-cases/authentication/ActiveWallet.ts b/packages/domain/src/use-cases/authentication/ActiveWallet.ts index 9db11a865a..6250c989fc 100644 --- a/packages/domain/src/use-cases/authentication/ActiveWallet.ts +++ b/packages/domain/src/use-cases/authentication/ActiveWallet.ts @@ -1,19 +1,16 @@ -import { invariant, never } from '@lens-protocol/shared-kernel'; +import { never } from '@lens-protocol/shared-kernel'; -import { ICredentials, Wallet } from '../../entities'; +import { Credentials, Wallet } from '../../entities'; +import { IWalletGateway } from '../wallets/IWalletGateway'; export interface ICredentialsReader { - getCredentials(): Promise; -} - -export interface IReadableWalletGateway { - getByAddress(address: string): Promise; + getCredentials(): Promise; } export class ActiveWallet { constructor( private credentialsReader: ICredentialsReader, - private walletGateway: IReadableWalletGateway, + private walletGateway: IWalletGateway, ) {} async requireActiveWallet(): Promise { @@ -23,10 +20,6 @@ export class ActiveWallet { never('User is not authenticated'); } - const wallet = await this.walletGateway.getByAddress(credentials.address); - - invariant(wallet, 'Active wallet should exist when credentials are present'); - - return wallet; + return this.walletGateway.getByAddress(credentials.address); } } diff --git a/packages/domain/src/use-cases/authentication/Bootstrap.ts b/packages/domain/src/use-cases/authentication/Bootstrap.ts index 2689e4e01b..d3b6c008f8 100644 --- a/packages/domain/src/use-cases/authentication/Bootstrap.ts +++ b/packages/domain/src/use-cases/authentication/Bootstrap.ts @@ -1,14 +1,14 @@ import { PromiseResult } from '@lens-protocol/shared-kernel'; -import { ICredentials, AnyTransactionRequestModel } from '../../entities'; +import { AnyTransactionRequestModel, Credentials } from '../../entities'; import { TransactionQueue } from '../transactions'; import { ICredentialsReader } from './ActiveWallet'; import { ICredentialsWriter } from './ICredentialsWriter'; import { Logout, LogoutReason } from './Logout'; import { + SessionData, anonymousSessionData, profileSessionData, - SessionData, walletOnlySessionData, } from './SessionData'; @@ -20,7 +20,7 @@ export class CredentialsExpiredError extends Error { export interface ICredentialsGateway extends ICredentialsReader, ICredentialsWriter {} export interface ICredentialsRenewer { - renewCredentials(credentials: ICredentials): PromiseResult; + renewCredentials(credentials: Credentials): PromiseResult; } export interface IBootstrapPresenter { diff --git a/packages/domain/src/use-cases/authentication/ICredentialsWriter.ts b/packages/domain/src/use-cases/authentication/ICredentialsWriter.ts index 440a9cc657..e6beec7883 100644 --- a/packages/domain/src/use-cases/authentication/ICredentialsWriter.ts +++ b/packages/domain/src/use-cases/authentication/ICredentialsWriter.ts @@ -1,5 +1,5 @@ -import { ICredentials } from '../../entities'; +import { Credentials } from '../../entities'; export interface ICredentialsWriter { - save(credentials: ICredentials): Promise; + save(credentials: Credentials): Promise; } diff --git a/packages/domain/src/use-cases/authentication/Login.ts b/packages/domain/src/use-cases/authentication/Login.ts index 6d6f1798b5..1028694b6e 100644 --- a/packages/domain/src/use-cases/authentication/Login.ts +++ b/packages/domain/src/use-cases/authentication/Login.ts @@ -1,14 +1,14 @@ import { EvmAddress, PromiseResult, Result, success } from '@lens-protocol/shared-kernel'; import { - ICredentials, + Credentials, PendingSigningRequestError, ProfileId, UserRejectedError, Wallet, WalletConnectionError, } from '../../entities'; -import { IWalletFactory } from '../wallets/IWalletFactory'; +import { IWalletGateway } from '../wallets/IWalletGateway'; import { ICredentialsWriter } from './ICredentialsWriter'; import { SessionData, profileSessionData, walletOnlySessionData } from './SessionData'; @@ -32,10 +32,6 @@ export type LoginRequest = { profileId?: ProfileId; }; -export interface IWritableWalletGateway { - save(wallet: Wallet): Promise; -} - export type LoginError = PendingSigningRequestError | UserRejectedError | WalletConnectionError; export interface ILoginPresenter { @@ -43,20 +39,19 @@ export interface ILoginPresenter { } export interface ICredentialsIssuer { - issueCredentials(signer: Wallet, using?: ProfileId): PromiseResult; + issueCredentials(signer: Wallet, using?: ProfileId): PromiseResult; } export class Login { constructor( - private readonly walletFactory: IWalletFactory, - private readonly walletGateway: IWritableWalletGateway, + private readonly walletGateway: IWalletGateway, private readonly credentialsIssuer: ICredentialsIssuer, private readonly credentialsWriter: ICredentialsWriter, private readonly presenter: ILoginPresenter, ) {} async execute(request: LoginRequest): Promise { - const wallet = await this.walletFactory.create(request.address); + const wallet = await this.walletGateway.getByAddress(request.address); const result = await this.credentialsIssuer.issueCredentials(wallet, request.profileId); if (result.isFailure()) { @@ -64,7 +59,6 @@ export class Login { return; } - await this.walletGateway.save(wallet); await this.credentialsWriter.save(result.value); if (request.profileId) { diff --git a/packages/domain/src/use-cases/authentication/Logout.ts b/packages/domain/src/use-cases/authentication/Logout.ts index 3a2dc183ff..0b9d7f7889 100644 --- a/packages/domain/src/use-cases/authentication/Logout.ts +++ b/packages/domain/src/use-cases/authentication/Logout.ts @@ -10,10 +10,6 @@ export interface IResettableCredentialsGateway { invalidate(reason: LogoutReason): Promise; } -export interface IResettableWalletGateway { - reset(): Promise; -} - export interface IResettableTransactionGateway { reset(): Promise; } @@ -28,7 +24,6 @@ export interface ILogoutPresenter { export class Logout { constructor( - private walletGateway: IResettableWalletGateway, private credentialsGateway: IResettableCredentialsGateway, private transactionGateway: IResettableTransactionGateway, private conversationsGateway: IConversationsGateway, @@ -36,10 +31,11 @@ export class Logout { ) {} async execute(reason: LogoutReason): Promise { - await this.walletGateway.reset(); - await this.conversationsGateway.reset(); - await this.transactionGateway.reset(); - await this.credentialsGateway.invalidate(reason); + await Promise.all([ + this.conversationsGateway.reset(), + this.transactionGateway.reset(), + this.credentialsGateway.invalidate(reason), + ]); this.presenter.logout(reason); } diff --git a/packages/domain/src/use-cases/authentication/UpgradeCredentials.ts b/packages/domain/src/use-cases/authentication/UpgradeCredentials.ts index 16f4f85c8c..8f236effeb 100644 --- a/packages/domain/src/use-cases/authentication/UpgradeCredentials.ts +++ b/packages/domain/src/use-cases/authentication/UpgradeCredentials.ts @@ -1,6 +1,6 @@ import { Result, invariant, success } from '@lens-protocol/shared-kernel'; -import { ICredentials, ProfileId } from '../../entities'; +import { Credentials, ProfileId } from '../../entities'; import { ICredentialsWriter } from './ICredentialsWriter'; import { SessionData, profileSessionData } from './SessionData'; @@ -9,7 +9,7 @@ export type UpgradeCredentialsRequest = { }; export interface ICredentialsUpgrader { - upgradeCredentials(profileId: ProfileId): Promise; + upgradeCredentials(profileId: ProfileId): Promise; } export interface IUpgradeCredentialsPresenter { diff --git a/packages/domain/src/use-cases/authentication/__tests__/ActiveWallet.spec.ts b/packages/domain/src/use-cases/authentication/__tests__/ActiveWallet.spec.ts index 6df040ffb4..4cd3fc25ed 100644 --- a/packages/domain/src/use-cases/authentication/__tests__/ActiveWallet.spec.ts +++ b/packages/domain/src/use-cases/authentication/__tests__/ActiveWallet.spec.ts @@ -2,19 +2,20 @@ import { InvariantError } from '@lens-protocol/shared-kernel'; import { mock } from 'jest-mock-extended'; import { when } from 'jest-when'; -import { mockICredentials, mockWallet } from '../../../entities/__helpers__/mocks'; -import { ActiveWallet, ICredentialsReader, IReadableWalletGateway } from '../ActiveWallet'; +import { mockCredentials, mockWallet } from '../../../entities/__helpers__/mocks'; +import { IWalletGateway } from '../../wallets/IWalletGateway'; +import { ActiveWallet, ICredentialsReader } from '../ActiveWallet'; describe(`Given the ${ActiveWallet.name} interactor`, () => { describe(`when "${ActiveWallet.prototype.requireActiveWallet.name}" is invoked`, () => { it('should return the active wallet when credentials are present', async () => { const wallet = mockWallet(); - const credentials = mockICredentials({ address: wallet.address }); + const credentials = mockCredentials({ address: wallet.address }); const credentialsReader = mock({ getCredentials: async () => credentials, }); - const walletGateway = mock(); + const walletGateway = mock(); when(walletGateway.getByAddress).calledWith(credentials.address).mockResolvedValue(wallet); @@ -29,22 +30,7 @@ describe(`Given the ${ActiveWallet.name} interactor`, () => { const credentialsReader = mock({ getCredentials: async () => null, }); - const walletGateway = mock(); - - const interactor = new ActiveWallet(credentialsReader, walletGateway); - - await expect(() => interactor.requireActiveWallet()).rejects.toThrow(InvariantError); - }); - - it(`should throw an ${InvariantError.name} if wallet for the given credentials is not found`, async () => { - const credentials = mockICredentials(); - - const credentialsReader = mock({ - getCredentials: async () => credentials, - }); - const walletGateway = mock(); - - when(walletGateway.getByAddress).calledWith(credentials.address).mockResolvedValue(null); + const walletGateway = mock(); const interactor = new ActiveWallet(credentialsReader, walletGateway); diff --git a/packages/domain/src/use-cases/authentication/__tests__/Bootstrap.spec.ts b/packages/domain/src/use-cases/authentication/__tests__/Bootstrap.spec.ts index e9069a8542..8c1025c8eb 100644 --- a/packages/domain/src/use-cases/authentication/__tests__/Bootstrap.spec.ts +++ b/packages/domain/src/use-cases/authentication/__tests__/Bootstrap.spec.ts @@ -2,15 +2,15 @@ import { failure, never, success } from '@lens-protocol/shared-kernel'; import { mock } from 'jest-mock-extended'; import { when } from 'jest-when'; -import { mockICredentials } from '../../../entities/__helpers__/mocks'; +import { mockCredentials } from '../../../entities/__helpers__/mocks'; import { mockTransactionQueue } from '../../../mocks'; import { TransactionQueue } from '../../transactions'; import { Bootstrap, CredentialsExpiredError, + IBootstrapPresenter, ICredentialsGateway, ICredentialsRenewer, - IBootstrapPresenter, } from '../Bootstrap'; import { Logout, LogoutReason } from '../Logout'; import { anonymousSessionData, profileSessionData } from '../SessionData'; @@ -60,8 +60,8 @@ describe(`Given the ${Bootstrap.name} interactor`, () => { }); describe(`when executed with credentials`, () => { - const oldCredentials = mockICredentials(); - const newCredentials = mockICredentials(oldCredentials); + const oldCredentials = mockCredentials(); + const newCredentials = mockCredentials(oldCredentials); it(`should: - renew the credentials and save the new ones diff --git a/packages/domain/src/use-cases/authentication/__tests__/Login.spec.ts b/packages/domain/src/use-cases/authentication/__tests__/Login.spec.ts index 8fb1b763dc..a664e63355 100644 --- a/packages/domain/src/use-cases/authentication/__tests__/Login.spec.ts +++ b/packages/domain/src/use-cases/authentication/__tests__/Login.spec.ts @@ -8,37 +8,29 @@ import { WalletConnectionError, WalletConnectionErrorReason, } from '../../../entities'; -import { mockICredentials, mockWallet } from '../../../entities/__helpers__/mocks'; -import { IWalletFactory } from '../../wallets/IWalletFactory'; +import { mockCredentials, mockWallet } from '../../../entities/__helpers__/mocks'; +import { IWalletGateway } from '../../wallets/IWalletGateway'; import { ICredentialsWriter } from '../ICredentialsWriter'; -import { ICredentialsIssuer, ILoginPresenter, IWritableWalletGateway, Login } from '../Login'; +import { ICredentialsIssuer, ILoginPresenter, Login } from '../Login'; import { profileSessionData, walletOnlySessionData } from '../SessionData'; import { mockJustWalletLoginRequest, mockProfileLoginRequest } from '../__helpers__/mocks'; function setupTestScenario({ - walletFactory, + walletGateway, credentialsIssuer, }: { - walletFactory: IWalletFactory; + walletGateway: IWalletGateway; credentialsIssuer: ICredentialsIssuer; }) { - const walletGateway = mock(); const credentialsWriter = mock(); const loginPresenter = mock(); - const interactor = new Login( - walletFactory, - walletGateway, - credentialsIssuer, - credentialsWriter, - loginPresenter, - ); + const interactor = new Login(walletGateway, credentialsIssuer, credentialsWriter, loginPresenter); return { credentialsIssuer, credentialsWriter, loginPresenter, - walletFactory, walletGateway, interactor, }; @@ -54,30 +46,27 @@ describe(`Given the ${Login.name} interactor`, () => { }); it(`should: - - use the IWalletFactory to create the specified ${Wallet.name} entity + - use the IWalletGateway to retrieve the specified ${Wallet.name} entity - generate new credentials for the wallet and specified profile - - save wallet and credentials - present successful ProfileSessionData`, async () => { - const walletFactory = mock(); - const credentialsIssuer = mock(); - - const credentials = mockICredentials({ address: wallet.address }); + const walletGateway = mock(); + when(walletGateway.getByAddress).calledWith(request.address).mockResolvedValue(wallet); - when(walletFactory.create).calledWith(request.address).mockResolvedValue(wallet); + const credentialsIssuer = mock(); + const credentials = mockCredentials({ address: wallet.address }); when(credentialsIssuer.issueCredentials) .calledWith(wallet, request.profileId) .mockResolvedValue(success(credentials)); - const { interactor, walletGateway, credentialsWriter, loginPresenter } = setupTestScenario({ + const { interactor, credentialsWriter, loginPresenter } = setupTestScenario({ credentialsIssuer, - walletFactory, + walletGateway, }); await interactor.execute(request); - expect(walletGateway.save).toHaveBeenCalledWith(wallet); expect(credentialsWriter.save).toHaveBeenCalledWith(credentials); - expect(loginPresenter.present).toBeCalledWith( + expect(loginPresenter.present).toHaveBeenCalledWith( success( profileSessionData({ address: wallet.address, @@ -88,16 +77,16 @@ describe(`Given the ${Login.name} interactor`, () => { }); it('should handle scenarios where the user cancels the challenge signing operation', async () => { - const walletFactory = mock(); + const walletGateway = mock(); const credentialsIssuer = mock(); const error = new UserRejectedError(); - when(walletFactory.create).mockResolvedValue(wallet); + when(walletGateway.getByAddress).calledWith(request.address).mockResolvedValue(wallet); when(credentialsIssuer.issueCredentials).mockResolvedValue(failure(error)); const { loginPresenter, interactor } = setupTestScenario({ credentialsIssuer, - walletFactory, + walletGateway, }); await interactor.execute(request); @@ -112,28 +101,26 @@ describe(`Given the ${Login.name} interactor`, () => { }); it(`should: - - use the IWalletFactory to create the specified ${Wallet.name} entity + - use the IWalletGateway to retrieve the specified ${Wallet.name} entity - generate new credentials for the address - - save wallet and credentials - present successful WalletOnlySessionData`, async () => { - const walletFactory = mock(); + const walletGateway = mock(); const credentialsIssuer = mock(); - const credentials = mockICredentials({ address: wallet.address }); + const credentials = mockCredentials({ address: wallet.address }); - when(walletFactory.create).calledWith(request.address).mockResolvedValue(wallet); + when(walletGateway.getByAddress).calledWith(request.address).mockResolvedValue(wallet); when(credentialsIssuer.issueCredentials) .calledWith(wallet, undefined) .mockResolvedValue(success(credentials)); - const { interactor, walletGateway, credentialsWriter, loginPresenter } = setupTestScenario({ + const { interactor, credentialsWriter, loginPresenter } = setupTestScenario({ credentialsIssuer, - walletFactory, + walletGateway, }); await interactor.execute(request); - expect(walletGateway.save).toHaveBeenCalledWith(wallet); expect(credentialsWriter.save).toHaveBeenCalledWith(credentials); expect(loginPresenter.present).toBeCalledWith( success( @@ -145,16 +132,16 @@ describe(`Given the ${Login.name} interactor`, () => { }); it('should handle scenarios where the user cancels the challenge signing operation', async () => { - const walletFactory = mock(); + const walletGateway = mock(); const credentialsIssuer = mock(); const error = new UserRejectedError(); - when(walletFactory.create).mockResolvedValue(wallet); + when(walletGateway.getByAddress).calledWith(request.address).mockResolvedValue(wallet); when(credentialsIssuer.issueCredentials).mockResolvedValue(failure(error)); const { loginPresenter, interactor } = setupTestScenario({ credentialsIssuer, - walletFactory, + walletGateway, }); await interactor.execute(request); @@ -168,16 +155,16 @@ describe(`Given the ${Login.name} interactor`, () => { address: wallet.address, }); - const walletFactory = mock(); + const walletGateway = mock(); const credentialsIssuer = mock(); const error = new WalletConnectionError(WalletConnectionErrorReason.WRONG_ACCOUNT); - when(walletFactory.create).calledWith(request.address).mockResolvedValue(wallet); + when(walletGateway.getByAddress).calledWith(request.address).mockResolvedValue(wallet); when(credentialsIssuer.issueCredentials).mockResolvedValue(failure(error)); const { loginPresenter, interactor } = setupTestScenario({ credentialsIssuer, - walletFactory, + walletGateway, }); await interactor.execute(request); diff --git a/packages/domain/src/use-cases/authentication/__tests__/Logout.spec.ts b/packages/domain/src/use-cases/authentication/__tests__/Logout.spec.ts index ff09d0b1b0..4038ca4ac4 100644 --- a/packages/domain/src/use-cases/authentication/__tests__/Logout.spec.ts +++ b/packages/domain/src/use-cases/authentication/__tests__/Logout.spec.ts @@ -5,25 +5,22 @@ import { mockWallet } from '../../../entities/__helpers__/mocks'; import { ActiveWallet } from '../ActiveWallet'; import { IConversationsGateway, - IResettableCredentialsGateway, - IResettableWalletGateway, - LogoutReason, - Logout, ILogoutPresenter, + IResettableCredentialsGateway, IResettableTransactionGateway, + Logout, + LogoutReason, } from '../Logout'; const wallet = mockWallet(); function setupTestScenario() { - const walletGateway = mock(); const credentialsGateway = mock(); const transactionGateway = mock(); const conversationGateway = mock(); const presenter = mock(); const interactor = new Logout( - walletGateway, credentialsGateway, transactionGateway, conversationGateway, @@ -31,7 +28,6 @@ function setupTestScenario() { ); return { - walletGateway, credentialsGateway, transactionGateway, conversationGateway, @@ -45,7 +41,6 @@ describe(`Given the "${Logout.name}" interactor`, () => { describe(`when "${Logout.prototype.execute.name}" is invoked`, () => { it(`should: - - clear wallets from storage - clear DM conversations from storage - clear transactions from storage - clear credentials from storage @@ -54,18 +49,11 @@ describe(`Given the "${Logout.name}" interactor`, () => { when(activeWallet.requireActiveWallet).calledWith().mockResolvedValue(wallet); - const { - walletGateway, - credentialsGateway, - transactionGateway, - conversationGateway, - presenter, - interactor, - } = setupTestScenario(); + const { credentialsGateway, transactionGateway, conversationGateway, presenter, interactor } = + setupTestScenario(); await interactor.execute(LogoutReason.USER_INITIATED); - expect(walletGateway.reset).toHaveBeenCalled(); expect(conversationGateway.reset).toHaveBeenCalled(); expect(transactionGateway.reset).toHaveBeenCalled(); expect(credentialsGateway.invalidate).toHaveBeenCalled(); diff --git a/packages/domain/src/use-cases/profile/CreateProfile.ts b/packages/domain/src/use-cases/profile/CreateProfile.ts index 8fb0a0e0a9..0c4fa74f3c 100644 --- a/packages/domain/src/use-cases/profile/CreateProfile.ts +++ b/packages/domain/src/use-cases/profile/CreateProfile.ts @@ -11,7 +11,7 @@ import { import { IPaidTransactionGateway } from '../transactions/IPaidTransactionGateway'; import { ITransactionResultPresenter } from '../transactions/ITransactionResultPresenter'; import { TransactionQueue } from '../transactions/TransactionQueue'; -import { IWalletFactory } from '../wallets/IWalletFactory'; +import { IWalletGateway } from '../wallets/IWalletGateway'; export type CreateProfileRequest = { kind: TransactionKind.CREATE_PROFILE; @@ -29,14 +29,14 @@ export type ICreateProfilePresenter = ITransactionResultPresenter< export class CreateProfile { constructor( - private readonly walletFactory: IWalletFactory, + private readonly wallets: IWalletGateway, private readonly gateway: ICreateProfileTransactionGateway, private readonly presenter: ICreateProfilePresenter, private readonly queue: TransactionQueue, ) {} async execute(request: CreateProfileRequest) { - const wallet = await this.walletFactory.create(request.to); + const wallet = await this.wallets.getByAddress(request.to); const unsigned = await this.gateway.createUnsignedTransaction(request, wallet); diff --git a/packages/domain/src/use-cases/profile/__tests__/CreateProfile.spec.ts b/packages/domain/src/use-cases/profile/__tests__/CreateProfile.spec.ts index 84b27002a4..0cde377e7c 100644 --- a/packages/domain/src/use-cases/profile/__tests__/CreateProfile.spec.ts +++ b/packages/domain/src/use-cases/profile/__tests__/CreateProfile.spec.ts @@ -22,7 +22,7 @@ import { mockWallet, } from '../../../mocks'; import { TransactionQueue } from '../../transactions'; -import { IWalletFactory } from '../../wallets/IWalletFactory'; +import { IWalletGateway } from '../../wallets'; import { CreateProfile, ICreateProfilePresenter, @@ -40,11 +40,11 @@ function setupCreateProfile({ queue?: TransactionQueue; wallet: Wallet; }) { - const walletFactory = mock(); + const walletGateway = mock(); - when(walletFactory.create).calledWith(wallet.address).mockResolvedValue(wallet); + when(walletGateway.getByAddress).calledWith(wallet.address).mockResolvedValue(wallet); - return new CreateProfile(walletFactory, gateway, presenter, queue); + return new CreateProfile(walletGateway, gateway, presenter, queue); } describe(`Given the ${CreateProfile.name} interactor`, () => { diff --git a/packages/domain/src/use-cases/wallets/IWalletFactory.ts b/packages/domain/src/use-cases/wallets/IWalletFactory.ts deleted file mode 100644 index ac36494dbb..0000000000 --- a/packages/domain/src/use-cases/wallets/IWalletFactory.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { EvmAddress } from '@lens-protocol/shared-kernel'; - -import { Wallet } from '../../entities'; - -export interface IWalletFactory { - create(address: EvmAddress): Promise; -} diff --git a/packages/domain/src/use-cases/wallets/IWalletGateway.ts b/packages/domain/src/use-cases/wallets/IWalletGateway.ts new file mode 100644 index 0000000000..af9951c8ee --- /dev/null +++ b/packages/domain/src/use-cases/wallets/IWalletGateway.ts @@ -0,0 +1,5 @@ +import { Wallet } from '../../entities'; + +export interface IWalletGateway { + getByAddress(address: string): Promise; +} diff --git a/packages/domain/src/use-cases/wallets/index.ts b/packages/domain/src/use-cases/wallets/index.ts index 6905bf5c31..ccea7b2a84 100644 --- a/packages/domain/src/use-cases/wallets/index.ts +++ b/packages/domain/src/use-cases/wallets/index.ts @@ -1,3 +1,3 @@ -export * from './IWalletFactory'; +export * from './IWalletGateway'; export * from './InviteWallets'; export * from './TokenAvailability'; diff --git a/packages/react-v1/.eslintignore b/packages/react-v1/.eslintignore deleted file mode 100644 index 627daaafb6..0000000000 --- a/packages/react-v1/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -dist -*.cjs -jest.config.ts diff --git a/packages/react-v1/.eslintrc.cjs b/packages/react-v1/.eslintrc.cjs deleted file mode 100644 index 9557135b22..0000000000 --- a/packages/react-v1/.eslintrc.cjs +++ /dev/null @@ -1,49 +0,0 @@ -module.exports = { - root: true, - extends: [ - '@lens-protocol/eslint-config', - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', - 'plugin:react/jsx-runtime', - ], - plugins: ['react', 'react-hooks'], - settings: { - react: { - version: 'detect', - }, - }, - rules: { - 'react/prop-types': 'off', - 'react/no-unescaped-entities': 'off', - 'react/jsx-curly-brace-presence': [ - 'error', - { props: 'never', children: 'never', propElementValues: 'always' }, - ], - 'no-restricted-imports': [ - 'error', - { - paths: [ - { - name: 'lodash', - message: 'Please use lodash submodules imports.', - }, - { - name: 'lodash/fp', - message: 'Please use lodash submodules imports.', - }, - { - name: '@apollo/client/testing', - importNames: ['createMockClient'], - message: 'Please import "mockLensApolloClient" from @lens-protocol/api-bindings/mocks.', - }, - { - name: '@apollo/client', - importNames: ['ApolloClient'], - message: - 'Please use "createLensApolloClient" or "createSnapshotApolloClient" from @lens-protocol/api-bindings.', - }, - ], - }, - ], - }, -}; diff --git a/packages/react-v1/.prettierignore b/packages/react-v1/.prettierignore deleted file mode 100644 index 3f6fff7b2b..0000000000 --- a/packages/react-v1/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -dist -coverage \ No newline at end of file diff --git a/packages/react-v1/CHANGELOG.md b/packages/react-v1/CHANGELOG.md deleted file mode 100644 index a6bbc3f47a..0000000000 --- a/packages/react-v1/CHANGELOG.md +++ /dev/null @@ -1,816 +0,0 @@ -# @lens-protocol/react - -## 1.3.1 - -### Patch Changes - -- ace02d32: **Fixes** support for ERC1155 gated content -- 5f251069: **Fixed** `usePublications` to refetch on `publicationIds` change -- dfb15e1a: **Fixed** 1.3.1-next.0 release packages bundles -- ebc2e7e5: **Added** `publicationsId` to `usePublications` args -- 48dd0860: **Fixed** internal imports -- Updated dependencies [ace02d32] -- Updated dependencies [5f251069] -- Updated dependencies [dfb15e1a] -- Updated dependencies [ebc2e7e5] -- Updated dependencies [48dd0860] - - @lens-protocol/gated-content@0.3.3 - - @lens-protocol/api-bindings@0.10.1 - - @lens-protocol/domain@0.10.1 - - @lens-protocol/blockchain-bindings@0.9.2 - -## 1.3.1-next.4 - -### Patch Changes - -- 48dd0860: **Fixed** internal imports -- Updated dependencies [48dd0860] - - @lens-protocol/domain@0.10.1-next.0 - - @lens-protocol/api-bindings@0.10.1-next.3 - - @lens-protocol/blockchain-bindings@0.9.2-next.0 - - @lens-protocol/gated-content@0.3.3-next.4 - -## 1.3.1-next.3 - -### Patch Changes - -- ace02d32: **Fixes** support for ERC1155 gated content -- Updated dependencies [ace02d32] - - @lens-protocol/gated-content@0.3.3-next.3 - -## 1.3.1-next.2 - -### Patch Changes - -- 5f251069: **Fixed** `usePublications` to refetch on `publicationIds` change -- Updated dependencies [5f251069] - - @lens-protocol/api-bindings@0.10.1-next.2 - - @lens-protocol/gated-content@0.3.3-next.2 - -## 1.3.1-next.1 - -### Patch Changes - -- dfb15e1a: **Fixed** 1.3.1-next.0 release packages bundles -- Updated dependencies [dfb15e1a] - - @lens-protocol/api-bindings@0.10.1-next.1 - - @lens-protocol/gated-content@0.3.3-next.1 - -## 1.3.1-next.0 - -### Patch Changes - -- ebc2e7e5: **Added** `publicationsId` to `usePublications` args -- Updated dependencies [ebc2e7e5] - - @lens-protocol/api-bindings@0.10.1-next.0 - - @lens-protocol/gated-content@0.3.3-next.0 - -## 1.3.0 - -### Minor Changes - -- de401a59: **Added** support for optimized and transformed media inside publication and profile MediaSet -- c8426cb3: **Added** publication types as valid argument for `usePublications` query -- 40fce6ff: **Added** support for bookmarks: list, add, and remove from a Profile private list of publications -- ad797714: **Added** `useNotInterested` hook -- c2a91ef4: **Added** `Profile.invitedBy` field -- 636ff014: **Added** `profileIds` to `usePublications` hook -- cfe0d51e: **Added** `highSignalFilter` to `useNotifications` hook -- 3ffab7b9: **Added** newly created `Profile` to `useCreateProfile` result -- 19ed489e: **Added** `beforeCount` to all paginated hooks and refetch data on re-render of `usePublication` and `useProfile` hooks. -- 0f75f79d: **Added** experimental `useCurrentSession` hook - **Fixed** issue with `Profile` entity being leaked by the `useWalletLogin` hook - **Fixed** bug preventing logout on expired credentials detected at startup type -- 847a9db3: **Added** `useClearRecentPosts` hook -- 773c2ed8: **Added** ability to override `sources` in `useExplorePublications` hook and support to `noRandomize` param. -- 773c2ed8: **Added** `name` support to non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` -- 6eaaaf22: **Added** `Profile.followNftAddress` field -- 433760f3: **Added** ability to specify profile picture and follow policy when creating a new profile" -- fc31f146: **Added** experimental hooks that integrate with @xmtp/react-sdk -- 9428efeb: **Added** support for `attributes` and `image` for non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` -- e8dc3cd8: fixes collect/mirror count bug -- 3b67207b: **Added** `appId` to `Comment` and `Post` -- 4c4505d2: **Added** support for Profile Guardian -- bdbc71d5: **Added** ability to await newly created post in `useCreatePost` hook - -### Patch Changes - -- a5cf2198: Fixed useCurrentSession -- 09206763: **Fixed** issue with `useWalletLogin` never settling -- df70461c: **Fixed** `useUnreadNotificationCount` to work with fresh accounts -- 773c2ed8: **Fixes** issues with `profileIds` not used to evaluate cache hits. Affecting `usePublications` and `useProfiles`. -- b7609fcb: **Fixed** `useNotification` to include `highSignalFilter` filter -- 773c2ed8: **Added** missing `commentsOfOrdering` and `commentsRankingFilter` to `useComments` hook -- 125ec30c: **Fixed** `usePollDetails` to be robust to flagged or misconfigured Snapshot Proposals -- 28094a84: **Fixed** XMTP dep is optional until chat features are requested via `@lens-protocol/react-web/inbox` entrypoint -- 1d13a3ab: **Fixed** issue with network switch failing on some wallets. Thanks [@jarrodwatts](https://github.com/jarrodwatts)! -- Updated dependencies [de401a59] -- Updated dependencies [40fce6ff] -- Updated dependencies [ad797714] -- Updated dependencies [773c2ed8] -- Updated dependencies [c2a91ef4] -- Updated dependencies [b7609fcb] -- Updated dependencies [636ff014] -- Updated dependencies [773c2ed8] -- Updated dependencies [3ffab7b9] -- Updated dependencies [19ed489e] -- Updated dependencies [0f75f79d] -- Updated dependencies [d5efd895] -- Updated dependencies [773c2ed8] -- Updated dependencies [773c2ed8] -- Updated dependencies [125ec30c] -- Updated dependencies [6eaaaf22] -- Updated dependencies [433760f3] -- Updated dependencies [fc31f146] -- Updated dependencies [9428efeb] -- Updated dependencies [e8dc3cd8] -- Updated dependencies [3b67207b] -- Updated dependencies [4c4505d2] -- Updated dependencies [bdbc71d5] -- Updated dependencies [5943a0f0] - - @lens-protocol/api-bindings@0.10.0 - - @lens-protocol/gated-content@0.3.2 - - @lens-protocol/blockchain-bindings@0.9.1 - - @lens-protocol/domain@0.10.0 - - @lens-protocol/shared-kernel@0.10.0 - - @lens-protocol/storage@0.7.4 - -## 1.3.0-next.11 - -### Patch Changes - -- 09206763: **Fixed** issue with `useWalletLogin` never settling - -## 1.3.0-next.10 - -### Minor Changes - -- bdbc71d5: **Added** ability to await newly created post in `useCreatePost` hook - -### Patch Changes - -- Updated dependencies [bdbc71d5] - - @lens-protocol/shared-kernel@0.10.0-next.2 - - @lens-protocol/domain@0.10.0-next.7 - - @lens-protocol/api-bindings@0.10.0-next.8 - - @lens-protocol/blockchain-bindings@0.9.1-next.7 - - @lens-protocol/gated-content@0.3.2-next.8 - - @lens-protocol/storage@0.7.4-next.2 - -## 1.3.0-next.9 - -### Patch Changes - -- Updated dependencies - - @lens-protocol/shared-kernel@0.10.0-next.1 - - @lens-protocol/api-bindings@0.10.0-next.7 - - @lens-protocol/blockchain-bindings@0.9.1-next.6 - - @lens-protocol/domain@0.10.0-next.6 - - @lens-protocol/gated-content@0.3.2-next.7 - - @lens-protocol/storage@0.7.4-next.1 - -## 1.3.0-next.8 - -### Minor Changes - -- 773c2ed8: **Added** ability to override `sources` in `useExplorePublications` hook and support to `noRandomize` param. -- 773c2ed8: **Added** `name` support to non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` - -### Patch Changes - -- 773c2ed8: **Fixes** issues with `profileIds` not used to evaluate cache hits. Affecting `usePublications` and `useProfiles`. -- 773c2ed8: **Added** missing `commentsOfOrdering` and `commentsRankingFilter` to `useComments` hook -- Updated dependencies [773c2ed8] -- Updated dependencies [773c2ed8] -- Updated dependencies [773c2ed8] -- Updated dependencies [773c2ed8] - - @lens-protocol/api-bindings@0.10.0-next.6 - - @lens-protocol/domain@0.10.0-next.5 - - @lens-protocol/gated-content@0.3.2-next.6 - - @lens-protocol/blockchain-bindings@0.9.1-next.5 - -## 1.3.0-next.7 - -### Patch Changes - -- 28094a84: **Fixed** XMTP dep is optional until chat features are requested via `@lens-protocol/react-web/inbox` entrypoint - -## 1.3.0-next.6 - -### Minor Changes - -- 3ffab7b9: **Added** newly created `Profile` to `useCreateProfile` result -- 19ed489e: **Added** `beforeCount` to all paginated hooks and refetch data on re-render of `usePublication` and `useProfile` hooks. -- 6eaaaf22: **Added** `Profile.followNftAddress` field - -### Patch Changes - -- Updated dependencies [3ffab7b9] -- Updated dependencies [19ed489e] -- Updated dependencies [6eaaaf22] - - @lens-protocol/domain@0.10.0-next.4 - - @lens-protocol/api-bindings@0.10.0-next.5 - - @lens-protocol/blockchain-bindings@0.9.1-next.4 - - @lens-protocol/gated-content@0.3.2-next.5 - -## 1.3.0-next.5 - -### Minor Changes - -- 433760f3: **Added** ability to specify profile picture and follow policy when creating a new profile" -- fc31f146: **Added** experimental hooks that integrate with @xmtp/react-sdk -- e8dc3cd8: fixes collect/mirror count bug - -### Patch Changes - -- b7609fcb: **Fixed** `useNotification` to include `highSignalFilter` filter -- Updated dependencies [b7609fcb] -- Updated dependencies [433760f3] -- Updated dependencies [fc31f146] -- Updated dependencies [e8dc3cd8] - - @lens-protocol/api-bindings@0.10.0-next.4 - - @lens-protocol/domain@0.10.0-next.3 - - @lens-protocol/shared-kernel@0.10.0-next.0 - - @lens-protocol/gated-content@0.3.2-next.4 - - @lens-protocol/blockchain-bindings@0.9.1-next.3 - - @lens-protocol/storage@0.7.4-next.0 - -## 1.3.0-next.4 - -### Minor Changes - -- 9428efeb: **Added** support for `attributes` and `image` for non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` - -### Patch Changes - -- Updated dependencies [9428efeb] - - @lens-protocol/domain@0.9.1-next.2 - - @lens-protocol/api-bindings@0.10.0-next.3 - - @lens-protocol/blockchain-bindings@0.9.1-next.2 - - @lens-protocol/gated-content@0.3.2-next.3 - -## 1.3.0-next.3 - -### Minor Changes - -- de401a59: **Added** support for optimized and transformed media inside publication and profile MediaSet -- 40fce6ff: **Added** support for bookmarks: list, add, and remove from a Profile private list of publications -- ad797714: **Added** `useNotInterested` hook -- 636ff014: **Added** `profileIds` to `usePublications` hook -- 3b67207b: **Added** `appId` to `Comment` and `Post` - -### Patch Changes - -- a5cf2198: Fixed useCurrentSession -- 125ec30c: **Fixed** `usePollDetails` to be robust to flagged or misconfigured Snapshot Proposals -- Updated dependencies [de401a59] -- Updated dependencies [40fce6ff] -- Updated dependencies [ad797714] -- Updated dependencies [636ff014] -- Updated dependencies [125ec30c] -- Updated dependencies [3b67207b] - - @lens-protocol/api-bindings@0.10.0-next.2 - - @lens-protocol/gated-content@0.3.2-next.2 - - @lens-protocol/blockchain-bindings@0.9.1-next.1 - - @lens-protocol/domain@0.9.1-next.1 - -## 1.3.0-next.2 - -### Patch Changes - -- df70461c: **Fixed** `useUnreadNotificationCount` to work with fresh accounts -- 1d13a3ab: **Fixed** issue with network switch failing on some wallets. Thanks [@jarrodwatts](https://github.com/jarrodwatts)! - -## 1.3.0-next.1 - -### Patch Changes - -- Updated dependencies [d5efd895] - - @lens-protocol/api-bindings@0.9.2-next.1 - - @lens-protocol/gated-content@0.3.2-next.1 - -## 1.2.2 - -### Patch Changes - -- Updated dependencies [06a30a2c] - - @lens-protocol/api-bindings@0.9.1 - - @lens-protocol/gated-content@0.3.1 - -## 1.3.0-next.0 - -### Minor Changes - -- c8426cb3: **Added** publication types as valid argument for `usePublications` query -- c2a91ef4: **Added** `Profile.invitedBy` field -- cfe0d51e: **Added** `highSignalFilter` to `useNotifications` hook -- 0f75f79d: **Added** experimental `useCurrentSession` hook - **Fixed** issue with `Profile` entity being leaked by the `useWalletLogin` hook - **Fixed** bug preventing logout on expired credentials detected at startup type -- 847a9db3: **Added** `useClearRecentPosts` hook -- 4c4505d2: **Added** support for Profile Guardian - -### Patch Changes - -- Updated dependencies [c2a91ef4] -- Updated dependencies [0f75f79d] -- Updated dependencies [4c4505d2] - - @lens-protocol/api-bindings@0.9.1-next.0 - - @lens-protocol/domain@0.9.1-next.0 - - @lens-protocol/gated-content@0.3.1-next.0 - - @lens-protocol/blockchain-bindings@0.9.1-next.0 - -## 1.2.1 - -### Patch Changes - -- 6be8cfb6: **Fixed** `useCreateComment` and `useCreateEncryptedComment` validation errors - -## 1.2.0 - -### Minor Changes - -- cb5b900d: **Added** sandbox environment support -- af4b1133: Detects malformed URLs from user's provided `upload` handler -- 3025d56a: allow self funded fallback for proxy actions -- 225f0fa7: **Added** `usePollDetail` and `usePollVote` hooks -- 422c627e: **Added** eager check on several tx hooks so to fail fast with dev friendly error messages" - -### Patch Changes - -- 55211083: Synchronize state change between `useActiveWallet` and `useActiveProfile` hooks -- 422c627e: **Fixed** missing DecryptionCriteria validation -- 1d99413a: Fixed: wrong reaction state when optimisticaly adding a reaction if another reaction already exists -- ea0b40e3: **Fixed** active profile to be always `null` when there is not active wallet -- 2dbe0035: - Adds the ability to override the `createGatedClient` function for gated content functionality. -- 97ecba69: **Fixed** cache redirects for Publication and Profile -- Updated dependencies [cb5b900d] -- Updated dependencies [55211083] -- Updated dependencies [3025d56a] -- Updated dependencies [1d99413a] -- Updated dependencies [225f0fa7] -- Updated dependencies [ea0b40e3] -- Updated dependencies [a899553c] -- Updated dependencies [422c627e] -- Updated dependencies [2dbe0035] -- Updated dependencies [148e9636] -- Updated dependencies [e4be6c07] -- Updated dependencies [97ecba69] - - @lens-protocol/gated-content@0.3.0 - - @lens-protocol/domain@0.9.0 - - @lens-protocol/api-bindings@0.9.0 - - @lens-protocol/blockchain-bindings@0.9.0 - - @lens-protocol/shared-kernel@0.9.0 - - @lens-protocol/storage@0.7.3 - -## 1.2.0-next.4 - -### Patch Changes - -- ea0b40e3: **Fixed** active profile to be always `null` when there is not active wallet -- Updated dependencies [ea0b40e3] -- Updated dependencies [a899553c] - - @lens-protocol/domain@0.9.0-next.2 - - @lens-protocol/api-bindings@0.9.0-next.2 - - @lens-protocol/blockchain-bindings@0.9.0-next.2 - - @lens-protocol/gated-content@0.3.0-next.4 - -## 1.1.1 - -### Patch Changes - -- Updated dependencies [58217985] - - @lens-protocol/api-bindings@0.8.1 - - @lens-protocol/gated-content@0.2.3 - -## 1.2.0-next.3 - -### Patch Changes - -- 2dbe0035: - Adds the ability to override the `createGatedClient` function for gated content functionality. -- Updated dependencies [2dbe0035] - - @lens-protocol/gated-content@0.3.0-next.3 - -## 1.2.0-next.2 - -### Minor Changes - -- 3025d56a: allow self funded fallback for proxy actions -- 225f0fa7: **Added** `usePollDetail` and `usePollVote` hooks -- 422c627e: **Added** eager check on several tx hooks so to fail fast with dev friendly error messages" - -### Patch Changes - -- 422c627e: **Fixed** missing DecryptionCriteria validation -- 97ecba69: **Fixed** cache redirects for Publication and Profile -- Updated dependencies [3025d56a] -- Updated dependencies [225f0fa7] -- Updated dependencies [422c627e] -- Updated dependencies [97ecba69] - - @lens-protocol/api-bindings@0.9.0-next.1 - - @lens-protocol/domain@0.9.0-next.1 - - @lens-protocol/blockchain-bindings@0.9.0-next.1 - - @lens-protocol/shared-kernel@0.9.0-next.0 - - @lens-protocol/gated-content@0.3.0-next.2 - - @lens-protocol/storage@0.7.3-next.0 - -## 1.2.0-next.1 - -### Patch Changes - -- 55211083: Synchronize state change between `useActiveWallet` and `useActiveProfile` hooks -- Updated dependencies [55211083] -- Updated dependencies [148e9636] - - @lens-protocol/domain@0.8.1-next.0 - - @lens-protocol/gated-content@0.3.0-next.1 - - @lens-protocol/api-bindings@0.8.1-next.0 - - @lens-protocol/blockchain-bindings@0.8.1-next.0 - -## 1.2.0-next.0 - -### Minor Changes - -- cb5b900d: **Added** sandbox environment support -- af4b1133: Detects malformed URLs from user's provided `upload` handler - -### Patch Changes - -- Updated dependencies [cb5b900d] - - @lens-protocol/gated-content@0.3.0-next.0 - -## 1.1.0 - -### Minor Changes - -- 03a8ad5: **Deprecated** publication's `isOptimisticMirroredByMe` property, introduced `isMirroredByMe` -- 513373d: **Enhanced** publication's `hasCollectedByMe` to replace deprecated `hasOptimisticCollectedByMe` property -- 98c6547: **Added** support to fetch results before the current results set -- c416a2e: **Added:** self-fund protocol calls when subsidized approach fails -- c416a2e: **Fixed:** ensures correct chain when signing typed data -- c416a2e: **Fixed:** network switch in wagmi bindings -- cf4a420: **Added** support for cover and `altTag` in publication media attributes -- ef1d7e2: **Added** Momoka support to React hooks -- 5c5bfb2: **Added** support for `SimpleCollectModule` - -### Patch Changes - -- 1d5cf31: **Fixed** create mirror commit phase so to update the correct publication in cache -- 72becec: **Fixed** documentation for `useuseActiveProfileSwitch` and `useProfilesOwnedByMe` hooks -- ca9b8cb: **Fixes** export of `NotificationTypes` -- 04647bb: **Fixed** issue preventing query hook from detecting active profile changes -- b738abb: **Fixed** `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` callback argument -- 71196cf: **Added** support for more metadata fields in create publication hooks -- c4e6fcf: **Fixes** `CollectType`, `NftAttributeDisplayType`, `ReferencePolicyType` not exported as values -- Updated dependencies [03a8ad5] -- Updated dependencies [37bf8e8] -- Updated dependencies [513373d] -- Updated dependencies [98c6547] -- Updated dependencies [04647bb] -- Updated dependencies [c416a2e] -- Updated dependencies [ef1d7e2] -- Updated dependencies [b738abb] -- Updated dependencies [5c5bfb2] -- Updated dependencies [71196cf] - - @lens-protocol/api-bindings@0.8.0 - - @lens-protocol/blockchain-bindings@0.8.0 - - @lens-protocol/shared-kernel@0.8.0 - - @lens-protocol/domain@0.8.0 - - @lens-protocol/gated-content@0.2.2 - - @lens-protocol/storage@0.7.2 - -## 1.1.0-next.5 - -### Patch Changes - -- Updated dependencies [37bf8e8] - - @lens-protocol/api-bindings@0.8.0-next.4 - - @lens-protocol/gated-content@0.2.2-next.4 - -## 1.1.0-next.4 - -### Minor Changes - -- 5c5bfb2: Added support for SimpleCollectModule - -### Patch Changes - -- b738abb: Fixed `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` callback argument -- Updated dependencies [b738abb] -- Updated dependencies [5c5bfb2] - - @lens-protocol/shared-kernel@0.8.0-next.1 - - @lens-protocol/domain@0.8.0-next.3 - - @lens-protocol/api-bindings@0.8.0-next.3 - - @lens-protocol/blockchain-bindings@0.8.0-next.3 - - @lens-protocol/gated-content@0.2.2-next.3 - - @lens-protocol/storage@0.7.2-next.1 - -## 1.1.0-next.3 - -### Patch Changes - -- 1d5cf31: Fixed create mirror commit phase so to update the correct publication in cache - -## 1.1.0-next.2 - -### Minor Changes - -- ef1d7e2: Added Momoka support to React hooks - -### Patch Changes - -- Updated dependencies [ef1d7e2] - - @lens-protocol/api-bindings@0.8.0-next.2 - - @lens-protocol/domain@0.8.0-next.2 - - @lens-protocol/gated-content@0.2.2-next.2 - - @lens-protocol/blockchain-bindings@0.8.0-next.2 - -## 1.1.0-next.1 - -### Minor Changes - -- 03a8ad5: Deprecated publication's `isOptimisticMirroredByMe` property, introduced `isMirroredByMe` - -### Patch Changes - -- ca9b8cb: **Fixes** export of `NotificationTypes` -- 71196cf: Added support for more metadata fields in create publication hooks -- Updated dependencies [03a8ad5] -- Updated dependencies [71196cf] - - @lens-protocol/api-bindings@0.8.0-next.1 - - @lens-protocol/domain@0.8.0-next.1 - - @lens-protocol/gated-content@0.2.2-next.1 - - @lens-protocol/blockchain-bindings@0.8.0-next.1 - -## 1.1.0-next.0 - -### Minor Changes - -- 513373d3: Enhanced publication's hasCollectedByMe to replace deprecated hasOptimisticCollectedByMe property -- c416a2ea: - - **Added:** self-fund protocol calls when subsidized approaches fails - - **Fixed:** ensures correct chain when signing typed data - - **Fixed:** network switch in wagmi bindings -- cf4a4201: Added support for cover and altTag in publication media attributes - -### Patch Changes - -- 72becec0: **Fixed** documentation for `useuseActiveProfileSwitch` and `useProfilesOwnedByMe` hooks -- 04647bbe: **Fixed** issue preventing query hook from detecting active profile changes -- c4e6fcfc: **Fixes** `CollectType`, `NftAttributeDisplayType`, `ReferencePolicyType` not exported as values -- Updated dependencies [513373d3] -- Updated dependencies [04647bbe] -- Updated dependencies [c416a2ea] - - @lens-protocol/api-bindings@0.8.0-next.0 - - @lens-protocol/blockchain-bindings@0.8.0-next.0 - - @lens-protocol/shared-kernel@0.8.0-next.0 - - @lens-protocol/domain@0.8.0-next.0 - - @lens-protocol/gated-content@0.2.2-next.0 - - @lens-protocol/storage@0.7.2-next.0 - -## 1.0.1 - -### Patch Changes - -- 425daba: **Fixed** 1.0.0 release packages bundles -- Updated dependencies [425daba] - - @lens-protocol/api-bindings@0.7.1 - - @lens-protocol/blockchain-bindings@0.7.1 - - @lens-protocol/domain@0.7.1 - - @lens-protocol/gated-content@0.2.1 - - @lens-protocol/shared-kernel@0.7.1 - - @lens-protocol/storage@0.7.1 - -## 1.0.0 - -### Minor Changes - -- c5dd99b: Changed arguments of `execute` method returned from `useCreateProfile` hook -- 37eaf8a: Added TSDoc, use shared tsconfig, better types - -### Patch Changes - -- fce5b18: Added support for new collect modules: multirecipientFeeCollectModule, erc4626FeeCollectModule, aaveFeeCollectModule -- 520a7c1: Changed GQL generated types so that Fragment suffix is no longer necessary - - Added several missing TS type definitions - - Added TSDoc comments to several APIs -- 0f20b5a: Changed storage keys so use environment name as namespace -- 006aff5: Fixed bug with schema validation for Date in NftAttribute -- 0f20b5a: Changed env config variables to be `development` and `production` -- a4e9500: allow to define sortCriteria for useExploreProfiles -- Updated dependencies [6ae90ef] -- Updated dependencies [0f20b5a] -- Updated dependencies [37eaf8a] -- Updated dependencies [0f20b5a] -- Updated dependencies [a4e9500] - - @lens-protocol/api-bindings@0.7.0 - - @lens-protocol/gated-content@0.2.0 - - @lens-protocol/blockchain-bindings@0.7.0 - - @lens-protocol/shared-kernel@0.7.0 - - @lens-protocol/storage@0.7.0 - - @lens-protocol/domain@0.7.0 - -## 1.0.0-beta.1 - -### Patch Changes - -- 0f20b5a: Changed storage keys so use environment name as namespace -- 0f20b5a: Changed env config variables to be `development` and `production` -- Updated dependencies [0f20b5a] -- Updated dependencies [0f20b5a] - - @lens-protocol/gated-content@0.2.0-beta.1 - -## 1.0.0-beta.0 - -### Minor Changes - -- c5dd99b: Changed arguments of `execute` method returned from `useCreateProfile` hook -- dc1350d: Added TSDoc, use shared tsconfig, better types - -### Patch Changes - -- fce5b18: Added support for new collect modules: `multirecipientFeeCollectModule`, `erc4626FeeCollectModule`, `aaveFeeCollectModule` -- 520a7c1: Changed GQL generated types so that `Fragment` suffix is no longer necessary -- Added several missing TS type definitions -- Added TSDoc comments to several APIs -- 006aff5: Fixed bug with schema validation for `Date` in `NftAttribute` -- a4e9500: allow to define `sortCriteria` for `useExploreProfiles` -- Updated dependencies [6ae90ef] -- Updated dependencies [dc1350d] -- Updated dependencies [a4e9500] - - @lens-protocol/api-bindings@0.7.0-beta.0 - - @lens-protocol/blockchain-bindings@0.7.0-beta.0 - - @lens-protocol/gated-content@0.2.0-beta.0 - - @lens-protocol/shared-kernel@0.7.0-beta.0 - - @lens-protocol/storage@0.7.0-beta.0 - - @lens-protocol/domain@0.7.0-beta.0 - -## 0.6.0 - -### Minor Changes - -- 6be7f14: Added support for token gated post/comment using Lit Protocol. -- d153c2e: Updated all hooks/flow requiring `observerId` to automatically use Active Profile Id. -- 4475a27: Added appId to LensConfig. It is used when creating publications. - -### Patch Changes - -- Updated dependencies [4475a27] - - @lens-protocol/domain@0.6.0 - - @lens-protocol/api-bindings@0.6.0 - - @lens-protocol/blockchain-bindings@0.6.0 - - @lens-protocol/gated-content@0.0.2 - - @lens-protocol/storage@0.6.0 - - @lens-protocol/shared-kernel@0.6.0 - -## 0.5.1 - -### Patch Changes - -- 44596707: Fixed `TransactionQueue already initialized` console error in strict mode -- ed973b51: Added `electedMirror`, `mirrors`, `collects` and `reactions` to feed query - - @lens-protocol/api-bindings@0.5.1 - - @lens-protocol/blockchain-bindings@0.5.1 - - @lens-protocol/domain@0.5.1 - - @lens-protocol/storage@0.5.1 - - @lens-protocol/shared-kernel@0.5.1 - -## 0.5.0 - -### Minor Changes - -- 17646fff: Removed the need for `assertRequiredSigner` when returning the signer from `getSigner` (Used in ) -- 95d905c5: Added `useProfilesOwnedByMe` hook -- 7124e4e6: Added `profilePublicationsForSale` hook -- b098c376: Added missing fields to `PublicationStats` and `ProfileStats` -- 30abfeec: Updated internal dependencies - -### Patch Changes - -- 99eb422e: Added `DecryptionCriteria` to `CommentFragment` and `PostFragment` - - @lens-protocol/api-bindings@0.5.0 - - @lens-protocol/blockchain-bindings@0.5.0 - - @lens-protocol/domain@0.5.0 - - @lens-protocol/shared-kernel@0.5.0 - - @lens-protocol/storage@0.5.0 - -## 0.4.1 - -### Patch Changes - -- 58c9d8e: Fixes the pagination support on the publication related queries - - @lens-protocol/api-bindings@0.4.1 - - @lens-protocol/blockchain-bindings@0.4.1 - - @lens-protocol/domain@0.4.1 - - @lens-protocol/shared-kernel@0.4.1 - - @lens-protocol/storage@0.4.1 - -## 0.4.0 - -### Minor Changes - -- b5350d9: Removed the `walletType` argument from the `login` method of `useWalletLogin` hook -- f0897b1: Added `useApproveModule` and internal toolings for EIP-1559 gas estimation -- 169352f: Added `metadataFilter` to `useFeed`, `useExplorePublications` and `useComments`. -- fa654d3: Added ability to collect a publication -- daad9ed: Added `useWhoMirroredPublication` hook - -### Patch Changes - -- de56baf: Added `IStorageProvider` `StorageSubscription` `StorageProviderSubscriber` and `IObservableStorageProvider` to the package exports - - Removed `IStorageProvider.subscribe` method (use `IObservableStorageProvider` when custom subscription logic is required) - - - @lens-protocol/api-bindings@0.4.0 - - @lens-protocol/blockchain-bindings@0.4.0 - - @lens-protocol/domain@0.4.0 - - @lens-protocol/shared-kernel@0.4.0 - - @lens-protocol/storage@0.4.0 - -## 0.3.0 - -### Minor Changes - -- fc53150: Added `useProfilesOwnedBy` hook -- e830624: Removed `PendingSigningRequestError | UserRejectedError | WalletConnectionError` from `LensProvider` `onError` handler - Changed `useWalletLogin` to return an object with `login`, `error` and `isPending` keys - Changed `useWalletLogout` to return an object with `logout` and `isPending`` -- 275f811: Added `useReportPublication` hook -- fb53a70: Added `useWhoCollectedPublication` hook -- b2c5ab5: Removes `Fields` suffix from GQL fragments type definitions -- 751d066: Added `useCreateMirror` hook -- c75bb6d: Added `useActiveProfileSwitcher` -- eb010f1: Added `useProfilePublicationRevenue` hook -- e6ba141: Added `useUpdateDispatcherConfig` hook -- cad27c4: Added `useHidePublication` hook -- b5c0427: Added ability to update profile follow policy -- 828089a: Added `useUpdateProfileImage` hook -- ab034e9: Added `RevenueAggregate.totalAmount: Amount` -- e3cc08e: Removed `totalCount` from paginated queries -- 2f15aa8: Added `useEnabledModules` hook -- 8bfd767: Added `isValidHandle` helper -- 1b3d049: Changed `useUpdatedProfileImage` to support dispatcher -- 6613321: Fixed duplicated `@apollo/client` package when using `pnpm` package manager -- 0236b7c: Changed return type of `useActiveWallet` hook. -- 422e571: Added capability to filter by event type in `useFeed` hook. -- bd33559: Fixed `usePublications` pagination support - -### Patch Changes - -- Updated dependencies - - @lens-protocol/api-bindings@0.3.0 - - @lens-protocol/blockchain-bindings@0.3.0 - - @lens-protocol/domain@0.3.0 - - @lens-protocol/shared-kernel@0.3.0 - - @lens-protocol/storage@0.3.0 - -## 0.2.0 - -### Minor Changes - -- 930d252: Added `useSearchProfiles` and `useSearchPublications` hooks -- 7b8e3f8: Added `useWhoReacted` hook -- c6a168e: Added `useCreateComment` hook -- 4e2b448: Added `useExplorePublications` hook -- 5f46cde: Added `useUnfollow` hook -- c89aed9: Added `useFollow` hook -- 1c607e2: Added `usePublicationRevenue` hook -- 2054ad6: Added `useProfileFollowRevenue` hook -- a921c32: Added `useReaction` hook - -### Patch Changes - -- Updated dependencies [930d252] -- Updated dependencies [7b8e3f8] -- Updated dependencies [4e2b448] -- Updated dependencies [5f46cde] -- Updated dependencies [c89aed9] -- Updated dependencies [1c607e2] -- Updated dependencies [a921c32] - - @lens-protocol/api-bindings@1.0.0 - - @lens-protocol/blockchain-bindings@1.0.0 - - @lens-protocol/shared-kernel@1.0.0 - - @lens-protocol/domain@1.0.0 - - @lens-protocol/storage@1.0.0 - -## 0.1.1 - -### Patch Changes - -- e8c5846: Fixes @lens-protocol/react/web exports config. - - @lens-protocol/api-bindings@0.1.1 - - @lens-protocol/domain@0.1.1 - - @lens-protocol/shared-kernel@0.1.1 - - @lens-protocol/storage@0.1.1 - -## 0.1.0 - -First developer preview release - -- feat: authentication w/ transparent token renewal -- feat: React Hooks to: - - fetch publications - - fetch profiles - - fetch followers/following - - create post - - fetch feed - - notifications diff --git a/packages/react-v1/README.md b/packages/react-v1/README.md deleted file mode 100644 index 30eea58a8e..0000000000 --- a/packages/react-v1/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# `@lens-protocol/react` - -The official Lens Protocol bindings for React applications. - -This package enables you to build applications on top of the Lens Protocol using React. - -> **Note** -> -> This is a low-level package, if you are building a web application you might want to look into `@lens-protocol/react-web` package. -> -> You can use this package to build a React Native app, see the `example/react-native` example in this repo. In the future we are considering to provide a battery-included `@lens-protocol/react-native` package for RN apps. - -## Documentation - -- [GitHub monorepo](https://github.com/lens-protocol/lens-sdk) -- [Getting Started](https://docs.lens.xyz/docs/sdk-react-getting-started) - -## Troubleshooting - -These are some common issues you may run into while using `@lens-protocol/react`. If you encounter something not listed here try searching for [GitHub issues](https://github.com/lens-protocol/lens-sdk/issues). - -### Next.js build failing - -You might see your Next.js failing with an error like this: - -``` -Error: Directory import '[...]/node_modules/@apollo/client/link/context' is not supported resolving ES modules imported from [...]/node_modules/@lens-protocol/api-bindings/dist/index.js -Did you mean to import @apollo/client/link/context/context.cjs? -``` - -The root cause is the lack of ESM support from Apollo Client which manifests itself when imported as sub-dependency of `@lens-protocol/api-bindings` (which in turn is imported by `@lens-protocol/react`). See open Apollo Client [issue](https://github.com/apollographql/apollo-feature-requests/issues/287). - -To fix it you need to edit you `next.config.js` so to make sure the Lens SDK and its sub-dependencies a transpiled by Next.js build pipeline. - -```js -const nextConfig = { - transpilePackages: ['@lens-protocol'], -}; -``` - -For further details on how to integrate Lens SDK with a Next.js app, there is a working Next.js example in this monorepo: https://github.com/lens-protocol/lens-sdk/tree/main/examples/nextjs diff --git a/packages/react-v1/jest.config.ts b/packages/react-v1/jest.config.ts deleted file mode 100644 index a51f5fcaf0..0000000000 --- a/packages/react-v1/jest.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -export default { - preset: 'ts-jest/presets/js-with-ts', - setupFilesAfterEnv: ['./src/__helpers__/jest.setup.ts'], - testEnvironment: 'jsdom', - testRegex: '/__tests__/.*|(\\.|/)spec\\.tsx?$', - testPathIgnorePatterns: ['/node_modules/', '/dist/'], - - transformIgnorePatterns: [`/node_modules/\.pnpm/(?!@lens-protocol/.+)`], -}; diff --git a/packages/react-v1/package.json b/packages/react-v1/package.json deleted file mode 100644 index 8a5cfa04de..0000000000 --- a/packages/react-v1/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "react-v1", - "version": "1.3.1", - "private": true, - "description": "Interacting with the Lens Protocol API using React.", - "main": "dist/lens-protocol-react.cjs.js", - "module": "dist/lens-protocol-react.esm.js", - "exports": { - ".": { - "module": "./dist/lens-protocol-react.esm.js", - "default": "./dist/lens-protocol-react.cjs.js" - }, - "./package.json": "./package.json" - }, - "repository": { - "directory": "packages/react-v1", - "type": "git", - "url": "git://github.com/lens-protocol/lens-sdk.git" - }, - "sideEffects": false, - "files": [ - "dist", - "web" - ], - "scripts": { - "build": "exit 0", - "eslint:fix": "pnpm run eslint --fix", - "eslint": "eslint src", - "lint": "exit 0", - "lint:fix": "pnpm run prettier:fix && pnpm run eslint:fix && pnpm run tsc", - "prettier:fix": "prettier --write .", - "prettier": "prettier --check .", - "test": "exit 0", - "test:watch": "jest --watch", - "tsc": "tsc --noEmit" - }, - "license": "MIT", - "dependencies": {}, - "devDependencies": {}, - "prettier": "@lens-protocol/prettier-config", - "babel": { - "presets": [ - "@babel/preset-env", - [ - "@babel/preset-react", - { - "runtime": "automatic" - } - ], - "@babel/preset-typescript" - ] - }, - "typedoc": { - "entryPoint": "./src/index.ts", - "tsconfig": "./tsconfig.json" - } -} diff --git a/packages/react-v1/src/ConsoleLogger.ts b/packages/react-v1/src/ConsoleLogger.ts deleted file mode 100644 index fe56a08491..0000000000 --- a/packages/react-v1/src/ConsoleLogger.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* eslint-disable no-console */ -import { ILogger } from '@lens-protocol/shared-kernel'; - -export class ConsoleLogger implements ILogger { - info(message: string, data?: unknown): void { - console.info(message, data); - } - - debug(message: string, data?: unknown): void { - console.info(message, data); - } - - warn(message: string, data?: unknown): void { - console.error(message, data); - } - - error(error: Error, message?: string, data?: unknown): void { - console.error(message, error, data); - } - - fatal(error: Error, message?: string, data?: unknown): void { - console.error(message, error, data); - } -} diff --git a/packages/react-v1/src/ErrorHandler.ts b/packages/react-v1/src/ErrorHandler.ts deleted file mode 100644 index cc6cb15b9c..0000000000 --- a/packages/react-v1/src/ErrorHandler.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * A function that handles an error. - */ -export type ErrorHandler = (error: T) => void; diff --git a/packages/react-v1/src/LensProvider.tsx b/packages/react-v1/src/LensProvider.tsx deleted file mode 100644 index 2ab8925ce2..0000000000 --- a/packages/react-v1/src/LensProvider.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { ReactNode, useEffect, useRef, useState } from 'react'; - -import { ErrorHandler } from './ErrorHandler'; -import { LensConfig, validateConfig } from './config'; -import { LogoutHandler } from './lifecycle'; -import { useBootstrapController } from './lifecycle/adapters/useBootstrapController'; -import { createSharedDependencies, SharedDependenciesProvider } from './shared'; -import { FailedTransactionError } from './transactions/adapters/TransactionQueuePresenter'; - -// eslint-disable-next-line @typescript-eslint/no-empty-function -function noop() {} - -export type { ErrorHandler, FailedTransactionError }; - -/** - * props - */ -export type LensProviderProps = { - /** - * The children to render - */ - children: ReactNode; - /** - * The configuration for the Lens SDK - */ - config: LensConfig; - /** - * A callback that is called when the user logs out - * - * @defaultValue no-op - */ - onLogout?: LogoutHandler; - /** - * A callback that is called when a transaction fails - * - * @defaultValue no-op - */ - onError?: ErrorHandler; -}; - -// A specific function type would not trigger implicit any. -// See https://github.com/DefinitelyTyped/DefinitelyTyped/issues/52873#issuecomment-845806435 for a comparison between `Function` and more specific types. -// eslint-disable-next-line @typescript-eslint/ban-types -function useLatestCallback(callback: T) { - const latestCallbackRef = useRef(callback); - - useEffect(() => { - latestCallbackRef.current = callback; - }, [callback]); - - return (...args: unknown[]) => latestCallbackRef.current.apply(null, args) as T; -} - -/** - * Manages the lifecycle and internal state of the Lens SDK - * - * @group Components - * @param props - {@link LensProviderProps} - */ -export function LensProvider({ children, ...props }: LensProviderProps) { - const onError = useLatestCallback(props.onError ?? noop); - const onLogout = useLatestCallback(props.onLogout ?? noop); - - const [sharedDependencies] = useState(() => { - validateConfig(props.config); - return createSharedDependencies(props.config, { onError, onLogout }); - }); - - const isStartedRef = useRef(false); - const start = useBootstrapController(sharedDependencies); - - useEffect(() => { - // Protects again multiple calls to start (quite likely from `useEffect` hook in concurrent mode (or in strict mode)) - if (isStartedRef.current) { - return; - } - - isStartedRef.current = true; - start(); - }, [start]); - - return ( - - {children} - - ); -} diff --git a/packages/react-v1/src/NotFoundError.ts b/packages/react-v1/src/NotFoundError.ts deleted file mode 100644 index 53eb3e7801..0000000000 --- a/packages/react-v1/src/NotFoundError.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class NotFoundError extends Error { - name = 'NotFoundError' as const; - - constructor(message: string) { - super(message); - } -} diff --git a/packages/react-v1/src/__helpers__/jest.setup.ts b/packages/react-v1/src/__helpers__/jest.setup.ts deleted file mode 100644 index 4138d923be..0000000000 --- a/packages/react-v1/src/__helpers__/jest.setup.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Blob } from 'buffer'; -import crypto from 'crypto'; -import { TextEncoder, TextDecoder } from 'util'; - -Object.defineProperty(global, 'crypto', { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - value: Object.setPrototypeOf({ subtle: crypto.subtle }, crypto), -}); - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -global.Blob = Blob; - -// until https://github.com/jsdom/jsdom/issues/2524 is resolved -global.TextEncoder = TextEncoder; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -global.TextDecoder = TextDecoder; diff --git a/packages/react-v1/src/__helpers__/testing-library.tsx b/packages/react-v1/src/__helpers__/testing-library.tsx deleted file mode 100644 index cf180061c9..0000000000 --- a/packages/react-v1/src/__helpers__/testing-library.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { renderHook, RenderHookOptions } from '@testing-library/react'; -import { ReactNode } from 'react'; - -import { SharedDependencies, SharedDependenciesProvider } from '../shared'; - -type RenderHookWithMocksOptions = Omit, 'wrapper'> & { - mocks: Partial; -}; - -function createWrapper(mocks: Partial = {}) { - return function TestWrapper({ children }: { children: ReactNode }) { - return ( - - {children} - - ); - }; -} - -export function renderHookWithMocks( - callback: (props: TProps) => TResult, - options?: RenderHookWithMocksOptions, -) { - return renderHook(callback, { - wrapper: createWrapper(options?.mocks), - ...options, - }); -} diff --git a/packages/react-v1/src/__tests__/config.spec.ts b/packages/react-v1/src/__tests__/config.spec.ts deleted file mode 100644 index 5f12c0d470..0000000000 --- a/packages/react-v1/src/__tests__/config.spec.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { InvariantError } from '@lens-protocol/shared-kernel'; -import { providers } from 'ethers'; - -import { IBindings, LensConfig, validateConfig } from '../config'; -import { staging } from '../environments'; -import { appId } from '../utils'; - -class DummyStorageProvider { - getItem(key: string) { - return key; - } - setItem(): void {} - removeItem(): void {} -} - -function bindings(): IBindings { - const provider = new providers.JsonRpcProvider(); - return { - getProvider: async () => provider, - getSigner: async () => provider.getSigner(), - }; -} - -const configBase = { - bindings: bindings(), - environment: staging, - storage: new DummyStorageProvider(), -}; - -const testAppId = appId('test'); - -describe(`Given the ${validateConfig.name} helper`, () => { - beforeAll(() => { - jest.spyOn(console, 'warn').mockImplementation(() => {}); - }); - - describe(`when the config has no "appId" nor "sources" defined`, () => { - it(`should pass the validation`, async () => { - const config: LensConfig = { - ...configBase, - }; - - expect(() => validateConfig(config)).not.toThrow(); - }); - }); - - describe(`when the config defines "appId" and no "sources"`, () => { - it(`should pass the validation`, async () => { - const config: LensConfig = { - ...configBase, - appId: testAppId, - }; - - expect(() => validateConfig(config)).not.toThrow(); - }); - }); - - describe(`when the config defines "appId" and "sources" include the same "appId"`, () => { - it(`should pass the validation`, async () => { - const config: LensConfig = { - ...configBase, - appId: testAppId, - sources: [testAppId], - }; - - expect(() => validateConfig(config)).not.toThrow(); - }); - }); - - describe(`when the config defines "appId" and "sources", but "sources" don't include the same "appId"`, () => { - it(`should throw an ${InvariantError.name}`, async () => { - const config: LensConfig = { - ...configBase, - appId: testAppId, - sources: [], - }; - - expect(() => validateConfig(config)).toThrow(InvariantError); - }); - }); -}); diff --git a/packages/react-v1/src/chains.ts b/packages/react-v1/src/chains.ts deleted file mode 100644 index 75160639f8..0000000000 --- a/packages/react-v1/src/chains.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { CryptoNativeAsset, ChainType, ether, matic } from '@lens-protocol/shared-kernel'; - -/** - * A chain configuration - * - * @internal - */ -export type ChainConfig = { - chainId: number; - name: string; - rpcUrl: string; - blockExplorer: string; - nativeCurrency: CryptoNativeAsset; -}; - -/** - * @internal - */ -export const mainnet: ChainConfig = { - chainId: 1, - name: 'Ethereum', - rpcUrl: 'https://mainnet.infura.io/v3', - blockExplorer: 'https://etherscan.io/', - nativeCurrency: ether(), -}; - -/** - * @internal - */ -export const goerli: ChainConfig = { - chainId: 5, - name: 'Goerli', - rpcUrl: 'https://goerli.infura.io/v3', - blockExplorer: 'https://goerli.etherscan.io/', - nativeCurrency: ether(), -}; - -/** - * @internal - */ -export const polygon: ChainConfig = { - chainId: 137, - name: 'Polygon Mainnet', - rpcUrl: 'https://polygon-rpc.com/', - blockExplorer: 'https://polygonscan.com/', - nativeCurrency: matic(), -}; - -/** - * @internal - */ -export const mumbai: ChainConfig = { - chainId: 80001, - name: 'Polygon Testnet Mumbai', - rpcUrl: 'https://rpc-mumbai.maticvigil.com/', - blockExplorer: 'https://mumbai.polygonscan.com/', - nativeCurrency: matic(), -}; - -/** - * A registry of chain configurations - * - * @internal - */ -export type ChainConfigRegistry = Record; diff --git a/packages/react-v1/src/config.ts b/packages/react-v1/src/config.ts deleted file mode 100644 index 65616ec642..0000000000 --- a/packages/react-v1/src/config.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { AppId } from '@lens-protocol/domain/entities'; -import { AuthenticationConfig, IEncryptionProvider, ICipher } from '@lens-protocol/gated-content'; -import { ILogger, invariant } from '@lens-protocol/shared-kernel'; -import { IObservableStorageProvider, IStorageProvider } from '@lens-protocol/storage'; - -import { EnvironmentConfig } from './environments'; -import { MediaTransformsConfig } from './mediaTransforms'; -import { createGatedClient } from './transactions/infrastructure/createGatedClient'; -import { IProviderBinding, GetProvider } from './wallet/infrastructure/ProviderFactory'; -import { ISignerBinding, GetSigner } from './wallet/infrastructure/SignerFactory'; - -export type { ILogger, AuthenticationConfig, IEncryptionProvider, ICipher }; - -export type { GetProvider, GetSigner }; - -export interface IBindings extends ISignerBinding, IProviderBinding {} - -/** - * `` configuration - */ -export type LensConfig = { - /** - * Provides integration with the ethers.js Signer and Provider - */ - bindings: IBindings; - /** - * The environment to use. See {@link production}, {@link development}, and {@link sandbox} - */ - environment: EnvironmentConfig; - /** - * The logger interface to use when something worth logging happens - * - * @defaultValue `ConsoleLogger`, an internal implementation of {@link ILogger} that logs to the console - */ - logger?: ILogger; - /** - * The storage provider to use. - * - * If a implementation of {@link IObservableStorageProvider} is provided, - * the provider will be used to subscribe to changes in the storage. - */ - storage: IStorageProvider | IObservableStorageProvider; - /** - * The `sources` determines the sources of posts and comments that will be fetched - * - * It also determines some Profile related statistics, such as the number of posts and comments. - * - * @defaultValue any sources, not restricted - */ - sources?: AppId[]; - /** - * The `appId` identifies post and comment created from the SDK - * - * The `appId`, if provided, MUST be included in the `sources` array. - * - * @defaultValue not set - * - * @see {@link appId} helper - */ - appId?: AppId; - - /** - * Media returned from the publication and profile queries can be transformed - * to sizes needed by the SDK consuming application. - * To overwrite default transformation values, provide a `mediaTransforms` object. - * - * @see {@link MediaTransformsConfig} for more information - */ - mediaTransforms?: MediaTransformsConfig; -}; - -/** - * Encryption configuration for token-gated content - */ -export type EncryptionConfig = { - authentication: AuthenticationConfig; - provider: IEncryptionProvider; - - /** - * @internal - */ - createGatedClient?: typeof createGatedClient; -}; - -/** @internal */ -export function validateConfig(config: LensConfig) { - invariant( - !(config.appId && config.sources && !config.sources?.includes(config.appId)), - `LensProvider config: "sources" don't include your "appId"`, - ); -} diff --git a/packages/react-v1/src/deprecated.ts b/packages/react-v1/src/deprecated.ts deleted file mode 100644 index 08223dea80..0000000000 --- a/packages/react-v1/src/deprecated.ts +++ /dev/null @@ -1,314 +0,0 @@ -import { - AnyPublication, - Attribute, - Comment, - ContentPublication, - EnabledModule, - EnabledModules, - FeeFollowModuleSettings, - Follower, - Following, - Media, - MetadataAttributeOutput, - MetadataOutput, - Mirror, - ModuleInfo, - NewCollectNotification, - NewCommentNotification, - NewFollowerNotification, - NewMentionNotification, - NewMirrorNotification, - NewReactionNotification, - NftImage, - PendingPost, - Post, - Profile, - ProfileAttributeReader, - ProfileAttributes, - ProfileFollowModuleSettings, - ProfileOwnedByMe, - ProfileStats, - PublicationOwnedByMe, - PublicationRevenue, - PublicationStats, - ReactionTypes, - RevenueAggregate, - RevertFollowModuleSettings, - TransactionState, - UnknownFollowModuleSettings, - WhoReactedResult, -} from '@lens-protocol/api-bindings'; -import { - MetadataAttribute, - MetadataAttributeDisplayType, -} from '@lens-protocol/domain/use-cases/publications'; -import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; -import { LoginError } from '@lens-protocol/domain/use-cases/wallets'; - -/** - * @deprecated Use {@link EnabledModules} instead. - */ -export type EnabledModulesFragment = EnabledModules; - -/** - * @deprecated Use {@link EnabledModule} instead. - */ -export type EnabledModuleFragment = EnabledModule; - -/** - * @deprecated Use {@link ModuleInfo} instead. - */ -export type ModuleInfoFragment = ModuleInfo; - -/** - * @deprecated This is not exposed by any hook so you should not need it. - */ -export type PaginatedResultInfo = { - __typename: 'PaginatedResultInfo'; - prev: string | null; - next: string | null; - totalCount: number | null; -}; - -/** - * @deprecated Use {@link PaginatedResultInfo} instead. - */ -export type CommonPaginatedResultInfoFragment = PaginatedResultInfo; - -/** - * @deprecated Use {@link PaginatedResultInfo} instead. - */ -export type CommonPaginatedResultInfo = PaginatedResultInfo; - -/** - * @deprecated Use {@link NewCollectNotification} instead. - */ -export type NewCollectNotificationFragment = NewCollectNotification; - -/** - * @deprecated Use {@link NewCommentNotification} instead. - */ -export type NewCommentNotificationFragment = NewCommentNotification; - -/** - * @deprecated Use {@link NewFollowerNotification} instead. - */ -export type NewFollowerNotificationFragment = NewFollowerNotification; - -/** - * @deprecated Use {@link NewMentionNotification} instead. - */ -export type NewMentionNotificationFragment = NewMentionNotification; - -/** - * @deprecated Use {@link NewMirrorNotification} instead. - */ -export type NewMirrorNotificationFragment = NewMirrorNotification; - -/** - * @deprecated Use {@link NewReactionNotification} instead. - */ -export type NewReactionNotificationFragment = NewReactionNotification; - -/** - * @deprecated Use {@link Attribute} instead. - */ -export type AttributeFragment = Attribute; - -/** - * @deprecated Use {@link Follower} instead. - */ -export type FollowerFragment = Follower; - -/** - * @deprecated Use {@link Following} instead. - */ -export type FollowingFragment = Following; - -/** - * @deprecated Use {@link ProfileAttributeReader} instead. - */ -export type ProfileAttributeReaderFragment = ProfileAttributeReader; - -/** - * @deprecated Use {@link ProfileAttributes} instead. - */ -export type ProfileAttributesFragment = ProfileAttributes; - -/** - * @deprecated Use {@link Profile} instead. - */ -export type ProfileFragment = Profile; - -/** - * @deprecated Use {@link ProfileOwnedByMe} instead. - */ -export type ProfileOwnedByMeFragment = ProfileOwnedByMe; - -/** - * @deprecated Use {@link ProfileStats} instead. - */ -export type ProfileStatsFragment = ProfileStats; - -/** - * @deprecated Use {@link FeeFollowModuleSettings} instead. - */ -export type FeeFollowModuleSettingsFragment = FeeFollowModuleSettings; - -/** - * @deprecated Use {@link ProfileFollowModuleSettings} instead. - */ -export type ProfileFollowModuleSettingsFragment = ProfileFollowModuleSettings; - -/** - * @deprecated Use {@link RevertFollowModuleSettings} instead. - */ -export type RevertFollowModuleSettingsFragment = RevertFollowModuleSettings; - -/** - * @deprecated Use {@link UnknownFollowModuleSettings} instead. - */ -export type UnknownFollowModuleSettingsFragment = UnknownFollowModuleSettings; - -/** - * @deprecated Use {@link AnyPublication} instead. - */ -export type AnyPublicationFragment = AnyPublication; - -/** - * @deprecated Use {@link Comment} instead. - */ -export type CommentFragment = Comment; - -/** - * @deprecated Use {@link Comment} instead. - */ -export type CommentWithFirstCommentFragment = Comment; - -/** - * @deprecated Use {@link Comment} instead. - */ -export type CommentWithFirstComment = Comment; - -/** - * @deprecated Use {@link ContentPublication} instead. - */ -export type ContentPublicationFragment = ContentPublication; - -/** - * @deprecated Use {@link Media} instead. - */ -export type MediaFragment = Media; - -/** - * @deprecated Use {@link MediaSet} instead. - */ -export type MediaSetFragment = MediaSet; - -/** - * @deprecated Use {@link MetadataAttributeOutput} instead. - */ -export type MetadataAttributeOutputFragment = MetadataAttributeOutput; - -/** - * @deprecated Use {@link MetadataOutput} instead. - */ -export type MetadataOutputFragment = MetadataOutput; - -/** - * @deprecated Use {@link Mirror} instead. - */ -export type MirrorFragment = Mirror; - -/** - * @deprecated Use {@link PendingPost} instead. - */ -export type PendingPostFragment = PendingPost; - -/** - * @deprecated Use {@link Post} instead. - */ -export type PostFragment = Post; - -/** - * @deprecated Use {@link PublicationOwnedByMe} instead. - */ -export type PublicationOwnedByMeFragment = PublicationOwnedByMe; - -/** - * @deprecated Use {@link PublicationStats} instead. - */ -export type PublicationStatsFragment = PublicationStats; - -/** - * @deprecated Use {@link RevenueAggregate} instead. - */ -export type RevenueAggregateFragment = RevenueAggregate; - -/** - * @deprecated Use {@link WhoReactedResult} instead. - */ -export type WhoReactedResultFragment = WhoReactedResult; - -/** - * @deprecated Use {@link PublicationRevenue} instead. - */ -export type PublicationRevenueFragment = PublicationRevenue; - -/** - * @deprecated Use {@link TransactionState} instead. - */ -export type BroadcastedTransactionData = TransactionState; - -/** - * @deprecated Use {@link TransactionState} instead. - */ -export type PendingTransactionData = TransactionState; - -/** - * @deprecated Use {@link AnyTransactionRequest} instead. - */ -export type TransactionRequestModel = AnyTransactionRequest; - -/** - * @deprecated Use {@link AnyTransactionRequest} instead. - */ -export type SupportedTransactionRequest = AnyTransactionRequest; - -/** - * @deprecated Use {@link LoginError} instead. - */ -export type WalletLoginPotentialErrors = LoginError; - -/** - * @deprecated Use {@link ProfilePictureMedia} or {@link ProfileCoverMedia} instead. - */ -export type ProfileMediaFragment = MediaSet | NftImage; - -/** - * @deprecated Use {@link ProfilePictureMedia} or {@link ProfileCoverMedia} instead. - */ -export type ProfileMedia = ProfileMediaFragment; - -/** - * @deprecated Use {@link ProfilePictureMedia}, {@link ProfileCoverMedia} or {@link PublicationMediaSet} instead. - */ -export type MediaSet = { __typename: 'MediaSet'; original: Media }; - -/** - * @deprecated Use {@link ReactionTypes} instead. - */ -export enum ReactionType { - UPVOTE = ReactionTypes.Upvote, - DOWNVOTE = ReactionTypes.Downvote, -} - -/** - * @deprecated Use {@link MetadataAttribute} instead. - */ -export type NftAttribute = MetadataAttribute; - -/** - * @deprecated Use {@link MetadataAttributeDisplayType} instead. - */ -export type NftAttributeDisplayType = MetadataAttributeDisplayType; diff --git a/packages/react-v1/src/environments.ts b/packages/react-v1/src/environments.ts deleted file mode 100644 index 3fbe732b40..0000000000 --- a/packages/react-v1/src/environments.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { ContentInsightMatcher, demoSnapshotPoll, snapshotPoll } from '@lens-protocol/api-bindings'; -import * as GatedEnvironments from '@lens-protocol/gated-content/environments'; -import { ChainType, Url } from '@lens-protocol/shared-kernel'; - -import { ChainConfigRegistry, goerli, mainnet, mumbai, polygon } from './chains'; -import { TransactionObserverTimings } from './transactions/infrastructure/TransactionObserver'; - -export type { TransactionObserverTimings }; - -/** - * The Snapshot.org integration configuration - * - * @internal - */ -export type SnapshotConfig = { - hub: Url; - sequencer: Url; - matcher: ContentInsightMatcher; -}; - -/** - * A function that resolves a profile handle to a fully qualified profile handle - * - * @internal - */ -export type ProfileHandleResolver = (handle: string) => string; - -/** - * The environment configuration type - * - * @internal - */ -export type EnvironmentConfig = { - name: 'production' | 'development' | 'sandbox' | string; - backend: Url; - chains: ChainConfigRegistry; - timings: TransactionObserverTimings; - handleResolver: ProfileHandleResolver; - snapshot: SnapshotConfig; - gated: GatedEnvironments.EnvironmentConfig; - xmtpEnv: { - name: 'production' | 'dev' | 'local'; - }; -}; - -/** - * The production environment configuration - * - * This is the environment to be used in the live instance of your application (real users, real profiles, real data). - * - * - Endpoint: https://api.lens.dev - * - Chain IDs: 137 (Polygon), 1 (Ethereum) - * - Profile handle suffix: `.lens` - * - Environment specific timings - */ -export const production: EnvironmentConfig = { - name: 'production', - backend: 'https://api.lens.dev', - chains: { - [ChainType.ETHEREUM]: mainnet, - [ChainType.POLYGON]: polygon, - }, - timings: { - pollingInterval: 3000, - maxIndexingWaitTime: 120000, - maxMiningWaitTime: 60000, - }, - handleResolver: (handle) => `${handle}.lens`, - snapshot: { - hub: 'https://hub.snapshot.org', - matcher: snapshotPoll, - sequencer: 'https://seq.snapshot.org', - }, - gated: GatedEnvironments.production, - xmtpEnv: { - name: 'production', - }, -}; -/** - * The development environment configuration - * - * This is the environment to be used when you develop and test your application (test users, test profiles, test data) - * - * - Endpoint: https://api-mumbai.lens.dev - * - Chain IDs: 80001 (Mumbai), 5 (Goerli) - * - Profile handle suffix: `.test` - * - Environment specific timings - */ -export const development: EnvironmentConfig = { - name: 'development', - backend: 'https://api-mumbai.lens.dev', - chains: { - [ChainType.ETHEREUM]: goerli, - [ChainType.POLYGON]: mumbai, - }, - timings: { - pollingInterval: 3000, - maxIndexingWaitTime: 240000, - maxMiningWaitTime: 120000, - }, - handleResolver: (handle) => `${handle}.test`, - snapshot: { - hub: 'https://testnet.snapshot.org', - matcher: demoSnapshotPoll, - sequencer: 'https://testnet.seq.snapshot.org', - }, - gated: GatedEnvironments.development, - xmtpEnv: { - name: 'dev', - }, -}; - -/** - * The sandbox environment configuration - * - * This is the environment to be used when you develop and you need to experiment with custom collect/follow modules. - * Although the Lens contract are also deployed on Mumbai this is a separate deployment so expect different test data, profiles, users, etc. - * - * - Endpoint: https://api-sandbox-mumbai.lens.dev - * - Chain IDs: 80001 (Mumbai), 5 (Goerli) - * - Profile handle suffix: `.test` - * - Environment specific timings - */ -export const sandbox: EnvironmentConfig = { - name: 'sandbox', - backend: 'https://api-sandbox-mumbai.lens.dev', - chains: { - [ChainType.ETHEREUM]: goerli, - [ChainType.POLYGON]: mumbai, - }, - timings: { - pollingInterval: 3000, - maxIndexingWaitTime: 240000, - maxMiningWaitTime: 120000, - }, - handleResolver: (handle) => `${handle}.test`, - snapshot: { - hub: 'https://testnet.snapshot.org', - matcher: demoSnapshotPoll, - sequencer: 'https://testnet.seq.snapshot.org', - }, - gated: GatedEnvironments.sandbox, - xmtpEnv: { - name: 'dev', - }, -}; - -/** - * The development environment configuration - * - * @deprecated Please use the {@link development} variable instead - * - * After extensive considerations, we have decided to rename the `staging` variable into `development`. - * We find that the term `staging` is inflated with too many meanings and people have different expectations - * depending on their past work experiences. So the term is not very intelligible for our purpose. - * - * Together with {@link production} the changes is meant to be more explicit about the intended usage of these variables. - * - * - `production` is the environment to be used in the live instance of your application (real users, real profiles, real data). - * - `development` is the environment to be used when you develop and test your application (test users, test profiles, test data). - * - * We also aligned the naming in the `@lens-protocol/client` package to enable interoperability between the two packages. - */ -export const staging = development; diff --git a/packages/react-v1/src/experimental/index.ts b/packages/react-v1/src/experimental/index.ts deleted file mode 100644 index 16e72d8bca..0000000000 --- a/packages/react-v1/src/experimental/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './useAccessToken'; -export * from './useApolloClient'; diff --git a/packages/react-v1/src/experimental/useAccessToken.ts b/packages/react-v1/src/experimental/useAccessToken.ts deleted file mode 100644 index a291905939..0000000000 --- a/packages/react-v1/src/experimental/useAccessToken.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { useSharedDependencies } from '../shared'; - -/** - * Returns the current access token. - * - * @defaultValue `null` if not authenticated. - * @experimental This API is experimental and might change in the future. - */ -export function useAccessToken() { - const { accessTokenStorage } = useSharedDependencies(); - - return accessTokenStorage.getAccessToken(); -} diff --git a/packages/react-v1/src/experimental/useApolloClient.ts b/packages/react-v1/src/experimental/useApolloClient.ts deleted file mode 100644 index a70298880b..0000000000 --- a/packages/react-v1/src/experimental/useApolloClient.ts +++ /dev/null @@ -1,36 +0,0 @@ -// eslint-disable-next-line no-restricted-imports -import type { ApolloClient, NormalizedCacheObject } from '@apollo/client'; - -import { useSharedDependencies } from '../shared'; - -/** - * Returns the internal Apollo Client instance. - * - * If you already signed in, the instance will be already include Access Token credentials in its requests. - * - * The internal Apollo Client instance is configured so that it automatically renews credentials (both Access Token and Refresh Token) when they expire. - * This is done transparently, so you don't need to worry about it. - * - * @example - * Perform a query - * ```ts - * import { useQuery, gql} from '@apollo/client'; - * import { useApolloClient } from '@lens-protocol/react-web'; - * - * function MyComponent() { - * const client = useApolloClient(); - * const { data, loading, error } = useQuery(gql``, { client }) - * - * // use the low-level useQuery response - * } - * ``` - * - * @experimental This hook is experimental and may change in the future. - * @category Misc - * @group Hooks - */ -export function useApolloClient(): ApolloClient { - const { apolloClient } = useSharedDependencies(); - - return apolloClient; -} diff --git a/packages/react-v1/src/feed/FeedEventItemType.ts b/packages/react-v1/src/feed/FeedEventItemType.ts deleted file mode 100644 index bfb52bde01..0000000000 --- a/packages/react-v1/src/feed/FeedEventItemType.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { FeedEventItemType as LensFeedEventItemType } from '@lens-protocol/api-bindings'; - -export enum FeedEventItemType { - Comment = LensFeedEventItemType.Comment, - Post = LensFeedEventItemType.Post, - Mirror = LensFeedEventItemType.Mirror, - CollectComment = LensFeedEventItemType.CollectComment, - CollectPost = LensFeedEventItemType.CollectPost, -} diff --git a/packages/react-v1/src/feed/__tests__/useFeed.spec.ts b/packages/react-v1/src/feed/__tests__/useFeed.spec.ts deleted file mode 100644 index 1967e0598b..0000000000 --- a/packages/react-v1/src/feed/__tests__/useFeed.spec.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { FeedEventItemType as LensFeedEventItemType, FeedItem } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockFeedItemFragment, - mockFeedResponse, - mockSources, - simulateAuthenticatedProfile, - simulateAuthenticatedWallet, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfileId, mockProfileIdentifier } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { FeedEventItemType } from '../FeedEventItemType'; -import { useFeed } from '../useFeed'; - -function setupTestScenario({ - profileId, - observerId, - expectedObserverId, - items, -}: { - profileId: ProfileId; - observerId?: ProfileId; - expectedObserverId: ProfileId | null; - items: FeedItem[]; -}) { - const sources = mockSources(); - - return renderHookWithMocks( - () => - useFeed({ - profileId, - observerId, - restrictEventTypesTo: [FeedEventItemType.Post], - }), - { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockFeedResponse({ - variables: { - profileId, - observerId: expectedObserverId, - restrictEventTypesTo: [LensFeedEventItemType.Post], - limit: 50, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - items, - }), - ]), - }, - }, - ); -} - -describe(`Given the ${useFeed.name} hook`, () => { - const profileId = mockProfileId(); - const items = [mockFeedItemFragment(), mockFeedItemFragment()]; - const expectations = items.map(({ __typename }) => ({ __typename })); - - describe('when the query returns data successfully', () => { - beforeAll(() => { - simulateAuthenticatedWallet(); - }); - - it('should return the feed', async () => { - const { result } = setupTestScenario({ profileId, items, expectedObserverId: null }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfileIdentifier(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - profileId, - items, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - profileId, - items, - observerId, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/feed/index.ts b/packages/react-v1/src/feed/index.ts deleted file mode 100644 index ac63d3d694..0000000000 --- a/packages/react-v1/src/feed/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './useFeed'; -export * from './FeedEventItemType'; - -export type { - FeedItem, - CollectedEvent, - ElectedMirror, - MirrorEvent, - ReactionEvent, -} from '@lens-protocol/api-bindings'; diff --git a/packages/react-v1/src/feed/useFeed.ts b/packages/react-v1/src/feed/useFeed.ts deleted file mode 100644 index 0004560f7a..0000000000 --- a/packages/react-v1/src/feed/useFeed.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { - FeedEventItemType as LensFeedEventItemType, - FeedItem, - useFeed as useUnderlyingQuery, -} from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { nonNullable } from '@lens-protocol/shared-kernel'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { - createPublicationMetadataFilters, - PublicationMetadataFilters, -} from '../publication/filters'; -import { FeedEventItemType } from './FeedEventItemType'; - -const SupportedFeedEvenTypesMap: Record = { - [FeedEventItemType.Comment]: LensFeedEventItemType.Comment, - [FeedEventItemType.Post]: LensFeedEventItemType.Post, - [FeedEventItemType.Mirror]: LensFeedEventItemType.Mirror, - [FeedEventItemType.CollectComment]: LensFeedEventItemType.CollectComment, - [FeedEventItemType.CollectPost]: LensFeedEventItemType.CollectPost, -}; - -const mapRestrictEventTypesToLensTypes = (restrictEventTypesTo?: FeedEventItemType[]) => { - return restrictEventTypesTo?.map((type) => - nonNullable(SupportedFeedEvenTypesMap[type], "Can't map the feed event type"), - ); -}; - -// feed limit is higher than others to get good aggregation of feed items -const FEED_LIMIT = 50; - -export type UseFeedArgs = PaginatedArgs< - WithObserverIdOverride<{ - profileId: ProfileId; - restrictEventTypesTo?: FeedEventItemType[]; - metadataFilter?: PublicationMetadataFilters; - }> ->; - -/** - * `useFeed` is a paginated hook that lets you read the feed of a given profile - * - * You MUST be authenticated via {@link useWalletLogin} to use this hook. - * - * @category Discovery - * @group Hooks - * @param args - {@link UseFeedArgs} - * - * @example - * ```tsx - * import { useFeed, ProfileId } from '@lens-protocol/react-web'; - * - * function Feed({ profileId }: { profileId: ProfileId }) { - * const { data, loading, error } = useFeed({ profileId }); - * - * if (loading) return
Loading...
; - * - * if (error) return
Error: {error.message}
; - * - * return ( - *
    - * {data.map((item, idx) => ( - *
  • - * // render item details - *
  • - * ))} - *
- * ); - * } - * ``` - */ -export function useFeed({ - metadataFilter, - restrictEventTypesTo, - observerId, - profileId, - limit = FEED_LIMIT, -}: UseFeedArgs): PaginatedReadResult { - return usePaginatedReadResult( - useUnderlyingQuery( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - metadata: createPublicationMetadataFilters(metadataFilter), - restrictEventTypesTo: mapRestrictEventTypesToLensTypes(restrictEventTypesTo), - profileId, - observerId, - limit, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/helpers/__tests__/operations.spec.ts b/packages/react-v1/src/helpers/__tests__/operations.spec.ts deleted file mode 100644 index 8188163cf0..0000000000 --- a/packages/react-v1/src/helpers/__tests__/operations.spec.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Deferred, failure, Result, success } from '@lens-protocol/shared-kernel'; -import { act, renderHook } from '@testing-library/react'; - -import { OperationHandler, useOperation } from '../operations'; - -describe(`Given the ${useOperation.name} hook`, () => { - describe(`when invoking the "execute" callback`, () => { - it('should call the provided handler function with the arguments passed to the execute method', async () => { - const fn: OperationHandler = jest.fn().mockResolvedValue(success()); - const { result } = renderHook(() => useOperation(fn)); - - const anyArgs = [1, '2', true, { a: 1 }, [1, 2, 3]] as const; - await act(() => result.current.execute(...anyArgs)); - - expect(fn).toHaveBeenCalledWith(...anyArgs); - }); - - it(`should return an 'isPending' flag that stays true while the operation is progress, false otherwise`, async () => { - const deferred = new Deferred>(); - const fn: OperationHandler = () => deferred.promise; - const { result } = renderHook(() => useOperation(fn)); - - expect(result.current.isPending).toBe(false); - - void act(() => { - void result.current.execute(); - }); - - expect(result.current.isPending).toBe(true); - - await act(async () => { - deferred.resolve(success()); - }); - - expect(result.current.isPending).toBe(false); - }); - - it(`should reset the 'isPending' flag even if the operation handler throws`, async () => { - const fn: OperationHandler = jest - .fn() - .mockRejectedValue(new Error('Something went wrong')); - const { result } = renderHook(() => useOperation(fn)); - - expect(result.current.isPending).toBe(false); - - await act(async () => { - try { - await result.current.execute(); - } catch { - /* empty */ - } - }); - - expect(result.current.isPending).toBe(false); - }); - - it(`should return any operation error as state`, async () => { - const error = new Error('Something went wrong'); - const fn: OperationHandler = jest.fn().mockResolvedValue(failure(error)); - - const { result } = renderHook(() => useOperation(fn)); - - const r = await act(() => result.current.execute()); - - expect(() => r.unwrap()).toThrow(error); - expect(result.current.error).toEqual(error); - }); - - it(`should reset previous errors if the operation is executed again`, async () => { - const error = new Error('Something went wrong'); - const fn: OperationHandler = jest - .fn() - .mockResolvedValueOnce(failure(error)) - .mockResolvedValue(success()); - - const { result } = renderHook(() => useOperation(fn)); - - await act(() => result.current.execute()); - expect(result.current.error).toEqual(error); - - await act(() => result.current.execute()); - expect(result.current.error).toBeUndefined(); - }); - }); -}); diff --git a/packages/react-v1/src/helpers/__tests__/reads.spec.ts b/packages/react-v1/src/helpers/__tests__/reads.spec.ts deleted file mode 100644 index c29907e4cf..0000000000 --- a/packages/react-v1/src/helpers/__tests__/reads.spec.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { ApolloError, gql, QueryResult as ApolloQueryResult, useQuery } from '@apollo/client'; -import { MockedResponse } from '@apollo/client/testing'; -import { SafeApolloClient, UnspecifiedError } from '@lens-protocol/api-bindings'; -import { mockLensApolloClient } from '@lens-protocol/api-bindings/mocks'; -import { renderHook, RenderHookResult, waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { QueryData, usePaginatedReadResult, useReadResult } from '../reads'; - -const document = gql` - query Ping { - result: ping - } -`; - -function mockQueryResponse>(data: TData): MockedResponse { - return { - request: { - query: document, - }, - result: { data }, - }; -} - -function mockQueryError(error: ApolloError): MockedResponse> { - return { - request: { - query: document, - }, - error, - }; -} - -function setupTestScenario(client: SafeApolloClient) { - return { - renderHook( - callback: (props: TProps) => TResult, - ): RenderHookResult { - return renderHookWithMocks(callback, { - mocks: { - apolloClient: client, - }, - }); - }, - }; -} - -describe(`Given the read hook helpers`, () => { - describe(`when rendering an hook created via the ${useReadResult.name} helper`, () => { - it('should return the data at the end of the initial loading phase', async () => { - const client = mockLensApolloClient([mockQueryResponse({ result: true })]); - const { result } = renderHook(() => useReadResult(useQuery(document, { client }))); - - expect(result.current).toMatchObject({ - error: undefined, - data: undefined, - loading: true, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - - expect(result.current).toMatchObject({ - data: true, - loading: false, - }); - }); - - it(`should wrap any error into ${UnspecifiedError.name}`, async () => { - const cause = new ApolloError({ graphQLErrors: [] }); - const queryResult = { error: cause, data: undefined, loading: false } as ApolloQueryResult< - QueryData - >; - const { result } = renderHook(() => useReadResult(queryResult)); - - expect(result.current).toMatchObject({ - error: expect.any(UnspecifiedError), - data: undefined, - loading: false, - }); - }); - - it(`should return data if immediately available without flickering the loading flag and then update it with fresh data as it updates`, async () => { - const client = mockLensApolloClient([ - mockQueryResponse({ result: true }), - mockQueryResponse({ result: false }), - ]); - - const first = renderHook(() => useReadResult(useQuery(document, { client }))); - await waitFor(() => expect(first.result.current.loading).toBeFalsy()); - - const second = renderHook(() => - useReadResult( - useQuery(document, { - client, - fetchPolicy: 'cache-and-network', - nextFetchPolicy: 'cache-first', - }), - ), - ); - - expect(second.result.current).toMatchObject({ - data: true, - loading: false, - }); - await waitFor(() => expect(first.result.current.data).toBeFalsy()); - }); - }); - - describe(`when rendering an hook created via the ${usePaginatedReadResult.name} helper`, () => { - const error = new ApolloError({ graphQLErrors: [] }); - const client = mockLensApolloClient([mockQueryError(error)]); - const { renderHook } = setupTestScenario(client); - - it(`should wrap any error into ${UnspecifiedError.name}`, async () => { - const { result } = renderHook(() => usePaginatedReadResult(useQuery(document, { client }))); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current).toMatchObject({ - error: expect.any(UnspecifiedError), - data: undefined, - loading: false, - }); - }); - }); -}); diff --git a/packages/react-v1/src/helpers/arguments.ts b/packages/react-v1/src/helpers/arguments.ts deleted file mode 100644 index d0b6f06c14..0000000000 --- a/packages/react-v1/src/helpers/arguments.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { OperationVariables, WatchQueryFetchPolicy } from '@apollo/client'; -import { - createSnapshotApolloClient, - MediaTransformParams, - SafeApolloClient, - SessionType, - Sources, - useSessionVar, -} from '@lens-protocol/api-bindings'; -import { AppId, ProfileId } from '@lens-protocol/domain/entities'; -import { Overwrite, Prettify, UnknownObject } from '@lens-protocol/shared-kernel'; -import { useState } from 'react'; - -import { mediaTransformConfigToQueryVariables } from '../mediaTransforms'; -import { useSharedDependencies } from '../shared'; - -export type UseApolloClientResult = TOptions & { - client: SafeApolloClient; -}; - -export function useLensApolloClient( - args: TOptions = {} as TOptions, -): UseApolloClientResult { - const { apolloClient: client } = useSharedDependencies(); - - return { - ...args, - client, - }; -} - -export function useSnapshotApolloClient( - args: TOptions = {} as TOptions, -): UseApolloClientResult { - const { environment } = useSharedDependencies(); - - const [client] = useState(() => - createSnapshotApolloClient({ - backendURL: environment.snapshot.hub, - }), - ); - - return { - ...args, - client, - }; -} - -/** - * When `skip` prop is true then all other props are optional. - * Used to allow to skip apollo API calls - */ -export type Skippable = - | (Partial & { - /** - * @experimental - */ - skip: true; - }) - | (T & { skip?: false }); - -export type WithObserverIdOverride = Prettify< - TVariables & { - /** - * The ID of the profile that is observing the data. - * - * @defaultValue The ID of the Active Profile if it exists, otherwise `null` - */ - observerId?: ProfileId; - } ->; - -export type UseActiveProfileAsDefaultObserverArgs = { - skip?: boolean; - variables: WithObserverIdOverride; - fetchPolicy?: WatchQueryFetchPolicy; - nextFetchPolicy?: WatchQueryFetchPolicy; -}; - -export type UseActiveProfileAsDefaultObserverResultVariables = TVariables & { - observerId: ProfileId | null; -}; - -export type UseActiveProfileAsDefaultObserverResult = Prettify< - Overwrite< - UseActiveProfileAsDefaultObserverArgs, - { - variables: UseActiveProfileAsDefaultObserverResultVariables; - skip: boolean; - } - > ->; - -export function useActiveProfileAsDefaultObserver({ - skip, - variables, - ...others -}: UseActiveProfileAsDefaultObserverArgs): UseActiveProfileAsDefaultObserverResult { - const session = useSessionVar(); - - return { - ...others, - variables: { - ...variables, - observerId: - variables.observerId ?? - (session && session.type === SessionType.WithProfile ? session.profile.id : null), - }, - skip: skip || !session, - }; -} - -export type UseSourcesFromConfigResult = TVariables & { - sources: Sources; -}; - -export function useSourcesFromConfig( - variables: TVariables, -): UseSourcesFromConfigResult { - const { sources } = useSharedDependencies(); - - return { - ...variables, - sources: variables.sources ?? sources, - }; -} - -export type UseMediaTransformFromConfigResult = - TVariables & { - mediaTransformPublicationSmall: MediaTransformParams; - mediaTransformPublicationMedium: MediaTransformParams; - mediaTransformProfileThumbnail: MediaTransformParams; - }; - -export function useMediaTransformFromConfig( - variables: TVariables, -): UseMediaTransformFromConfigResult { - const { mediaTransforms } = useSharedDependencies(); - - return { - ...variables, - ...mediaTransformConfigToQueryVariables(mediaTransforms), - }; -} diff --git a/packages/react-v1/src/helpers/operations.ts b/packages/react-v1/src/helpers/operations.ts deleted file mode 100644 index e0f87c05b7..0000000000 --- a/packages/react-v1/src/helpers/operations.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { IEquatableError, PromiseResult } from '@lens-protocol/shared-kernel'; -import { useCallback, useState } from 'react'; - -export type OperationHandler< - TResult, - TError extends IEquatableError, - TArgs extends unknown[] = never, -> = (...args: TArgs) => PromiseResult; - -/** - * An operation is a function that can be executed multiple times and that can be in a pending state. - * - * It also provides a way to access the last error that occurred during the execution of the operation. - */ -export type Operation< - TResult, - TError extends IEquatableError = never, - TArgs extends unknown[] = [], -> = { - error: TError | undefined; - execute: (...args: TArgs) => PromiseResult; - isPending: boolean; -}; - -export function useOperation( - handler: OperationHandler, -): Operation { - const [isPending, setIsPending] = useState(false); - const [error, setError] = useState(undefined); - - return { - error, - execute: useCallback( - async (...args: TArgs) => { - setError(undefined); - setIsPending(true); - - try { - const result = await handler(...args); - - if (result.isFailure()) { - setError(result.error); - } - - return result; - } finally { - setIsPending(false); - } - }, - [handler], - ), - isPending, - }; -} diff --git a/packages/react-v1/src/helpers/reads.ts b/packages/react-v1/src/helpers/reads.ts deleted file mode 100644 index 2e271fc16d..0000000000 --- a/packages/react-v1/src/helpers/reads.ts +++ /dev/null @@ -1,248 +0,0 @@ -/* eslint-disable no-console */ -import { - ApolloError, - DocumentNode, - LazyQueryExecFunction, - OperationVariables, - QueryResult as ApolloQueryResult, - useLazyQuery, -} from '@apollo/client'; -import { - Cursor, - PaginatedResultInfo, - UnspecifiedError, - InputMaybe, -} from '@lens-protocol/api-bindings'; -import { Prettify } from '@lens-protocol/shared-kernel'; -import { useCallback, useEffect, useRef, useState } from 'react'; - -import { useSharedDependencies } from '../shared'; - -/** - * A discriminated union of the possible results of a read operation with no errors. - * - * You can rely on the `loading` value to determine if the `data` is available. - * When `loading` is `false`, the `data` value will be available. - */ -export type ReadResultWithoutError = - | { - data: undefined; - loading: true; - } - | { - data: T; - loading: false; - }; - -/** - * A discriminated union of the possible results of a read operation with possible errors. - * - * You can rely on the `loading` value to determine if the `data` or `error` can be evaluated. - * - * If `error` is `undefined`, then `data` value will be available. - */ -export type ReadResultWithError = - | { - data: undefined; - error: undefined; - loading: true; - } - | { - data: T; - error: undefined; - loading: false; - } - | { - data: undefined; - error: E; - loading: false; - }; - -/** - * A discriminated union of the possible results of a read operation. - */ -export type ReadResult = E extends Error - ? ReadResultWithError - : ReadResultWithoutError; - -function buildReadResult( - data: T | undefined, - error: ApolloError | undefined, -): ReadResult { - if (data !== undefined) { - return { - data, - error: undefined, - loading: false, - }; - } - - if (error) { - return { - data: undefined, - error: new UnspecifiedError(error), - loading: false, - }; - } - - return { - data: undefined, - error: undefined, - loading: true, - }; -} - -export type QueryData = { result: R }; - -type InferResult> = T extends QueryData ? R : never; - -export function useReadResult< - T extends QueryData, - R = InferResult, - V = { [key: string]: never }, ->({ error, data }: ApolloQueryResult): ReadResult { - return buildReadResult(data?.result, error); -} - -export type PaginatedArgs = Prettify< - T & { - /** - * The number of items to return. - * - * @defaultValue 10 - */ - limit?: number; - } ->; - -/** - * A paginated read result. - */ -export type PaginatedReadResult = ReadResult & { - /** - * The number of items that are available before the results set. - * - * Use this to determine if you want to offer the option of loading more items - * at the beginning of the list via the `prev` method. - */ - beforeCount: number; - /** - * Whether there are more items to fetch in the next page - */ - hasMore: boolean; - /** - * Fetches the next page of items. - * - * @returns A promise that resolves when the next page of items has been fetched. - */ - next: () => Promise; - /** - * Fetches the previous page of items. - * - * @returns A promise that resolves when the prev page of items has been fetched. - */ - prev: () => Promise; -}; - -type PaginatedQueryVariables = OperationVariables & { cursor?: InputMaybe }; - -export type PaginatedQueryData = { - result: { pageInfo: PaginatedResultInfo; items: K[] }; -}; - -type InferPaginatedItemsType> = T extends PaginatedQueryData< - infer R -> - ? R - : never; - -function useAdHocQuery< - TVariables extends PaginatedQueryVariables, - TData extends PaginatedQueryData, - TItem = InferPaginatedItemsType, ->(query: DocumentNode): LazyQueryExecFunction { - const { apolloClient } = useSharedDependencies(); - const [fetch] = useLazyQuery(query, { - fetchPolicy: 'no-cache', - client: apolloClient, - }); - - return fetch; -} - -export function usePaginatedReadResult< - TVariables extends PaginatedQueryVariables, - TData extends PaginatedQueryData, - TItem = InferPaginatedItemsType, ->({ - error, - data, - loading, - fetchMore, - variables, - observable, -}: ApolloQueryResult): PaginatedReadResult { - const fetch = useAdHocQuery(observable.query); - const cachedData = useRef(data).current; - - const [beforeCount, setBeforeCount] = useState(0); - - const probeForNewerResults = useCallback( - async function (prev: Cursor) { - const response = await fetch({ - variables: { - ...variables, - cursor: prev, - } as TVariables, - }); - - if (response.data) { - setBeforeCount(response.data.result.items.length); - } - }, - [fetch, variables], - ); - - useEffect(() => { - if (cachedData?.result.pageInfo.prev) { - void probeForNewerResults(cachedData.result.pageInfo.prev); - } - }, [cachedData, probeForNewerResults]); - - return { - ...buildReadResult(data?.result.items, error), - - beforeCount, - - hasMore: data?.result.pageInfo.moreAfter ?? false, - - next: async () => { - if (loading) { - console.warn('Cannot fetch next page while loading, this is a no-op.'); - return; - } - if (!loading && data?.result.pageInfo.next) { - await fetchMore({ - variables: { - cursor: data.result.pageInfo.next, - }, - }); - } - }, - - prev: async () => { - if (loading) { - console.warn('Cannot fetch previous page while loading, this is a no-op.'); - return; - } - if (!loading && data?.result.pageInfo.prev) { - await fetchMore({ - variables: { - cursor: data.result.pageInfo.prev, - }, - }); - setBeforeCount(0); - } - }, - }; -} diff --git a/packages/react-v1/src/inbox/adapters/DisableConversationsGateway.ts b/packages/react-v1/src/inbox/adapters/DisableConversationsGateway.ts deleted file mode 100644 index c2ac05508a..0000000000 --- a/packages/react-v1/src/inbox/adapters/DisableConversationsGateway.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { IConversationsGateway } from '@lens-protocol/domain/use-cases/wallets'; -import { IStorage } from '@lens-protocol/storage'; - -export class DisableConversationsGateway implements IConversationsGateway { - constructor(private readonly storage: IStorage) {} - - async reset(): Promise { - return this.storage.reset(); - } -} diff --git a/packages/react-v1/src/inbox/index.ts b/packages/react-v1/src/inbox/index.ts deleted file mode 100644 index dfa48da67e..0000000000 --- a/packages/react-v1/src/inbox/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './adapters/DisableConversationsGateway'; -export * from './infrastructure/InboxKeyStorage'; diff --git a/packages/react-v1/src/inbox/infrastructure/InboxKeyStorage.ts b/packages/react-v1/src/inbox/infrastructure/InboxKeyStorage.ts deleted file mode 100644 index db4a69137d..0000000000 --- a/packages/react-v1/src/inbox/infrastructure/InboxKeyStorage.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { BaseStorageSchema, IStorageProvider, Storage } from '@lens-protocol/storage'; -import { z } from 'zod'; - -export const KeyBundleData = z.string(); - -export type KeyBundleData = z.infer; - -export function createInboxKeyStorage(storageProvider: IStorageProvider, namespace: string) { - const notificationStorageDataSchema = new BaseStorageSchema( - `lens.${namespace}.inbox.keyBundle`, - KeyBundleData, - ); - return Storage.createForSchema(notificationStorageDataSchema, storageProvider); -} diff --git a/packages/react-v1/src/index.ts b/packages/react-v1/src/index.ts deleted file mode 100644 index d69da35bb9..0000000000 --- a/packages/react-v1/src/index.ts +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Components - */ -export * from './LensProvider'; - -/** - * Hooks - */ -export * from './experimental'; -export * from './feed'; -export * from './lifecycle'; -export * from './modules'; -export * from './notifications'; -export * from './polls'; -export * from './profile'; -export * from './publication'; -export * from './revenue'; -export * from './transactions'; -export * from './wallet'; - -/** - * Config - */ -export * from './chains'; -export * from './environments'; -export type { - Digit, - ImageSizeTransform, - MediaTransformsConfig, - MediaTransformParams, - Percentage, - Pixel, -} from './mediaTransforms'; -export type { - AuthenticationConfig, - EncryptionConfig, - GetProvider, - GetSigner, - IBindings, - ICipher, - IEncryptionProvider, - ILogger, - LensConfig, -} from './config'; - -/** - * Hooks helpers types - */ -export type { WithObserverIdOverride, Skippable } from './helpers/arguments'; -export type { Operation } from './helpers/operations'; -export type { - PaginatedArgs, - PaginatedReadResult, - ReadResult, - ReadResultWithError, - ReadResultWithoutError, -} from './helpers/reads'; - -/** - * Storage - */ -export type { - IObservableStorageProvider, - IStorage, - IStorageProvider, - StorageProviderSubscriber, - StorageSubscriber, - StorageSubscription, -} from '@lens-protocol/storage'; - -/** - * Domain errors - */ -export { - InsufficientGasError, - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, - WalletConnectionErrorReason, -} from '@lens-protocol/domain/entities'; -export { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; - -/** - * Domain essentials - */ -export type { AppId, NftId, ProfileId, PublicationId } from '@lens-protocol/domain/entities'; -export type { ChainType, EthereumAddress, Url } from '@lens-protocol/shared-kernel'; - -/** - * Common Types - */ -export type { - AmountValue, - Asset, - BigDecimal, - CryptoAmount, - CryptoAsset, - CryptoNativeAmount, - CryptoNativeAsset, - Erc20, - Erc20Amount, - Erc20Info, - Ether, - Kind, - NativeType, - Failure, - Fiat, - FiatAmount, - IEquatableError, - InvariantError, - Matic, - PromiseResult, - Result, - Success, -} from '@lens-protocol/shared-kernel'; - -/** - * Common fragments - */ -export type { Erc20Fields, Erc20AmountFields, ModuleFeeAmount } from '@lens-protocol/api-bindings'; - -/** - * Common errors - */ -export { NotFoundError } from './NotFoundError'; -export { UnspecifiedError } from '@lens-protocol/api-bindings'; - -/** - * Helpers - */ -export { Amount, WellKnownSymbols, ether, matic, erc20, usd } from '@lens-protocol/shared-kernel'; -export { useSharedDependencies } from './shared'; -export * from './sources'; -export * from './utils'; -export { isValidHandle } from '@lens-protocol/api-bindings'; - -/** - * Helpers types - */ -export type { - Brand, - Cast, - Distribute, - DistributiveOmit, - Narrow, - Overwrite, - Prettify, - Primitive, - TwoAtLeastArray, - UnknownObject, - Without, - XOR, -} from '@lens-protocol/shared-kernel'; -export type { Typename, PickByTypename } from '@lens-protocol/api-bindings'; -export * from './deprecated'; diff --git a/packages/react-v1/src/lifecycle/__tests__/useCurrentSession.spec.ts b/packages/react-v1/src/lifecycle/__tests__/useCurrentSession.spec.ts deleted file mode 100644 index 03d375917f..0000000000 --- a/packages/react-v1/src/lifecycle/__tests__/useCurrentSession.spec.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { - Profile, - SessionType, - authenticatedProfile, - authenticatedWallet, - notAuthenticated, - resetSession, - updateSession, -} from '@lens-protocol/api-bindings'; -import { - mockGetProfileResponse, - mockLensApolloClient, - mockProfileFragment, - mockSources, -} from '@lens-protocol/api-bindings/mocks'; -import { mockProfileIdentifier, mockWalletData } from '@lens-protocol/domain/mocks'; -import { act, waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { useCurrentSession } from '../useCurrentSession'; - -function setupUseCurrentSession({ profiles }: { profiles: Profile[] }) { - const sources = mockSources(); - - const apolloClient = mockLensApolloClient( - profiles.map((profile) => - mockGetProfileResponse({ - variables: { - request: { profileId: profile.id }, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - profile, - }), - ), - ); - - return renderHookWithMocks(() => useCurrentSession(), { - mocks: { sources, mediaTransforms: defaultMediaTransformsConfig, apolloClient }, - }); -} - -describe(`Given the ${useCurrentSession.name} hook`, () => { - const profile = mockProfileFragment(); - const wallet = mockWalletData({ address: profile.ownedBy }); - const profileIdentifier = mockProfileIdentifier({ id: profile.id, handle: profile.handle }); - - describe(`when the current session is "null"`, () => { - beforeAll(() => { - resetSession(); - }); - - it('should return the expected loading state', async () => { - const { result } = setupUseCurrentSession({ profiles: [] }); - - expect(result.current.loading).toBeTruthy(); - expect(result.current.data).toBeUndefined(); - }); - }); - - describe.each([ - { - session: notAuthenticated(), - expectations: { - type: SessionType.Anonymous, - }, - }, - { - session: authenticatedWallet(wallet), - expectations: { - type: SessionType.JustWallet, - wallet, - }, - }, - { - session: authenticatedProfile(wallet, profileIdentifier), - expectations: { - type: SessionType.WithProfile, - wallet, - profile: { - __typename: 'Profile', - ...profileIdentifier, - }, - }, - }, - ])(`when the current session is`, ({ session, expectations }) => { - describe(`a ${session.constructor.name}`, () => { - beforeAll(() => { - resetSession(); - }); - - it('should return the expected session object', async () => { - const { result } = setupUseCurrentSession({ profiles: [profile] }); - - expect(result.current.loading).toBe(true); - - act(() => { - updateSession(session); - }); - - await waitFor(() => { - expect(result.current.loading).toBe(false); - expect(result.current.data).toMatchObject(expectations); - }); - }); - }); - }); - - describe(`when the user logs-in with a Lens Profile`, () => { - beforeAll(() => { - updateSession(notAuthenticated()); - }); - - it('should return the profile data without flickering of the "loading" flag', async () => { - const { result } = setupUseCurrentSession({ profiles: [profile] }); - - act(() => { - updateSession(authenticatedProfile(wallet, profileIdentifier)); - }); - - expect(result.current.loading).toBe(false); - - await waitFor(() => { - expect(result.current.data).toMatchObject({ - type: SessionType.WithProfile, - wallet, - profile: { - __typename: 'Profile', - ...profileIdentifier, - }, - }); - }); - }); - }); - - describe(`when the user switches to a different profile`, () => { - const prevProfile = mockProfileFragment({ ownedBy: wallet.address }); - const prevProfileIdentifier = mockProfileIdentifier({ - id: prevProfile.id, - handle: prevProfile.handle, - }); - - beforeAll(() => { - updateSession(notAuthenticated()); - }); - - it('should return the new profile data', async () => { - const { result } = setupUseCurrentSession({ profiles: [prevProfile, profile] }); - - act(() => { - updateSession(authenticatedProfile(wallet, prevProfileIdentifier)); - }); - - await waitFor(() => { - // previous profile loaded - expect(result.current.loading).toBe(false); - expect(result.current.data).toMatchObject({ - type: SessionType.WithProfile, - wallet, - profile: { - __typename: 'Profile', - ...prevProfileIdentifier, - }, - }); - }); - - act(() => { - // change to a new profile - updateSession(authenticatedProfile(wallet, profileIdentifier)); - }); - - // loading state shouldn't change anymore, return previous session while loading a new profile - expect(result.current.loading).toBe(false); - - await waitFor(() => { - expect(result.current.data).toMatchObject({ - type: SessionType.WithProfile, - wallet, - profile: { - __typename: 'Profile', - ...profileIdentifier, - }, - }); - }); - }); - }); -}); diff --git a/packages/react-v1/src/lifecycle/adapters/SessionPresenter.ts b/packages/react-v1/src/lifecycle/adapters/SessionPresenter.ts deleted file mode 100644 index 717d59423a..0000000000 --- a/packages/react-v1/src/lifecycle/adapters/SessionPresenter.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { - authenticatedProfile, - authenticatedWallet, - getSession, - notAuthenticated, - updateSession, -} from '@lens-protocol/api-bindings'; -import { - ISessionPresenter, - LogoutData, - ProfileIdentifier, - WalletData, -} from '@lens-protocol/domain/use-cases/lifecycle'; -import { invariant } from '@lens-protocol/shared-kernel'; - -/** - * Handler for logging out - */ -export type LogoutHandler = (data: LogoutData) => void; - -export class SessionPresenter implements ISessionPresenter { - constructor(private readonly logoutHandler: LogoutHandler) {} - - anonymous(): void { - updateSession(notAuthenticated()); - } - - authenticated(wallet: WalletData, profile: ProfileIdentifier | null): void { - if (profile) { - updateSession(authenticatedProfile(wallet, profile)); - } else { - updateSession(authenticatedWallet(wallet)); - } - } - - switchProfile(profile: ProfileIdentifier): void { - const session = getSession(); - - invariant(session?.isAuthenticated(), 'Cannot switch profile on a non-authenticated session'); - - updateSession(authenticatedProfile(session.wallet, profile)); - } - - logout(data: LogoutData): void { - this.logoutHandler(data); - updateSession(notAuthenticated()); - } -} diff --git a/packages/react-v1/src/lifecycle/adapters/__tests__/SessionPresenter.spec.ts b/packages/react-v1/src/lifecycle/adapters/__tests__/SessionPresenter.spec.ts deleted file mode 100644 index d024ebcad9..0000000000 --- a/packages/react-v1/src/lifecycle/adapters/__tests__/SessionPresenter.spec.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { - authenticatedProfile, - authenticatedWallet, - getSession, - notAuthenticated, -} from '@lens-protocol/api-bindings'; -import { mockProfileIdentifier, mockWalletData } from '@lens-protocol/domain/mocks'; -import { LogoutReason } from '@lens-protocol/domain/use-cases/wallets'; -import { InvariantError } from '@lens-protocol/shared-kernel'; - -import { SessionPresenter } from '../SessionPresenter'; - -function noop() {} - -describe(`Given the ${SessionPresenter.name}`, () => { - const wallet = mockWalletData(); - - describe(`when the "${SessionPresenter.prototype.anonymous.name}" method is invoked`, () => { - it('should set a NotAuthenticatedSession', () => { - const presenter = new SessionPresenter(noop); - - presenter.anonymous(); - - expect(getSession()).toEqual(notAuthenticated()); - }); - }); - - describe(`when the "${SessionPresenter.prototype.authenticated.name}" method is invoked`, () => { - describe('with just WalletData', () => { - it('should set an AuthenticatedWalletSession', () => { - const presenter = new SessionPresenter(noop); - - presenter.authenticated(wallet, null); - - expect(getSession()).toEqual(authenticatedWallet(wallet)); - }); - }); - - describe('with WalletData and ProfileIdentifier', () => { - const profile = mockProfileIdentifier(); - - it('should set an AuthenticatedProfileSession', () => { - const presenter = new SessionPresenter(noop); - - presenter.authenticated(wallet, profile); - - expect(getSession()).toEqual(authenticatedProfile(wallet, profile)); - }); - }); - }); - - describe(`when the "${SessionPresenter.prototype.switchProfile.name}" method is invoked`, () => { - const wallet = mockWalletData(); - const oldProfile = mockProfileIdentifier(); - - it('should change the current AuthenticatedProfileSession profile', () => { - const newProfile = mockProfileIdentifier(); - const presenter = new SessionPresenter(noop); - presenter.authenticated(wallet, oldProfile); - - presenter.switchProfile(newProfile); - - expect(getSession()).toEqual(authenticatedProfile(wallet, newProfile)); - }); - - it(`should throw an ${InvariantError.name} in case the current session is not authenticated`, () => { - const presenter = new SessionPresenter(noop); - presenter.anonymous(); - - expect(() => presenter.switchProfile(mockProfileIdentifier())).toThrow(InvariantError); - }); - }); - - describe(`when the "${SessionPresenter.prototype.logout.name}" method is invoked`, () => { - const data = { - logoutReason: LogoutReason.USER_INITIATED, - lastLoggedInWallet: mockWalletData(), - }; - const handler = jest.fn(); - - it(`should: - - set a NotAuthenticatedSession - - call the injected handler with the logout data`, () => { - const presenter = new SessionPresenter(handler); - presenter.authenticated(wallet, null); - - presenter.logout(data); - - expect(handler).toHaveBeenCalledWith(data); - expect(getSession()).toEqual(notAuthenticated()); - }); - }); -}); diff --git a/packages/react-v1/src/lifecycle/adapters/useBootstrapController.ts b/packages/react-v1/src/lifecycle/adapters/useBootstrapController.ts deleted file mode 100644 index b59602111d..0000000000 --- a/packages/react-v1/src/lifecycle/adapters/useBootstrapController.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Bootstrap } from '@lens-protocol/domain/use-cases/lifecycle'; -import { ActiveProfileLoader } from '@lens-protocol/domain/use-cases/profile'; - -import { SharedDependencies } from '../../shared'; - -export function useBootstrapController({ - activeProfileGateway, - activeWallet, - credentialsFactory, - credentialsGateway, - profileGateway, - sessionPresenter, - transactionQueue, - walletLogout, -}: SharedDependencies) { - return function () { - const activeProfileLoader = new ActiveProfileLoader(profileGateway, activeProfileGateway); - - const bootstrap = new Bootstrap( - activeWallet, - credentialsGateway, - credentialsFactory, - activeProfileLoader, - transactionQueue, - sessionPresenter, - walletLogout, - ); - - void bootstrap.execute(); - }; -} diff --git a/packages/react-v1/src/lifecycle/index.ts b/packages/react-v1/src/lifecycle/index.ts deleted file mode 100644 index 6c03c8efd2..0000000000 --- a/packages/react-v1/src/lifecycle/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type { LogoutHandler } from './adapters/SessionPresenter'; -export * from './useCurrentSession'; diff --git a/packages/react-v1/src/lifecycle/useCurrentSession.ts b/packages/react-v1/src/lifecycle/useCurrentSession.ts deleted file mode 100644 index 220a25decd..0000000000 --- a/packages/react-v1/src/lifecycle/useCurrentSession.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { - ProfileOwnedByMe, - Session, - SessionType, - UnspecifiedError, - authenticatedProfile, - isProfileOwnedByMe, - useGetProfile, - useSessionVar, -} from '@lens-protocol/api-bindings'; -import { WalletData } from '@lens-protocol/domain/use-cases/lifecycle'; -import { invariant } from '@lens-protocol/shared-kernel'; -import { useEffect, useRef } from 'react'; - -import { - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, -} from '../helpers/arguments'; -import { ReadResult } from '../helpers/reads'; - -export type { - NotAuthenticatedSession, - AuthenticatedWalletSession, - AuthenticatedProfileSession, -} from '@lens-protocol/api-bindings'; - -export { SessionType }; - -export type { Session, WalletData }; - -function usePrevious(value: T) { - const ref = useRef(); - - useEffect(() => { - ref.current = value; - }, [value]); - - return ref.current; -} - -/** - * `useCurrentSession` is a hook that lets you access the current {@link Session} - * - * **Pro-tip**: Use this hook to determine if the user is authenticated or not, - * and contextually if they have an Active Profile or not. - * - * @category Misc - * @group Hooks - * @internal Should not be used directly by consumers. - * @experimental This API is experimental and may change in the future. - * - * @example - * ```tsx - * import { useCurrentSession } from '@lens-protocol/react-web'; - * - * function Page() { - * const { data, loading } = useCurrentSession(); - * - * if (loading) return

Loading...

; - * - * switch (data.type) { - * case SessionType.Anonymous: - * return ; - * - * case SessionType.JustWallet: - * return ; - * - * case SessionType.WithProfile: - * return ; - * } - * } - * ``` - */ -export function useCurrentSession(): ReadResult< - Session, - UnspecifiedError -> { - const session = useSessionVar(); - - const prevSession = usePrevious(session); - - const trigger = session?.type === SessionType.WithProfile; - const profileId = session?.type === SessionType.WithProfile ? session.profile.id : undefined; - - const { data, error } = useGetProfile( - useLensApolloClient({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - request: { - profileId, - }, - }), - ), - fetchPolicy: 'cache-first', - skip: !trigger, - }), - ); - - const prevData = usePrevious(data); - - if (!session) { - return { - data: undefined, - error: undefined, - loading: true, - }; - } - - if (session.type !== SessionType.WithProfile) { - return { - data: session, - error: undefined, - loading: false, - }; - } - - if (error) { - return { - data: undefined, - error: new UnspecifiedError(error), - loading: false, - }; - } - - if (!data) { - if (!prevSession) { - // no data, no previous session, so still loading for initial data - return { - data: undefined, - error: undefined, - loading: true, - }; - } - - if (prevSession.type === SessionType.WithProfile) { - // no data, but we have a previous session, so that means transitioning to a new profile - if (prevData?.result) { - invariant( - isProfileOwnedByMe(prevData.result), - `Previous Active Profile [ID:${prevData.result.id}] not owned by the active wallet.\n` + - `Check the Profile ID provided is owned by ${session.wallet.address}.`, - ); - - return { - data: authenticatedProfile(prevSession.wallet, prevData.result), - error: undefined, - loading: false, - }; - } - - // shouldn't happen, but just in case, fallback to loading - return { - data: undefined, - error: undefined, - loading: true, - }; - } - - // transitioning from NotAuthenticatedSession to AuthenticatedProfileSession - // OR from AuthenticatedWalletSession to AuthenticatedProfileSession - return { - data: prevSession, - error: undefined, - loading: false, - }; - } - - invariant( - data.result, - `Active Profile [ID:${session.profile.id}] data not found.\n` + - 'Check the Profile ID provided exists in the current environment.', - ); - invariant( - isProfileOwnedByMe(data.result), - `Active Profile [ID:${session.profile.id}] not owned by the active wallet.\n` + - `Check the Profile ID provided is owned by ${session.wallet.address}.`, - ); - - return { - data: authenticatedProfile(session.wallet, data.result), - error: undefined, - loading: false, - }; -} diff --git a/packages/react-v1/src/mediaTransforms.ts b/packages/react-v1/src/mediaTransforms.ts deleted file mode 100644 index 3b97da584a..0000000000 --- a/packages/react-v1/src/mediaTransforms.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - Digit, - ImageSizeTransform, - MediaTransformParams, - Percentage, - Pixel, -} from '@lens-protocol/api-bindings'; - -export type { Digit, ImageSizeTransform, MediaTransformParams, Percentage, Pixel }; - -/** - * The media transforms configuration. - */ -export type MediaTransformsConfig = { - publication: { - small: MediaTransformParams; - medium: MediaTransformParams; - }; - profile: { - thumbnail: MediaTransformParams; - }; -}; - -function buildMediaTransform( - width: ImageSizeTransform, - height: ImageSizeTransform = 'auto', -): MediaTransformParams { - return { - width, - height, - keepAspectRatio: true, - }; -} - -export const defaultMediaTransformsConfig: MediaTransformsConfig = { - publication: { - small: buildMediaTransform('350px'), - medium: buildMediaTransform('700px'), - }, - profile: { - thumbnail: buildMediaTransform('256px'), - }, -}; - -export function mediaTransformConfigToQueryVariables(config: MediaTransformsConfig) { - return { - mediaTransformPublicationSmall: config.publication.small, - mediaTransformPublicationMedium: config.publication.medium, - mediaTransformProfileThumbnail: config.profile.thumbnail, - }; -} diff --git a/packages/react-v1/src/modules/__tests__/useCurrencies.spec.ts b/packages/react-v1/src/modules/__tests__/useCurrencies.spec.ts deleted file mode 100644 index 33b9398632..0000000000 --- a/packages/react-v1/src/modules/__tests__/useCurrencies.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { - mockLensApolloClient, - mockEnabledModuleCurrenciesResponse, -} from '@lens-protocol/api-bindings/mocks'; -import { ChainType } from '@lens-protocol/shared-kernel'; -import { mockDaiAsset, mockUsdcAsset } from '@lens-protocol/shared-kernel/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { useCurrencies } from '../useCurrencies'; - -describe(`Given the ${useCurrencies.name} hook`, () => { - describe('when invoked', () => { - it(`should return the expected list of Erc20`, async () => { - const chainType = ChainType.POLYGON; - const currencies = [mockDaiAsset({ chainType }), mockUsdcAsset({ chainType })]; - const { result } = renderHookWithMocks(() => useCurrencies(), { - mocks: { - apolloClient: mockLensApolloClient([mockEnabledModuleCurrenciesResponse(currencies)]), - }, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - - expect(result.current.data).toEqual(currencies); - }); - }); -}); diff --git a/packages/react-v1/src/modules/__tests__/useEnabledModules.spec.ts b/packages/react-v1/src/modules/__tests__/useEnabledModules.spec.ts deleted file mode 100644 index 59ce528df2..0000000000 --- a/packages/react-v1/src/modules/__tests__/useEnabledModules.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { - mockLensApolloClient, - mockEnabledModulesFragment, - mockEnabledModulesResponse, -} from '@lens-protocol/api-bindings/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { useEnabledModules } from '../useEnabledModules'; - -describe(`Given the ${useEnabledModules.name} hook`, () => { - describe('when invoked', () => { - it(`should return the expected list of enabled modules`, async () => { - const enabledModules = mockEnabledModulesFragment(); - const { result } = renderHookWithMocks(() => useEnabledModules(), { - mocks: { - apolloClient: mockLensApolloClient([ - mockEnabledModulesResponse({ data: enabledModules }), - ]), - }, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - - expect(result.current.data).toEqual(enabledModules); - }); - }); -}); diff --git a/packages/react-v1/src/modules/index.ts b/packages/react-v1/src/modules/index.ts deleted file mode 100644 index 0632bc6853..0000000000 --- a/packages/react-v1/src/modules/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './useCurrencies'; -export * from './useEnabledModules'; - -export type { EnabledModules, EnabledModule, ModuleInfo } from '@lens-protocol/api-bindings'; diff --git a/packages/react-v1/src/modules/useCurrencies.ts b/packages/react-v1/src/modules/useCurrencies.ts deleted file mode 100644 index c9848c03df..0000000000 --- a/packages/react-v1/src/modules/useCurrencies.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { useEnabledModuleCurrencies } from '@lens-protocol/api-bindings'; -import { ChainType, erc20, Erc20 } from '@lens-protocol/shared-kernel'; - -import { useLensApolloClient } from '../helpers/arguments'; -import { ReadResult, useReadResult } from '../helpers/reads'; - -/** - * `useCurrencies` lets you get the list of ERC20 that are enabled on the Lens protocol - * - * You MUST be authenticated via {@link useWalletLogin} to use this hook. - * - * **Pro-tip**: use this hook to populate a dropdown menu of currencies - * to choose from for powering a collect policy form of your post composer interface. - * - * @category Misc - * @group Hooks - * - * @example - * ```tsx - * import { useCurrencies, Erc20 } from '@lens-protocol/react-web'; - * - * function CurrencySelector({ onChange }: { onChange: (currency: Erc20) => void }) { - * const { data: currencies, error, loading } = useCurrencies(); - * - * const handleChange = (event: React.ChangeEvent) => { - * const currency = currencies.find((currency) => currency.symbol === event.target.value); - * if (currency) onChange(currency); - * }; - * - * if (loading) return

Loading...

; - * - * if (error) return

Error: {error.message}

; - * - * return ( - * - * ); - * } - * ``` - */ -export function useCurrencies(): ReadResult { - const { data, error, loading } = useReadResult(useEnabledModuleCurrencies(useLensApolloClient())); - - if (loading) { - return { - data: undefined, - error: undefined, - loading: true, - }; - } - - if (error) { - return { - data: undefined, - error: error, - loading: false, - }; - } - - return { - data: (data ?? []).map((currency) => erc20({ ...currency, chainType: ChainType.POLYGON })), - error: undefined, - loading: false, - }; -} diff --git a/packages/react-v1/src/modules/useEnabledModules.ts b/packages/react-v1/src/modules/useEnabledModules.ts deleted file mode 100644 index 2511bce670..0000000000 --- a/packages/react-v1/src/modules/useEnabledModules.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { useEnabledModules as useUnderlyingQuery } from '@lens-protocol/api-bindings'; - -import { useLensApolloClient } from '../helpers/arguments'; -import { useReadResult } from '../helpers/reads'; - -/** - * @category Misc - * @group Hooks - */ -export function useEnabledModules() { - return useReadResult(useUnderlyingQuery(useLensApolloClient())); -} diff --git a/packages/react-v1/src/notifications/index.ts b/packages/react-v1/src/notifications/index.ts deleted file mode 100644 index 113c96af14..0000000000 --- a/packages/react-v1/src/notifications/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -export * from './useUnreadNotificationCount'; -export * from './useNotifications'; - -export type { - NewCollectNotification, - NewCommentNotification, - NewFollowerNotification, - NewMentionNotification, - NewMirrorNotification, - NewReactionNotification, -} from '@lens-protocol/api-bindings'; -export { NotificationTypes } from '@lens-protocol/api-bindings'; diff --git a/packages/react-v1/src/notifications/useNotifications.ts b/packages/react-v1/src/notifications/useNotifications.ts deleted file mode 100644 index 66700eb86e..0000000000 --- a/packages/react-v1/src/notifications/useNotifications.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { - NewCollectNotification, - NewCommentNotification, - NewFollowerNotification, - NewMentionNotification, - NewMirrorNotification, - NewReactionNotification, - NotificationTypes, - useNotifications as useUnderlyingQuery, -} from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; - -import { - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; - -export type UseNotificationsArgs = PaginatedArgs<{ - /** - * The profile id you want to retrieve notifications for - */ - profileId: ProfileId; - - /** - * The types of notifications you want to retrieve - * - * @defaultValue `undefined` - will retrieve all types of notifications - */ - notificationTypes?: NotificationTypes[]; - - /** - * Whether to filter out notifications generated by low signal profiles activities - * - * @defaultValue `true` - will return notifications from high signal profiles only - */ - highSignalFilter?: boolean; -}>; - -export type Notification = - | NewFollowerNotification - | NewCollectNotification - | NewCommentNotification - | NewMirrorNotification - | NewMentionNotification - | NewReactionNotification; - -/** - * `useNotifications` is a paginated hook that lets you retrieve notifications for a given profile - * - * @category Notifications - * @group Hooks - * @param args - {@link UseNotificationsArgs} - * - * @example - * ```tsx - * import { useNotifications, ProfileId } from '@lens-protocol/react-web'; - * - * function Notifications({ profileId }: { profileId: ProfileId }}) { - * const { data, error, loading } = useNotifications({ profileId }); - * - * if (loading) return

Loading...

; - * - * if (error) return

Error: {error.message}

; - * - * return ( - *
    - * {data.map((notification) => ( - *
  • {notification.type}
  • - * ))} - *
- * ); - * } - * ``` - */ -export function useNotifications({ - highSignalFilter = true, - notificationTypes, - profileId, - limit, -}: UseNotificationsArgs): PaginatedReadResult { - return usePaginatedReadResult( - useUnderlyingQuery( - useLensApolloClient({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - observerId: profileId, - limit: limit ?? 10, - notificationTypes, - highSignalFilter, - }), - ), - }), - ), - ); -} diff --git a/packages/react-v1/src/notifications/useUnreadNotificationCount.ts b/packages/react-v1/src/notifications/useUnreadNotificationCount.ts deleted file mode 100644 index 65e48c48e2..0000000000 --- a/packages/react-v1/src/notifications/useUnreadNotificationCount.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { useUnreadNotificationCount as useUnderlyingQuery } from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { invariant } from '@lens-protocol/shared-kernel'; -import { useEffect, useState } from 'react'; - -import { useLensApolloClient } from '../helpers/arguments'; -import { useSharedDependencies } from '../shared'; - -export type UseUnreadNotificationCountArgs = { - /** - * The profile id you want to retrieve the number of unread notifications for - */ - profileId: ProfileId; -}; - -/** - * `useUnreadNotificationCount` is a hook that lets you retrieve the number of unread notifications for a given profile - * - * It also provides a `clear` function that you can use to mark all notifications as read - * - * @category Notifications - * @group Hooks - * @param args - {@link UseUnreadNotificationCountArgs} - * - * @example - * ```tsx - * import { useUnreadNotificationCount, ProfileId } from '@lens-protocol/react-web'; - * - * function UnreadNotifications({ profileId }: { profileId: ProfileId }}) { - * const { unreadNotificationCount, clear, loading } = useUnreadNotificationCount({ profileId }); - * - * if (loading) return

Loading...

; - * - * return ( - *
- *

You have {unreadNotificationCount} unread notifications

- * - *
- * ); - * } - * ``` - */ -export function useUnreadNotificationCount({ profileId }: UseUnreadNotificationCountArgs) { - const { notificationStorage } = useSharedDependencies(); - const [unreadNotificationCount, setUnreadNotificationCount] = useState(0); - - const { loading, data } = useUnderlyingQuery( - useLensApolloClient({ - variables: { profileId }, - // no cache is required to always have up-to-date information - // and to not affect notifications cache - fetchPolicy: 'no-cache', - }), - ); - - useEffect(() => { - async function calculate() { - if (loading) { - return; - } - - invariant(data, 'Expected data to be defined'); - - invariant( - data.result.pageInfo.totalCount !== null, - 'Expected total notification count to be defined', - ); - - const readTotalCount = (await notificationStorage.get())?.totalReadNotificationsCount; - - if (readTotalCount) { - const currentTotalCount = data.result.pageInfo.totalCount; - - setUnreadNotificationCount(currentTotalCount - readTotalCount); - } else { - await notificationStorage.set({ - totalReadNotificationsCount: data.result.pageInfo.totalCount, - }); - - setUnreadNotificationCount(0); - } - } - - void calculate(); - }, [data, loading, notificationStorage]); - - if (loading) { - return { - loading: true, - }; - } - - if (unreadNotificationCount === 0) { - return { - loading: false, - unreadNotificationCount, - clear: (): Promise => { - return Promise.resolve(); - }, - }; - } - - return { - loading: false, - unreadNotificationCount, - clear: async (): Promise => { - invariant( - data?.result.pageInfo.totalCount, - 'Expected total notification count to be defined', - ); - - await notificationStorage.set({ - totalReadNotificationsCount: data.result.pageInfo.totalCount, - }); - - setUnreadNotificationCount(0); - }, - }; -} diff --git a/packages/react-v1/src/polls/adapters/SnapshotVoteFactory.ts b/packages/react-v1/src/polls/adapters/SnapshotVoteFactory.ts deleted file mode 100644 index d5804cae7b..0000000000 --- a/packages/react-v1/src/polls/adapters/SnapshotVoteFactory.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { - SafeApolloClient, - GetSnapshotProposalDocument, - SnapshotSpaceId, - GetSnapshotProposalData, - GetSnapshotProposalVariables, - SnapshotProposal, - SnapshotVotingSystem, -} from '@lens-protocol/api-bindings'; -import { TypedData } from '@lens-protocol/blockchain-bindings'; -import { AppId, Wallet, IUnsignedVote, PollId } from '@lens-protocol/domain/entities'; -import { - CreateUnsignedVoteRequest, - IUnsignedVoteFactory, - VoteChoice, -} from '@lens-protocol/domain/use-cases/polls'; -import { invariant, InvariantError, never } from '@lens-protocol/shared-kernel'; -import { getAddress } from 'ethers/lib/utils'; - -import { vote2Types, voteArray2Types, voteString2Types } from './types'; - -export class UnsignedVote implements IUnsignedVote { - constructor(readonly pollId: PollId, readonly typedData: TypedData) {} -} - -type Message = { - app: string; - choice: number | number[] | string; - from: string; - metadata: string; - proposal: string; - reason: string; - space: string; - timestamp: number; -}; - -function createTypedData({ - message, - types, -}: { - message: Partial; - types: typeof vote2Types | typeof voteArray2Types; -}): TypedData { - return { - domain: { - name: 'snapshot', - version: '0.1.4', - }, - types, - message: { - reason: '', - app: '', - metadata: '{}', - timestamp: parseInt((Date.now() / 1e3).toFixed()), - ...message, - }, - }; -} - -function isNumber(value: unknown): value is number { - return typeof value === 'number'; -} - -function validateSingleChoice( - request: { choice: VoteChoice }, - proposal: SnapshotProposal, -): asserts request is { choice: number } { - invariant(isNumber(request.choice), 'Choice must be an number'); - invariant(request.choice >= 0, 'Choice is a 0-based index, it must be a positive number'); - invariant( - request.choice < proposal.choices.length, - 'Choice is a 0-based index, it must be less than the number of choices', - ); -} - -function singleChoiceTypedData( - proposal: SnapshotProposal, - choice: number, - voter: Wallet, - appId?: AppId, -): TypedData { - return createTypedData({ - message: { - app: appId ?? '', - choice: choice + 1, - from: getAddress(voter.address), - proposal: proposal.id, - space: proposal.space?.id ?? never(), - }, - types: vote2Types, - }); -} - -function isNumberArray(value: unknown): value is number[] { - return Array.isArray(value) && value.every(isNumber); -} - -function validateMultipleChoice( - request: { choice: VoteChoice }, - proposal: SnapshotProposal, -): asserts request is { choice: number[] } { - invariant(isNumberArray(request.choice), 'Choice must be an array of numbers'); - invariant(request.choice.length > 0, 'Choice must contain at least one choice'); - invariant( - request.choice.length <= proposal.choices.length, - 'Choice must contain at most the number of choices', - ); - invariant( - request.choice.every((c) => c >= 0), - 'Choice is a 0-based index, it must be a positive number', - ); - invariant( - request.choice.every((c) => c < proposal.choices.length), - 'Choice is a 0-based index, it must be less than the number of choices', - ); -} - -function multipleChoiceTypedData( - proposal: SnapshotProposal, - choice: number[], - voter: Wallet, - appId?: AppId, -): TypedData { - return createTypedData({ - message: { - app: appId ?? '', - choice: choice.map((c) => c + 1), - from: getAddress(voter.address), - proposal: proposal.id, - space: proposal.space?.id ?? never(), - }, - types: voteArray2Types, - }); -} - -function serializeWeightedChoice(choice: number[]): string { - const map = choice.reduce((acc, value, idx) => { - if (value > 0) { - acc[idx + 1] = value; - } - return acc; - }, {} as { [key: number]: number }); - return JSON.stringify(map); -} - -function validateWeightedChoice( - request: { choice: VoteChoice }, - proposal: SnapshotProposal, -): asserts request is { choice: number[] } { - invariant(isNumberArray(request.choice), 'Choice must be an array of numbers'); - invariant( - request.choice.length === proposal.choices.length, - 'Choice must specify a value for each proposal choice', - ); - invariant( - request.choice.every((c) => c >= 0), - 'Choice is a 0-based index, it must be a positive number', - ); -} - -function weightedChoiceTypedData( - proposal: SnapshotProposal, - choice: number[], - voter: Wallet, - appId?: AppId, -): TypedData { - return createTypedData({ - message: { - app: appId ?? '', - choice: serializeWeightedChoice(choice), - from: getAddress(voter.address), - proposal: proposal.id, - space: proposal.space?.id ?? never(), - }, - types: voteString2Types, - }); -} - -function resolveTypedData( - proposal: SnapshotProposal, - request: CreateUnsignedVoteRequest, - appId?: AppId, -): TypedData { - switch (proposal.type) { - case SnapshotVotingSystem.BASIC: - case SnapshotVotingSystem.SINGLE_CHOICE: - validateSingleChoice(request, proposal); - return singleChoiceTypedData(proposal, request.choice, request.voter, appId); - - case SnapshotVotingSystem.APPROVAL: - case SnapshotVotingSystem.RANKED_CHOICE: - validateMultipleChoice(request, proposal); - return multipleChoiceTypedData(proposal, request.choice, request.voter, appId); - - case SnapshotVotingSystem.QUADRATIC: - case SnapshotVotingSystem.WEIGHTED: - validateWeightedChoice(request, proposal); - return weightedChoiceTypedData(proposal, request.choice, request.voter, appId); - - default: - throw new InvariantError(`Unsupported voting system: ${String(proposal.type)}`); - } -} - -export class SnapshotVoteFactory implements IUnsignedVoteFactory { - constructor( - private readonly client: SafeApolloClient, - private readonly spaceId: SnapshotSpaceId, - private readonly appId?: AppId, - ) {} - - async createUnsignedVote(request: CreateUnsignedVoteRequest): Promise { - const result = await this.client.query({ - query: GetSnapshotProposalDocument, - variables: { - spaceId: this.spaceId, - proposalId: request.pollId, - includeVotes: false, - voterAddress: '0x000', - }, - }); - - const proposal = result.data.proposal; - invariant(proposal !== null, 'Proposal not found'); - invariant( - proposal.privacy !== 'shutter', - 'Proposal with shutter privacy are not supported at this time', - ); - - return new UnsignedVote(request.pollId, resolveTypedData(proposal, request, this.appId)); - } -} diff --git a/packages/react-v1/src/polls/adapters/SnapshotVoteRelayer.ts b/packages/react-v1/src/polls/adapters/SnapshotVoteRelayer.ts deleted file mode 100644 index e16ccef534..0000000000 --- a/packages/react-v1/src/polls/adapters/SnapshotVoteRelayer.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { TypedData } from '@lens-protocol/blockchain-bindings'; -import { ISignedVote } from '@lens-protocol/domain/entities'; -import { IPollVoteRelayer } from '@lens-protocol/domain/use-cases/polls'; -import { EthereumAddress, Url } from '@lens-protocol/shared-kernel'; - -export interface ISnapshotVote extends ISignedVote { - voter: EthereumAddress; - data: TypedData; -} - -export class SnapshotRelayError extends Error { - name = 'SnapshotRelayError' as const; -} - -export class SnapshotVoteRelayer implements IPollVoteRelayer { - constructor(private readonly sequencer: Url) {} - - async relay({ data, pollId, signature, voter }: ISnapshotVote): Promise { - const envelope = { - address: voter, - data, - sig: signature, - }; - - const response = await fetch(this.sequencer, { - method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify(envelope), - }); - - if (!response.ok) { - throw new SnapshotRelayError( - `Failed to relay snapshot vote for proposal: ${pollId}\n\n` + - `${JSON.stringify(data, null, 2) - .split(`\n`) - .map((line) => ` ${line}`) - .join('\n')}`, - ); - } - } -} diff --git a/packages/react-v1/src/polls/adapters/__helpers__/mocks.ts b/packages/react-v1/src/polls/adapters/__helpers__/mocks.ts deleted file mode 100644 index dc89439362..0000000000 --- a/packages/react-v1/src/polls/adapters/__helpers__/mocks.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { TypedData } from '@lens-protocol/blockchain-bindings'; -import { mockPollId } from '@lens-protocol/domain/mocks'; - -import { UnsignedVote } from '../SnapshotVoteFactory'; - -export function mockUnsignedVote({ typedData }: { typedData: TypedData }): UnsignedVote { - return new UnsignedVote(mockPollId(), typedData); -} diff --git a/packages/react-v1/src/polls/adapters/__tests__/SnapshotVoteFactory.spec.ts b/packages/react-v1/src/polls/adapters/__tests__/SnapshotVoteFactory.spec.ts deleted file mode 100644 index ce16f3d416..0000000000 --- a/packages/react-v1/src/polls/adapters/__tests__/SnapshotVoteFactory.spec.ts +++ /dev/null @@ -1,284 +0,0 @@ -import { - SnapshotProposal, - SnapshotSpaceId, - SnapshotVotingSystem, -} from '@lens-protocol/api-bindings'; -import { - mockGetSnapshotProposalDataResponse, - mockSnapshotApolloClient, - mockSnapshotProposal, -} from '@lens-protocol/api-bindings/mocks'; -import { AppId, PollId } from '@lens-protocol/domain/entities'; -import { mockAppId, mockCreateUnsignedVoteRequest, mockWallet } from '@lens-protocol/domain/mocks'; -import { InvariantError, never } from '@lens-protocol/shared-kernel'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; -import { getAddress } from 'ethers/lib/utils'; - -import { SnapshotVoteFactory, UnsignedVote } from '../SnapshotVoteFactory'; -import { vote2Types, voteArray2Types, voteString2Types } from '../types'; - -function setupTestScenario({ appId, proposal }: { appId?: AppId; proposal: SnapshotProposal }) { - const client = mockSnapshotApolloClient([mockGetSnapshotProposalDataResponse({ proposal })]); - - return new SnapshotVoteFactory(client, (proposal.space?.id ?? never()) as SnapshotSpaceId, appId); -} - -describe(`Given an instance of the ${SnapshotVoteFactory.name}`, () => { - const voter = mockWallet({ - // ensures `from` has EIP-55 checksum - address: mockEthereumAddress().toLowerCase(), - }); - - const appId = mockAppId(); - - describe.each([ - { - proposal: mockSnapshotProposal({ - type: SnapshotVotingSystem.SINGLE_CHOICE, - }), - }, - { - proposal: mockSnapshotProposal({ - type: SnapshotVotingSystem.BASIC, - }), - }, - ])( - `when the ${SnapshotVoteFactory.prototype.createUnsignedVote.name} method is invoked for a proposal w/ "$proposal.type" voting system`, - ({ proposal }) => { - it(`should create an instance of ${UnsignedVote.name} w/ the expected EIP-712 typed data"`, async () => { - const request = mockCreateUnsignedVoteRequest({ - pollId: proposal.id as PollId, - choice: 0, - voter, - }); - const factory = setupTestScenario({ appId, proposal }); - - const vote = await factory.createUnsignedVote(request); - - const expectedTypedData = { - domain: { - name: expect.any(String), - version: expect.any(String), - }, - types: vote2Types, - message: { - choice: 1, - reason: '', - proposal: proposal.id, - space: proposal.space?.id ?? never(), - app: appId, - metadata: '{}', - from: getAddress(voter.address), - timestamp: expect.any(Number), - }, - }; - expect(vote).toBeInstanceOf(UnsignedVote); - expect(vote.typedData).toMatchObject(expectedTypedData); - }); - - it.each([ - { - choice: [0], - description: 'not a number', - }, - { - choice: -1, - description: 'less than 0', - }, - { - choice: proposal.choices.length, - description: 'greater than the number of choices', - }, - ])( - `should throw an ${InvariantError.name} if the "choice" is $description`, - async ({ choice }) => { - const request = mockCreateUnsignedVoteRequest({ - pollId: proposal.id as PollId, - choice, - voter, - }); - const factory = setupTestScenario({ proposal }); - - await expect(factory.createUnsignedVote(request)).rejects.toThrow(InvariantError); - }, - ); - }, - ); - - describe.each([ - { - proposal: mockSnapshotProposal({ - type: SnapshotVotingSystem.APPROVAL, - choices: ['a', 'b', 'c'], - }), - }, - { - proposal: mockSnapshotProposal({ - type: SnapshotVotingSystem.RANKED_CHOICE, - choices: ['a', 'b', 'c'], - }), - }, - ])( - `when the ${SnapshotVoteFactory.prototype.createUnsignedVote.name} method is invoked for a proposal w/ "$proposal.type" voting system`, - ({ proposal }) => { - it(`should create an instance of ${UnsignedVote.name} w/ the expected EIP-712 typed data"`, async () => { - const request = mockCreateUnsignedVoteRequest({ - pollId: proposal.id as PollId, - choice: [0, 1], - voter, - }); - const factory = setupTestScenario({ appId, proposal }); - - const vote = await factory.createUnsignedVote(request); - - const expectedTypedData = { - domain: { - name: expect.any(String), - version: expect.any(String), - }, - types: voteArray2Types, - message: { - choice: [1, 2], - reason: '', - proposal: proposal.id, - space: proposal.space?.id ?? never(), - app: appId, - metadata: '{}', - from: getAddress(voter.address), - timestamp: expect.any(Number), - }, - }; - expect(vote).toBeInstanceOf(UnsignedVote); - expect(vote.typedData).toMatchObject(expectedTypedData); - }); - - it.each([ - { - choice: 0, - description: 'is not an array of numbers', - }, - { - choice: [], - description: 'is an empty array', - }, - { - choice: [-1, 0], - description: 'contains negative numbers', - }, - { - choice: [0, 1, 2, 3, 4, 5], - description: 'contains more choices than the proposal has', - }, - { - choice: [0, 1, 1000], - description: 'contains choices that are greater than the number of choices', - }, - ])( - `should throw an ${InvariantError.name} if the "choice" $description`, - async ({ choice }) => { - const request = mockCreateUnsignedVoteRequest({ - pollId: proposal.id as PollId, - choice, - voter, - }); - const factory = setupTestScenario({ proposal }); - - await expect(factory.createUnsignedVote(request)).rejects.toThrow(InvariantError); - }, - ); - }, - ); - - describe.each([ - { - proposal: mockSnapshotProposal({ - type: SnapshotVotingSystem.QUADRATIC, - choices: ['a', 'b', 'c'], - }), - }, - { - proposal: mockSnapshotProposal({ - type: SnapshotVotingSystem.WEIGHTED, - choices: ['a', 'b', 'c'], - }), - }, - ])( - `when the ${SnapshotVoteFactory.prototype.createUnsignedVote.name} method is invoked for a proposal w/ "$proposal.type" voting system`, - ({ proposal }) => { - it(`should create an instance of ${UnsignedVote.name} w/ the expected EIP-712 typed data"`, async () => { - const request = mockCreateUnsignedVoteRequest({ - pollId: proposal.id as PollId, - choice: [0, 1, 0], - voter, - }); - const factory = setupTestScenario({ appId, proposal }); - - const vote = await factory.createUnsignedVote(request); - - const expectedTypedData = { - domain: { - name: expect.any(String), - version: expect.any(String), - }, - types: voteString2Types, - message: { - choice: JSON.stringify({ 2: 1 }), - reason: '', - proposal: proposal.id, - space: proposal.space?.id ?? never(), - app: appId, - metadata: '{}', - from: getAddress(voter.address), - timestamp: expect.any(Number), - }, - }; - expect(vote).toBeInstanceOf(UnsignedVote); - expect(vote.typedData).toMatchObject(expectedTypedData); - }); - - it.each([ - { - choice: 0, - description: 'is not an array of numbers', - }, - { - choice: [0], - description: 'is shorter than the number of choices', - }, - { - choice: [-1, 0, 0], - description: 'contains negative numbers', - }, - ])( - `should throw an ${InvariantError.name} if the "choice" $description`, - async ({ choice }) => { - const request = mockCreateUnsignedVoteRequest({ - pollId: proposal.id as PollId, - choice, - voter, - }); - const factory = setupTestScenario({ proposal }); - - await expect(factory.createUnsignedVote(request)).rejects.toThrow(InvariantError); - }, - ); - }, - ); - - describe(`when the proposal has "privacy" set to "shutter"`, () => { - it(`should throw an ${InvariantError.name}`, async () => { - const proposal = mockSnapshotProposal({ - type: SnapshotVotingSystem.QUADRATIC, - privacy: 'shutter', - }); - const request = mockCreateUnsignedVoteRequest({ - pollId: proposal.id as PollId, - choice: 0, - voter, - }); - const factory = setupTestScenario({ appId, proposal }); - - await expect(factory.createUnsignedVote(request)).rejects.toThrow(InvariantError); - }); - }); -}); diff --git a/packages/react-v1/src/polls/adapters/__tests__/SnapshotVoteRelayer.spec.ts b/packages/react-v1/src/polls/adapters/__tests__/SnapshotVoteRelayer.spec.ts deleted file mode 100644 index 25e603f57e..0000000000 --- a/packages/react-v1/src/polls/adapters/__tests__/SnapshotVoteRelayer.spec.ts +++ /dev/null @@ -1,99 +0,0 @@ -/* - * @jest-environment node - */ - -import { faker } from '@faker-js/faker'; -import { mock32BytesHexString, mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; -import { when } from 'jest-when'; - -import { production } from '../../../environments'; -import { mockSignedVote } from '../../../wallet/adapters/__helpers__/mocks'; -import { SnapshotRelayError, SnapshotVoteRelayer } from '../SnapshotVoteRelayer'; - -const sequencer = production.snapshot.sequencer; - -function createHttpJsonResponse( - status: number, - body: unknown, - headers: Record = {}, -): Response { - return new Response(JSON.stringify(body), { - status, - headers: { - ...headers, - 'Content-Type': 'application/json', - }, - }); -} - -function createSuccessfulResponse() { - return createHttpJsonResponse( - 200, - JSON.stringify({ - id: mock32BytesHexString(), - ipfs: faker.random.alphaNumeric(10), - relayer: { - address: mockEthereumAddress(), - receipt: faker.datatype.hexadecimal({ length: 65 }), - }, - }), - ); -} - -function createFailedRequest() { - return createHttpJsonResponse( - 500, - `...`, // properly wrong to prove robustness - ); -} - -function setupTestScenario() { - const snapshotVoteRelayer = new SnapshotVoteRelayer(production.snapshot.sequencer); - return snapshotVoteRelayer; -} - -describe(`Given an instance of the ${SnapshotVoteRelayer.name}`, () => { - describe(`when calling "${SnapshotVoteRelayer.prototype.relay.name}" method`, () => { - const signedVote = mockSignedVote(); - - beforeAll(() => { - jest.spyOn(global, 'fetch'); - }); - - afterAll(() => { - jest.mocked(fetch).mockRestore(); - }); - - it('should send the expected data envelope to the snapshot sequencer', async () => { - when(fetch).mockResolvedValue(createSuccessfulResponse()); - - const snapshotVoteRelayer = setupTestScenario(); - - await snapshotVoteRelayer.relay(signedVote); - - expect(fetch).toBeCalledWith( - sequencer, - expect.objectContaining({ - method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - address: signedVote.voter, - data: signedVote.data, - sig: signedVote.signature, - }), - }), - ); - }); - - it(`should throw an ${SnapshotRelayError.name} in case of failed request`, async () => { - when(fetch).mockResolvedValue(createFailedRequest()); - - const snapshotVoteRelayer = setupTestScenario(); - - await expect(snapshotVoteRelayer.relay(signedVote)).rejects.toThrowError(SnapshotRelayError); - }); - }); -}); diff --git a/packages/react-v1/src/polls/adapters/types.ts b/packages/react-v1/src/polls/adapters/types.ts deleted file mode 100644 index 061b589ea6..0000000000 --- a/packages/react-v1/src/polls/adapters/types.ts +++ /dev/null @@ -1,77 +0,0 @@ -export const voteTypes = { - Vote: [ - { name: 'from', type: 'address' }, - { name: 'space', type: 'string' }, - { name: 'timestamp', type: 'uint64' }, - { name: 'proposal', type: 'string' }, - { name: 'choice', type: 'uint32' }, - { name: 'reason', type: 'string' }, - { name: 'app', type: 'string' }, - { name: 'metadata', type: 'string' }, - ], -}; - -export const voteArrayTypes = { - Vote: [ - { name: 'from', type: 'address' }, - { name: 'space', type: 'string' }, - { name: 'timestamp', type: 'uint64' }, - { name: 'proposal', type: 'string' }, - { name: 'choice', type: 'uint32[]' }, - { name: 'reason', type: 'string' }, - { name: 'app', type: 'string' }, - { name: 'metadata', type: 'string' }, - ], -}; - -export const voteStringTypes = { - Vote: [ - { name: 'from', type: 'address' }, - { name: 'space', type: 'string' }, - { name: 'timestamp', type: 'uint64' }, - { name: 'proposal', type: 'string' }, - { name: 'choice', type: 'string' }, - { name: 'reason', type: 'string' }, - { name: 'app', type: 'string' }, - { name: 'metadata', type: 'string' }, - ], -}; - -export const vote2Types = { - Vote: [ - { name: 'from', type: 'address' }, - { name: 'space', type: 'string' }, - { name: 'timestamp', type: 'uint64' }, - { name: 'proposal', type: 'bytes32' }, - { name: 'choice', type: 'uint32' }, - { name: 'reason', type: 'string' }, - { name: 'app', type: 'string' }, - { name: 'metadata', type: 'string' }, - ], -}; - -export const voteArray2Types = { - Vote: [ - { name: 'from', type: 'address' }, - { name: 'space', type: 'string' }, - { name: 'timestamp', type: 'uint64' }, - { name: 'proposal', type: 'bytes32' }, - { name: 'choice', type: 'uint32[]' }, - { name: 'reason', type: 'string' }, - { name: 'app', type: 'string' }, - { name: 'metadata', type: 'string' }, - ], -}; - -export const voteString2Types = { - Vote: [ - { name: 'from', type: 'address' }, - { name: 'space', type: 'string' }, - { name: 'timestamp', type: 'uint64' }, - { name: 'proposal', type: 'bytes32' }, - { name: 'choice', type: 'string' }, - { name: 'reason', type: 'string' }, - { name: 'app', type: 'string' }, - { name: 'metadata', type: 'string' }, - ], -}; diff --git a/packages/react-v1/src/polls/adapters/useVotePollController.ts b/packages/react-v1/src/polls/adapters/useVotePollController.ts deleted file mode 100644 index 0846a3ba17..0000000000 --- a/packages/react-v1/src/polls/adapters/useVotePollController.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { - createSnapshotApolloClient, - SnapshotProposalId, - SnapshotSpaceId, -} from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { VoteChoice, VotePoll } from '@lens-protocol/domain/use-cases/polls'; - -import { useSharedDependencies } from '../../shared'; -import { PromiseResultPresenter } from '../../transactions/adapters/PromiseResultPresenter'; -import { SnapshotVoteFactory } from './SnapshotVoteFactory'; -import { SnapshotVoteRelayer } from './SnapshotVoteRelayer'; - -export type VotePollArgs = { - spaceId: SnapshotSpaceId; - proposalId: SnapshotProposalId; - choice: VoteChoice; -}; - -export function useVotePollController() { - const { activeWallet, appId, environment } = useSharedDependencies(); - - return async ({ choice, proposalId, spaceId }: VotePollArgs) => { - const snapshotApolloClient = createSnapshotApolloClient({ - backendURL: environment.snapshot.hub, - }); - const factory = new SnapshotVoteFactory(snapshotApolloClient, spaceId, appId); - - const relayer = new SnapshotVoteRelayer(environment.snapshot.sequencer); - - const presenter = new PromiseResultPresenter< - void, - PendingSigningRequestError | UserRejectedError | WalletConnectionError - >(); - const votePoll = new VotePoll(factory, activeWallet, presenter, relayer); - - await votePoll.execute({ pollId: proposalId, choice }); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/polls/index.ts b/packages/react-v1/src/polls/index.ts deleted file mode 100644 index 339ec0887a..0000000000 --- a/packages/react-v1/src/polls/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './usePollDetails'; -export * from './usePollVote'; - -export { isPollPublication } from '@lens-protocol/api-bindings'; -export type { - ContentInsight, - Poll, - PollPublication, - SnapshotVotingSystem, -} from '@lens-protocol/api-bindings'; diff --git a/packages/react-v1/src/polls/usePollDetails.ts b/packages/react-v1/src/polls/usePollDetails.ts deleted file mode 100644 index ed20855cac..0000000000 --- a/packages/react-v1/src/polls/usePollDetails.ts +++ /dev/null @@ -1,255 +0,0 @@ -import { - PollPublication, - SnapshotProposal, - SnapshotVote, - SnapshotVotePower, - SnapshotVotingSystem, - useGetSnapshotProposal, - useSessionVar, -} from '@lens-protocol/api-bindings'; -import { - assertError, - EthereumAddress, - hasTwoOrMore, - invariant, - never, - TwoAtLeastArray, - Url, -} from '@lens-protocol/shared-kernel'; - -import { NotFoundError } from '../NotFoundError'; -import { useSnapshotApolloClient } from '../helpers/arguments'; -import { ReadResult } from '../helpers/reads'; - -/** - * @experimental - */ -export type SnapshotSpace = { - id: string; - name: string; -}; - -/** - * @experimental - */ -export type PollChoice = { - label: string; - votes: number; - didVote: boolean; - percentage: number; -}; - -/** - * @experimental - */ -export enum VoteEligibility { - CAN_VOTE = 'CAN_VOTE', - CANNOT_VOTE = 'CANNOT_VOTE', - UNKNOWN = 'UNKNOWN', -} - -function resolveVoteEligibility(power: SnapshotVotePower | null | undefined): VoteEligibility { - if (!power || power.value === null) { - return VoteEligibility.UNKNOWN; - } - - if (power.value > 0) { - return VoteEligibility.CAN_VOTE; - } - - return VoteEligibility.CANNOT_VOTE; -} - -/** - * @experimental - */ -export type SnapshotDetails = { - author: EthereumAddress; - choices: TwoAtLeastArray; - eligibility: VoteEligibility; - endAt: Date; - isActive: boolean; - isSingleChoice: boolean; - quorum: number; - snapshot: string | null; - space: SnapshotSpace; - startAt: Date; - system: SnapshotVotingSystem; - title: string; - totalVotes: number; - url: Url; -}; - -/** - * @experimental - */ -export type UsePollDetailsArgs = { - publication: PollPublication; -}; - -function isValidVoteChoice(data: unknown): data is Array { - return Array.isArray(data) && data.every(Number.isFinite); -} - -function isChoiceIndex(data: unknown): data is number { - return Number.isInteger(data); -} - -function resolveMyChoices(vote: SnapshotVote | null | undefined): Array { - if (!vote) { - return []; - } - - if (isChoiceIndex(vote.choice)) { - return [vote.choice - 1]; - } - - if (isValidVoteChoice(vote.choice)) { - return vote.choice.map((choice) => choice - 1); - } - return []; -} - -function buildPollChoices( - proposal: SnapshotProposal, - votes: Array, -): TwoAtLeastArray { - invariant(hasTwoOrMore(proposal.choices), 'Snapshot proposal must have at least two choices'); - - const myVote = votes.at(0); - const myChoices = resolveMyChoices(myVote); - const totalScores = proposal.scores_total ?? 0; - - return proposal.choices.map((choice, idx) => { - const scores = proposal.scores?.[idx] ?? 0; - - return { - label: choice ?? never('Choice must not be null'), - votes: scores, - didVote: myChoices.includes(idx), - percentage: totalScores > 0 ? Math.max(0, Math.min(1, scores / totalScores)) * 100 : 0, - }; - }); -} - -/** - * Fetches details of a poll from Snapshot. - * - * @experimental - * @category Publications - * @group Hooks - * @param args - {@link UsePollDetailsArgs} - * - * @example - * ```tsx - * import { PollPublication, usePollDetails } from '@lens-protocol/react-web'; - * - * - * function Poll({ publication }: { publication: PollPublication }) { - * const { data: poll, error, loading } = usePollDetails({ publication }); - * - * if (loading) return

Loading...

; - * - * if (error) return

Error: {error.message}

; - * - * return ( - *
- *

{poll.title

- * - * {poll.choices.map((choice, idx) => ( - * - * ))} - *
- * ) - * } - * ``` - */ -export function usePollDetails({ - publication, -}: UsePollDetailsArgs): ReadResult { - const session = useSessionVar(); - - const { data, loading } = useGetSnapshotProposal( - useSnapshotApolloClient({ - variables: { - spaceId: publication.contentInsight.spaceId, - proposalId: publication.contentInsight.proposalId, - includeVotes: session?.isAuthenticated() ?? false, - voterAddress: session?.isAuthenticated() ? session.wallet.address : '', - }, - }), - ); - - if (data && !loading) { - if (data.proposal === null) { - return { - data: undefined, - error: new NotFoundError(`Snapshot Proposal ${publication.contentInsight.proposalId}`), - loading: false, - }; - } - - if (data.proposal.flagged) { - return { - data: undefined, - error: new NotFoundError( - `Snapshot Proposal ${publication.contentInsight.proposalId} might contain scams, offensive material, or be malicious in nature`, - ), - loading: false, - }; - } - - try { - return { - data: { - author: data.proposal.author, - choices: buildPollChoices(data.proposal, data.votes ?? []), - eligibility: resolveVoteEligibility(data.vp), - endAt: new Date(data.proposal.end), - isActive: data.proposal.state === 'active', - isSingleChoice: - data.proposal.type === SnapshotVotingSystem.SINGLE_CHOICE || - data.proposal.type === SnapshotVotingSystem.BASIC, - quorum: data.proposal.quorum, - snapshot: data.proposal.snapshot, - space: { - id: publication.contentInsight.spaceId, - name: data.proposal.space?.name ?? publication.contentInsight.spaceId, - }, - startAt: new Date(data.proposal.start), - system: data.proposal.type as SnapshotVotingSystem, - title: data.proposal.title, - totalVotes: data.proposal.scores_total ?? 0, - url: publication.contentInsight.url, - }, - error: undefined, - loading: false, - }; - } catch (error) { - assertError(error); - - return { - data: undefined, - error: new NotFoundError( - `Snapshot Proposal ${publication.contentInsight.proposalId} could not be processed due to\n${error.message}`, - ), - loading: false, - }; - } - } - - return { - data: undefined, - error: undefined, - loading: true, - }; -} diff --git a/packages/react-v1/src/polls/usePollVote.ts b/packages/react-v1/src/polls/usePollVote.ts deleted file mode 100644 index 5eadb0428c..0000000000 --- a/packages/react-v1/src/polls/usePollVote.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { PollPublication } from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { VoteChoice } from '@lens-protocol/domain/use-cases/polls'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useVotePollController } from './adapters/useVotePollController'; - -export type UsePollVoteArgs = { - /** - * The publication containing a poll - * - * **Pro-tip**: use {@link isPollPublication} to check if the publication contains a poll. - */ - publication: PollPublication; -}; - -export type { VoteChoice }; - -export type PollVoteOperation = Operation< - void, - PendingSigningRequestError | UserRejectedError | WalletConnectionError, - [VoteChoice] ->; - -/** - * Hook to vote on a poll. - * - * @experimental - * @category Publications - * @group Hooks - * @param args - {@link UsePollVoteArgs} - * - * @example - * - * ```tsx - * import { PollPublication, usePollVote } from '@lens-protocol/react-web'; - * - * function Poll({ publication }: { publication: PollPublication }) { - * const { execute, error, isPending } = usePollDetails({ publication }); - * - * const vote = async () => { - * const result = await execute({ choice: 0 }); - * - * if (result.isFailure()) { - * console.error(result.error); - * } - * } - * - * return ( - * - * ); - * } - * ``` - */ -export function usePollVote({ publication }: UsePollVoteArgs) { - const vote = useVotePollController(); - - return useOperation((choice: VoteChoice) => - vote({ - proposalId: publication.contentInsight.proposalId, - spaceId: publication.contentInsight.spaceId, - choice, - }), - ); -} diff --git a/packages/react-v1/src/profile/__tests__/useActiveProfile.spec.ts b/packages/react-v1/src/profile/__tests__/useActiveProfile.spec.ts deleted file mode 100644 index da01104e77..0000000000 --- a/packages/react-v1/src/profile/__tests__/useActiveProfile.spec.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { FragmentProfile, Profile, resetSession } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockProfileFragment, - mockSources, - simulateNotAuthenticated, - simulateAuthenticatedWallet, - simulateAuthenticatedProfile, -} from '@lens-protocol/api-bindings/mocks'; -import { mockProfileIdentifier, mockWalletData } from '@lens-protocol/domain/mocks'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { defaultMediaTransformsConfig } from '../../mediaTransforms'; -import { useActiveProfile } from '../useActiveProfile'; - -function setupUseActiveProfile({ profile }: { profile: Profile }) { - const sources = mockSources(); - - const apolloClient = mockLensApolloClient(); - - apolloClient.cache.writeFragment({ - id: apolloClient.cache.identify({ - __typename: 'Profile', - id: profile.id, - }), - fragment: FragmentProfile, - fragmentName: 'Profile', - data: profile, - }); - - return renderHookWithMocks(() => useActiveProfile(), { - mocks: { sources, mediaTransforms: defaultMediaTransformsConfig, apolloClient }, - }); -} - -describe(`Given the ${useActiveProfile.name} hook`, () => { - const profile = mockProfileFragment(); - - describe(`when the current session is "null"`, () => { - beforeAll(() => { - resetSession(); - }); - - it('should return the expected loading state', async () => { - const { result } = setupUseActiveProfile({ profile }); - - expect(result.current.loading).toBeTruthy(); - expect(result.current.data).toBeUndefined(); - }); - }); - - describe(`when the current session is anonymous`, () => { - beforeAll(() => { - simulateNotAuthenticated(); - }); - - it('should return null', async () => { - const { result } = setupUseActiveProfile({ profile }); - - expect(result.current.data).toBeNull(); - }); - }); - - describe(`when the current authenticated session does not have an active profile`, () => { - beforeAll(() => { - simulateAuthenticatedWallet(mockWalletData()); - }); - - it('should return null', async () => { - const { result } = setupUseActiveProfile({ profile }); - - expect(result.current.data).toBeNull(); - }); - }); - - describe(`when the current session includes an active profile`, () => { - beforeAll(() => { - simulateAuthenticatedProfile( - mockProfileIdentifier(profile), - mockWalletData({ address: profile.ownedBy }), - ); - }); - - it('should return the expected profile data without flickering of the "loading" flag', async () => { - const { result } = setupUseActiveProfile({ profile }); - - expect(result.current.loading).toBe(false); - expect(result.current.data).toMatchObject({ - id: profile.id, - }); - }); - }); -}); diff --git a/packages/react-v1/src/profile/__tests__/useExploreProfiles.spec.ts b/packages/react-v1/src/profile/__tests__/useExploreProfiles.spec.ts deleted file mode 100644 index cb187bb443..0000000000 --- a/packages/react-v1/src/profile/__tests__/useExploreProfiles.spec.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Profile, ProfileSortCriteria } from '@lens-protocol/api-bindings'; -import { - mockExploreProfilesResponse, - mockLensApolloClient, - mockProfileFragment, - mockSources, - simulateAuthenticatedProfile, - simulateAuthenticatedWallet, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../../utils'; -import { useExploreProfiles, UseExploreProfilesArgs } from '../useExploreProfiles'; - -function setupTestScenario({ - expectedObserverId, - result, - ...args -}: UseExploreProfilesArgs & { result: Profile[]; expectedObserverId?: ProfileId }) { - const sources = mockSources(); - - return renderHookWithMocks( - () => useExploreProfiles({ sortCriteria: ProfileSortCriteria.CreatedOn, ...args }), - { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - - apolloClient: mockLensApolloClient([ - mockExploreProfilesResponse({ - variables: { - limit: DEFAULT_PAGINATED_QUERY_LIMIT, - sortCriteria: ProfileSortCriteria.CreatedOn, - ...args, - sources, - observerId: expectedObserverId ?? null, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - items: result, - }), - ]), - }, - }, - ); -} - -describe(`Given the ${useExploreProfiles.name} hook`, () => { - const profiles = [mockProfileFragment()]; - const expectations = profiles.map(({ __typename, id }) => ({ __typename, id })); - - describe('when the query returns data successfully', () => { - beforeAll(() => { - simulateAuthenticatedWallet(); - }); - - it('should return list of profiles', async () => { - const { result } = setupTestScenario({ result: profiles }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - result: profiles, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - observerId, - result: profiles, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/profile/__tests__/useMutualFollowers.spec.ts b/packages/react-v1/src/profile/__tests__/useMutualFollowers.spec.ts deleted file mode 100644 index 044b653d71..0000000000 --- a/packages/react-v1/src/profile/__tests__/useMutualFollowers.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { - mockLensApolloClient, - mockMutualFollowersResponse, - mockProfileFragment, - mockSources, -} from '@lens-protocol/api-bindings/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { useMutualFollowers } from '../useMutualFollowers'; - -const sources = mockSources(); - -describe('Given the useMutualFollowers hook', () => { - const observer = mockProfileFragment(); - const viewingProfile = mockProfileFragment(); - - const profiles = [mockProfileFragment()]; - const expectations = profiles.map(({ __typename, id }) => ({ __typename, id })); - - describe('when the query returns data successfully', () => { - it('should return mutual followers profiles', async () => { - const { result } = renderHookWithMocks( - () => - useMutualFollowers({ - observerId: observer.id, - viewingProfileId: viewingProfile.id, - }), - { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockMutualFollowersResponse({ - variables: { - observerId: observer.id, - viewingProfileId: viewingProfile.id, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - profiles, - }), - ]), - }, - }, - ); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/profile/__tests__/useProfile.spec.ts b/packages/react-v1/src/profile/__tests__/useProfile.spec.ts deleted file mode 100644 index 3198ca0664..0000000000 --- a/packages/react-v1/src/profile/__tests__/useProfile.spec.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockGetProfileResponse, - mockProfileFragment, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { NotFoundError } from '../../NotFoundError'; -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { useProfile, UseProfileArgs } from '../useProfile'; - -function setupTestScenario({ - profile, - expectedObserverId, - ...args -}: UseProfileArgs & { profile: Profile | null; expectedObserverId: ProfileId | null }) { - const sources = mockSources(); - - return renderHookWithMocks(() => useProfile(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockGetProfileResponse({ - profile, - variables: { - request: args.profileId - ? { - profileId: args.profileId, - } - : { - handle: args.handle, - }, - observerId: expectedObserverId, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - }), - ]), - }, - }); -} - -describe(`Given the ${useProfile.name} hook`, () => { - const profile = mockProfileFragment(); - const expectations = { __typename: 'Profile', id: profile.id }; - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe.each([ - { - precondition: 'and NO Active Profile set', - activeProfileValue: null, - }, - { - precondition: 'and an Active Profile set', - activeProfileValue: mockProfile(), - }, - ])('$precondition', ({ activeProfileValue }) => { - describe.each([ - { - description: 'when invoked with a profile id', - args: { profileId: profile.id }, - }, - { - description: 'when invoked with a profile handle', - args: { handle: profile.handle }, - }, - ])('$description', ({ args }) => { - beforeAll(() => { - if (activeProfileValue) { - simulateAuthenticatedProfile(activeProfileValue); - } - }); - - it('should settle with the profile data', async () => { - const { result } = setupTestScenario({ - ...args, - profile, - expectedObserverId: activeProfileValue?.id ?? null, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to specify the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - ...args, - profile, - observerId, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it(`should settle with a ${NotFoundError.name} if not found`, async () => { - const { result } = setupTestScenario({ - ...args, - profile: null, - expectedObserverId: activeProfileValue?.id ?? null, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.error).toBeInstanceOf(NotFoundError); - }); - }); - }); -}); diff --git a/packages/react-v1/src/profile/__tests__/useProfiles.spec.ts b/packages/react-v1/src/profile/__tests__/useProfiles.spec.ts deleted file mode 100644 index b68e7f1837..0000000000 --- a/packages/react-v1/src/profile/__tests__/useProfiles.spec.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { - mockGetAllProfilesResponse, - mockLensApolloClient, - mockProfileFragment, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../../utils'; -import { useProfiles, UseProfilesArgs } from '../useProfiles'; - -function setupTestScenario({ - expectedObserverId, - result, - ...args -}: UseProfilesArgs & { result: Profile[]; expectedObserverId?: ProfileId }) { - const sources = mockSources(); - - return renderHookWithMocks(() => useProfiles(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockGetAllProfilesResponse({ - variables: { - byHandles: args.handles, - byProfileIds: args.profileIds, - limit: DEFAULT_PAGINATED_QUERY_LIMIT, - sources, - observerId: expectedObserverId ?? null, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - profiles: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useProfiles.name} hook`, () => { - const profiles = [mockProfileFragment()]; - const expectations = profiles.map(({ id }) => ({ __typename: 'Profile', id })); - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe.each([ - { - precondition: 'and NO Active Profile set', - activeProfileValue: null, - }, - { - precondition: 'and an Active Profile set', - activeProfileValue: mockProfile(), - }, - ])('$precondition', ({ activeProfileValue }) => { - describe.each([ - { - description: 'when invoked with a list of profile IDs', - args: { profileIds: profiles.map(({ id }) => id) }, - }, - { - description: 'when invoked with a list of profile handles', - args: { handles: profiles.map(({ handle }) => handle) }, - }, - ])('$description', ({ args }) => { - beforeAll(() => { - if (activeProfileValue) { - simulateAuthenticatedProfile(activeProfileValue); - } - }); - - it('should return list of profiles', async () => { - const { result } = setupTestScenario({ - ...args, - result: profiles, - expectedObserverId: activeProfileValue?.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - ...args, - observerId, - result: profiles, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - }); -}); diff --git a/packages/react-v1/src/profile/__tests__/useProfilesOwnedBy.spec.ts b/packages/react-v1/src/profile/__tests__/useProfilesOwnedBy.spec.ts deleted file mode 100644 index f89193b692..0000000000 --- a/packages/react-v1/src/profile/__tests__/useProfilesOwnedBy.spec.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { - mockGetAllProfilesResponse, - mockLensApolloClient, - mockProfileFragment, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { useProfilesOwnedBy, UseProfilesOwnedByArgs } from '../useProfilesOwnedBy'; - -function setupTestScenario({ - result, - expectedObserverId, - address, - ...others -}: UseProfilesOwnedByArgs & { expectedObserverId?: ProfileId; result: Profile[] }) { - const sources = mockSources(); - - return renderHookWithMocks(() => useProfilesOwnedBy({ address, ...others }), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockGetAllProfilesResponse({ - variables: { - ...others, - byOwnerAddresses: [address], - observerId: expectedObserverId ?? null, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - profiles: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useProfilesOwnedBy.name} hook`, () => { - const address = mockEthereumAddress(); - const profiles = [ - mockProfileFragment({ ownedBy: address }), - mockProfileFragment({ ownedBy: address }), - ]; - const expectations = profiles.map(({ id }) => ({ __typename: 'Profile', id })); - - describe('when the query returns data successfully', () => { - beforeAll(() => { - simulateNotAuthenticated(); - }); - - it('should return the profiles owned by the specified address', async () => { - const { result } = setupTestScenario({ address, result: profiles }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - address, - result: profiles, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - address, - observerId, - result: profiles, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/profile/__tests__/useProfilesOwnedByMe.spec.ts b/packages/react-v1/src/profile/__tests__/useProfilesOwnedByMe.spec.ts deleted file mode 100644 index 437effcb22..0000000000 --- a/packages/react-v1/src/profile/__tests__/useProfilesOwnedByMe.spec.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { - mockGetAllProfilesResponse, - mockLensApolloClient, - mockProfileFragment, - mockSources, - simulateAuthenticatedProfile, - simulateAuthenticatedWallet, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId, mockWalletData } from '@lens-protocol/domain/mocks'; -import { EthereumAddress } from '@lens-protocol/shared-kernel'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { useProfilesOwnedByMe, UseProfilesOwnedByMeArgs } from '../useProfilesOwnedByMe'; - -function setupTestScenario({ - address, - result, - expectedObserverId, - ...args -}: UseProfilesOwnedByMeArgs & { - address: EthereumAddress; - expectedObserverId?: ProfileId; - result: Profile[]; -}) { - const sources = mockSources(); - - return renderHookWithMocks(() => useProfilesOwnedByMe(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockGetAllProfilesResponse({ - variables: { - ...args, - byOwnerAddresses: [address], - observerId: expectedObserverId ?? null, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - profiles: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useProfilesOwnedByMe.name} hook`, () => { - const wallet = mockWalletData(); - const profiles = [ - mockProfileFragment({ ownedBy: wallet.address, ownedByMe: true }), - mockProfileFragment({ ownedBy: wallet.address, ownedByMe: true }), - ]; - const expectedProfiles = profiles.map(({ id }) => ({ id })); - - describe('and there is an Active Wallet defined', () => { - beforeAll(() => { - simulateAuthenticatedWallet(wallet); - }); - - describe('when invoked', () => { - it('should return the profiles owned by the Active Wallet address', async () => { - const { result } = setupTestScenario({ address: wallet.address, result: profiles }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectedProfiles); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile, wallet); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - address: wallet.address, - result: profiles, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectedProfiles); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - address: wallet.address, - observerId, - result: profiles, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectedProfiles); - }); - }); - }); -}); diff --git a/packages/react-v1/src/profile/__tests__/useProfilesToFollow.spec.ts b/packages/react-v1/src/profile/__tests__/useProfilesToFollow.spec.ts deleted file mode 100644 index 229155fc5b..0000000000 --- a/packages/react-v1/src/profile/__tests__/useProfilesToFollow.spec.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockProfileFragment, - mockProfilesToFollowResponse, - mockSources, - simulateAuthenticatedProfile, - simulateAuthenticatedWallet, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { useProfilesToFollow, UseProfilesToFollowArgs } from '../useProfilesToFollow'; - -function setupTestScenario({ - expectedObserverId, - profiles, - ...args -}: UseProfilesToFollowArgs & { - expectedObserverId?: ProfileId; - profiles: Profile[]; -}) { - const sources = mockSources(); - - return renderHookWithMocks(() => useProfilesToFollow(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockProfilesToFollowResponse({ - variables: { - observerId: expectedObserverId ?? null, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - profiles, - }), - ]), - }, - }); -} - -describe(`Given the ${useProfilesToFollow.name} hook`, () => { - const profiles = [mockProfileFragment()]; - const expectations = profiles.map((profile) => ({ __typename: 'Profile', id: profile.id })); - - beforeAll(() => { - simulateAuthenticatedWallet(); - }); - - describe('when the query returns data successfully', () => { - it('should return profiles to follow', async () => { - const { result } = setupTestScenario({ profiles }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ profiles, expectedObserverId: activeProfile.id }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - observerId, - profiles, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/profile/__tests__/useSearchProfiles.spec.ts b/packages/react-v1/src/profile/__tests__/useSearchProfiles.spec.ts deleted file mode 100644 index 41fb898030..0000000000 --- a/packages/react-v1/src/profile/__tests__/useSearchProfiles.spec.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockSearchProfilesResponse, - mockProfileFragment, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { useSearchProfiles, UseSearchProfilesArgs } from '../useSearchProfiles'; - -function setupTestScenario({ - expectedObserverId, - result, - ...args -}: UseSearchProfilesArgs & { result: Profile[]; expectedObserverId?: ProfileId }) { - const sources = mockSources(); - - return renderHookWithMocks(() => useSearchProfiles(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockSearchProfilesResponse({ - variables: { - ...args, - limit: 10, - observerId: expectedObserverId ?? null, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - items: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useSearchProfiles.name} hook`, () => { - const query = 'query_test'; - const profiles = [mockProfileFragment()]; - const expectations = profiles.map(({ id }) => ({ __typename: 'Profile', id })); - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe('when the query returns data successfully', () => { - it('should return profiles that match the search criteria', async () => { - const { result } = setupTestScenario({ query, result: profiles }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - query, - result: profiles, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - query, - observerId, - result: profiles, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/profile/adapters/ActiveProfileGateway.ts b/packages/react-v1/src/profile/adapters/ActiveProfileGateway.ts deleted file mode 100644 index f0447b7ceb..0000000000 --- a/packages/react-v1/src/profile/adapters/ActiveProfileGateway.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Profile, ProfileId } from '@lens-protocol/domain/entities'; -import * as profileUseCases from '@lens-protocol/domain/use-cases/profile'; -import * as walletsUseCases from '@lens-protocol/domain/use-cases/wallets'; -import { IStorage } from '@lens-protocol/storage'; -import { z } from 'zod'; - -export const StoredActiveProfileData = z.object({ - id: z.custom(), - handle: z.string(), -}); - -export type StoredActiveProfileData = z.infer; - -export class ActiveProfileGateway - implements profileUseCases.IActiveProfileGateway, walletsUseCases.IActiveProfileGateway -{ - constructor(private readonly activeProfileStorage: IStorage) {} - - async setActiveProfile(profile: Profile): Promise { - await this.activeProfileStorage.set(profile); - } - - async getActiveProfile(): Promise { - const data = await this.activeProfileStorage.get(); - - if (!data) { - return null; - } - return data; - } - - async reset() { - await this.activeProfileStorage.reset(); - } -} diff --git a/packages/react-v1/src/profile/adapters/CreateProfilePresenter.ts b/packages/react-v1/src/profile/adapters/CreateProfilePresenter.ts deleted file mode 100644 index d42081c558..0000000000 --- a/packages/react-v1/src/profile/adapters/CreateProfilePresenter.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { TransactionError } from '@lens-protocol/domain/entities'; -import { - CreateProfileRequest, - DuplicatedHandleError, - ICreateProfilePresenter, -} from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError, TransactionData } from '@lens-protocol/domain/use-cases/transactions'; -import { Deferred, Failure, failure, Result, success } from '@lens-protocol/shared-kernel'; - -import { AsyncTransactionResult } from '../../transactions/adapters/AsyncTransactionResult'; -import { IProfileCacheManager } from '../../transactions/adapters/IProfileCacheManager'; - -export type CreateProfileAsyncResult = AsyncTransactionResult; - -export class CreateProfilePresenter implements ICreateProfilePresenter { - private deferredResult = new Deferred>(); - - private earlyFailure: Failure | null = null; - - constructor( - private readonly profileCacheManager: IProfileCacheManager, // eslint-disable-next-line @typescript-eslint/no-empty-function - ) {} - - async present( - result: Result< - TransactionData, - BroadcastingError | DuplicatedHandleError | TransactionError - >, - ) { - if (result.isFailure()) { - if ( - result.error instanceof BroadcastingError || - result.error instanceof DuplicatedHandleError - ) { - this.earlyFailure = failure(result.error); - return; - } - - this.deferredResult.resolve(failure(result.error)); - return; - } - const profile = await this.profileCacheManager.fetchNewProfile(result.value.request.handle); - - this.deferredResult.resolve(success(profile)); - } - - asResult(): Result { - if (this.earlyFailure) { - return this.earlyFailure; - } - - return success({ - waitForCompletion: async () => { - return this.deferredResult.promise; - }, - }); - } -} diff --git a/packages/react-v1/src/profile/adapters/ProfileGateway.ts b/packages/react-v1/src/profile/adapters/ProfileGateway.ts deleted file mode 100644 index ea020d8326..0000000000 --- a/packages/react-v1/src/profile/adapters/ProfileGateway.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { - GetProfileData, - GetProfileVariables, - GetProfileDocument, - SafeApolloClient, - GetAllProfilesData, - GetAllProfilesVariables, - GetAllProfilesDocument, -} from '@lens-protocol/api-bindings'; -import { Profile, ProfileId } from '@lens-protocol/domain/entities'; -import { IProfileGateway } from '@lens-protocol/domain/use-cases/profile'; - -import { MediaTransformsConfig, mediaTransformConfigToQueryVariables } from '../../mediaTransforms'; - -export class ProfileGateway implements IProfileGateway { - constructor( - private readonly apolloClient: SafeApolloClient, - private readonly mediaTransforms: MediaTransformsConfig, - ) {} - - async getAllProfilesByOwnerAddress(address: string): Promise { - const { data } = await this.apolloClient.query({ - query: GetAllProfilesDocument, - // 'sources' and 'observerId' are not needed. We just use 'id' and 'handle' for now. - variables: { - byOwnerAddresses: [address], - limit: 10, - ...mediaTransformConfigToQueryVariables(this.mediaTransforms), - }, - }); - - return data.result.items.map(({ id, handle }) => Profile.create({ id, handle })); - } - - async getProfileById(profileId: ProfileId): Promise { - const { data } = await this.apolloClient.query({ - query: GetProfileDocument, - // 'sources' and 'observerId' are not needed. We just use 'id' and 'handle' for now. - variables: { - request: { profileId }, - ...mediaTransformConfigToQueryVariables(this.mediaTransforms), - }, - }); - - if (data.result === null) { - return null; - } - return Profile.create({ - id: data.result.id, - handle: data.result.handle, - }); - } -} diff --git a/packages/react-v1/src/profile/adapters/ProfileTransactionGateway.ts b/packages/react-v1/src/profile/adapters/ProfileTransactionGateway.ts deleted file mode 100644 index 9d3d7f00a9..0000000000 --- a/packages/react-v1/src/profile/adapters/ProfileTransactionGateway.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { - CreateProfileDocument, - CreateProfileData, - CreateProfileVariables, - SafeApolloClient, - RelayErrorReasons, -} from '@lens-protocol/api-bindings'; -import { NativeTransaction } from '@lens-protocol/domain/entities'; -import { - CreateProfileRequest, - DuplicatedHandleError, - IProfileTransactionGateway, -} from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; -import { v4 } from 'uuid'; - -import { resolveFollowModuleParams } from '../../transactions/adapters/FollowPolicyCallGateway'; -import { ITransactionFactory } from '../../transactions/adapters/ITransactionFactory'; -import { handleRelayError } from '../../transactions/adapters/relayer'; - -export class ProfileTransactionGateway implements IProfileTransactionGateway { - constructor( - private apolloClient: SafeApolloClient, - private factory: ITransactionFactory, - ) {} - - async createProfileTransaction( - request: T, - ): PromiseResult, DuplicatedHandleError | BroadcastingError> { - const { data } = await this.apolloClient.mutate({ - mutation: CreateProfileDocument, - variables: { - request: { - handle: request.handle, - followModule: request.followPolicy - ? resolveFollowModuleParams(request.followPolicy) - : null, - profilePictureUri: request.profileImage ?? null, - }, - }, - }); - - if (data.result.__typename === 'RelayError') { - switch (data.result.reason) { - case RelayErrorReasons.HandleTaken: - return failure(new DuplicatedHandleError(request.handle)); - - default: - return handleRelayError(data.result); - } - } - - const transaction = this.factory.createNativeTransaction({ - chainType: ChainType.POLYGON, - request, - id: v4(), - indexingId: data.result.txId, - txHash: data.result.txHash, - }); - - return success(transaction); - } -} diff --git a/packages/react-v1/src/profile/adapters/__tests__/ActiveProfileGateway.spec.ts b/packages/react-v1/src/profile/adapters/__tests__/ActiveProfileGateway.spec.ts deleted file mode 100644 index 964437052a..0000000000 --- a/packages/react-v1/src/profile/adapters/__tests__/ActiveProfileGateway.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { mockProfile } from '@lens-protocol/domain/mocks'; -import { mockStorage } from '@lens-protocol/storage/mocks'; - -import { ActiveProfileGateway, StoredActiveProfileData } from '../ActiveProfileGateway'; - -describe(`Given an instance of the ${ActiveProfileGateway.name}`, () => { - describe(`when the "${ActiveProfileGateway.prototype.setActiveProfile.name}" method is invoked`, () => { - it(`should persist the given profile handle so that it can be retrieved later on via ""${ActiveProfileGateway.prototype.getActiveProfile.name}"" method`, async () => { - const profile = mockProfile(); - const activeProfileStorage = mockStorage(null); - const gateway = new ActiveProfileGateway(activeProfileStorage); - - await gateway.setActiveProfile(profile); - - const stored = await gateway.getActiveProfile(); - - expect(stored).toEqual(profile); - }); - }); -}); diff --git a/packages/react-v1/src/profile/adapters/__tests__/CreateProfilePresenter.spec.ts b/packages/react-v1/src/profile/adapters/__tests__/CreateProfilePresenter.spec.ts deleted file mode 100644 index e295c7dadb..0000000000 --- a/packages/react-v1/src/profile/adapters/__tests__/CreateProfilePresenter.spec.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { mockProfileFragment } from '@lens-protocol/api-bindings/mocks'; -import { TransactionError, TransactionErrorReason } from '@lens-protocol/domain/entities'; -import { mockCreateProfileRequest, mockTransactionData } from '@lens-protocol/domain/mocks'; -import { - CreateProfileRequest, - DuplicatedHandleError, -} from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError, TransactionData } from '@lens-protocol/domain/use-cases/transactions'; -import { failure, Result, success } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; - -import { IProfileCacheManager } from '../../../transactions/adapters/IProfileCacheManager'; -import { CreateProfilePresenter } from '../CreateProfilePresenter'; - -function setupTestScenario() { - const cacheManager = mock(); - - const presenter = new CreateProfilePresenter(cacheManager); - - return { - cacheManager, - presenter, - }; -} - -describe(`Given an instance of the ${CreateProfilePresenter.name}`, () => { - describe.each([new DuplicatedHandleError('handle'), new BroadcastingError('error')])( - `and the "${CreateProfilePresenter.prototype.present.name}" method is called with failure($name)`, - (error) => { - const result: Result = failure(error); - - describe(`when the "${CreateProfilePresenter.prototype.asResult.name}" is called`, () => { - it(`should eagerly return the failure`, async () => { - const { presenter } = setupTestScenario(); - - await presenter.present(result); - - expect(presenter.asResult()).toEqual(result); - }); - }); - }, - ); - - describe(`and the "${CreateProfilePresenter.prototype.asResult.name}" method is called`, () => { - describe(`when the "${CreateProfilePresenter.prototype.present.name}" method is subsequently called`, () => { - describe(`with failure(${TransactionError.name})`, () => { - const result: Result = failure( - new TransactionError(TransactionErrorReason.REVERTED), - ); - - it('should yield the failure as result of the "waitForCompletion" callback', async () => { - const { presenter } = setupTestScenario(); - - const broadcasted = presenter.asResult(); - - const [completion] = await Promise.all([ - broadcasted.unwrap().waitForCompletion(), - presenter.present(result), - ]); - - expect(completion).toEqual(result); - }); - }); - - describe(`with success(TransactionData)`, () => { - const request = mockCreateProfileRequest(); - const result: Result, never> = success( - mockTransactionData({ request }), - ); - const profile = mockProfileFragment(); - - it('should fetch and return the newly create Profile as result of the "waitForCompletion" callback', async () => { - const { cacheManager, presenter } = setupTestScenario(); - cacheManager.fetchNewProfile.mockResolvedValue(profile); - - const broadcasted = presenter.asResult(); - - const [completion] = await Promise.all([ - broadcasted.unwrap().waitForCompletion(), - presenter.present(result), - ]); - - expect(completion).toEqual(success(profile)); - }); - }); - }); - }); -}); diff --git a/packages/react-v1/src/profile/adapters/__tests__/ProfileGateway.spec.ts b/packages/react-v1/src/profile/adapters/__tests__/ProfileGateway.spec.ts deleted file mode 100644 index 4d2d1f60bf..0000000000 --- a/packages/react-v1/src/profile/adapters/__tests__/ProfileGateway.spec.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { SafeApolloClient } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockGetProfileResponse, - mockProfileFragment, - mockGetAllProfilesResponse, -} from '@lens-protocol/api-bindings/mocks'; -import { Profile } from '@lens-protocol/domain/entities'; -import { mockProfileId } from '@lens-protocol/domain/mocks'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; - -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../../mediaTransforms'; -import { ProfileGateway } from '../ProfileGateway'; - -function setupProfileGateway({ apolloClient }: { apolloClient: SafeApolloClient }) { - const mediaTransforms = defaultMediaTransformsConfig; - return new ProfileGateway(apolloClient, mediaTransforms); -} - -describe(`Given an instance of the ${ProfileGateway.name}`, () => { - describe(`when "${ProfileGateway.prototype.getAllProfilesByOwnerAddress.name}" method is invoked`, () => { - it('should return all Profile entities owned by the given address', async () => { - const address = mockEthereumAddress(); - const profileDataFragment = mockProfileFragment(); - const apolloClient = mockLensApolloClient([ - mockGetAllProfilesResponse({ - variables: { - byOwnerAddresses: [address], - limit: 10, - sources: [], - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - profiles: [profileDataFragment], - }), - ]); - const gateway = setupProfileGateway({ apolloClient }); - - const [profile] = await gateway.getAllProfilesByOwnerAddress(address); - - expect(profile).toBeInstanceOf(Profile); - expect(profile).toEqual({ - id: profileDataFragment.id, - handle: profileDataFragment.handle, - }); - }); - }); - - describe(`when "${ProfileGateway.prototype.getProfileById.name}" method is invoked`, () => { - it('should return the corresponding Profile entity', async () => { - const profileDataFragment = mockProfileFragment(); - const apolloClient = mockLensApolloClient([ - mockGetProfileResponse({ - variables: { - request: { profileId: profileDataFragment.id }, - sources: [], - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - profile: profileDataFragment, - }), - ]); - const gateway = setupProfileGateway({ apolloClient }); - - const profile = await gateway.getProfileById(profileDataFragment.id); - - expect(profile).toBeInstanceOf(Profile); - expect(profile).toEqual({ - id: profileDataFragment.id, - handle: profileDataFragment.handle, - }); - }); - - it('should return null if the Profile does not exist', async () => { - const profileId = mockProfileId(); - const apolloClient = mockLensApolloClient([ - mockGetProfileResponse({ - variables: { - request: { profileId }, - sources: [], - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - profile: null, - }), - ]); - const gateway = setupProfileGateway({ apolloClient }); - - const profile = await gateway.getProfileById(profileId); - - expect(profile).toBeNull(); - }); - }); -}); diff --git a/packages/react-v1/src/profile/adapters/__tests__/ProfileTransactionGateway.spec.ts b/packages/react-v1/src/profile/adapters/__tests__/ProfileTransactionGateway.spec.ts deleted file mode 100644 index 504d7e657b..0000000000 --- a/packages/react-v1/src/profile/adapters/__tests__/ProfileTransactionGateway.spec.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { SafeApolloClient, RelayErrorReasons } from '@lens-protocol/api-bindings'; -import { - mockRelayerResultFragment, - mockRelayErrorFragment, - mockLensApolloClient, - mockCreateProfileResponse, -} from '@lens-protocol/api-bindings/mocks'; -import { NativeTransaction } from '@lens-protocol/domain/entities'; -import { - mockChargeFollowConfig, - mockNoFeeFollowConfig, - mockCreateProfileRequest, -} from '@lens-protocol/domain/mocks'; -import { DuplicatedHandleError, FollowPolicyType } from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType } from '@lens-protocol/shared-kernel'; - -import { mockITransactionFactory } from '../../../transactions/adapters/__helpers__/mocks'; -import { ProfileTransactionGateway } from '../ProfileTransactionGateway'; - -function setupProfileTransactionGateway({ apollo }: { apollo: SafeApolloClient }) { - const factory = mockITransactionFactory(); - return new ProfileTransactionGateway(apollo, factory); -} - -describe(`Given an instance of the ${ProfileTransactionGateway.name}`, () => { - describe(`when calling the "${ProfileTransactionGateway.prototype.createProfileTransaction.name}" method`, () => { - const request = mockCreateProfileRequest(); - - it(`should create the expected "${NativeTransaction.name}"`, async () => { - const relayerResult = mockRelayerResultFragment(); - - const apollo = mockLensApolloClient([ - mockCreateProfileResponse({ - request: { - handle: request.handle, - followModule: null, - profilePictureUri: null, - }, - result: relayerResult, - }), - ]); - - const profileTransactionGateway = setupProfileTransactionGateway({ apollo }); - - const result = await profileTransactionGateway.createProfileTransaction(request); - - expect(result.unwrap()).toBeInstanceOf(NativeTransaction); - expect(result.unwrap()).toEqual( - expect.objectContaining({ - chainType: ChainType.POLYGON, - hash: relayerResult.txHash, - id: expect.any(String), - request, - }), - ); - }); - - const chargeFollowConfig = mockChargeFollowConfig(); - - it.each([ - { - followPolicy: chargeFollowConfig, - expectedFollowModuleParams: { - feeFollowModule: { - amount: { - currency: chargeFollowConfig.amount.asset.address, - value: chargeFollowConfig.amount.toSignificantDigits(), - }, - recipient: chargeFollowConfig.recipient, - }, - }, - }, - { - followPolicy: mockNoFeeFollowConfig({ - type: FollowPolicyType.ANYONE, - }), - expectedFollowModuleParams: { - freeFollowModule: true, - }, - }, - { - followPolicy: mockNoFeeFollowConfig({ - type: FollowPolicyType.NO_ONE, - }), - expectedFollowModuleParams: { - revertFollowModule: true, - }, - }, - { - followPolicy: mockNoFeeFollowConfig({ - type: FollowPolicyType.ONLY_PROFILE_OWNERS, - }), - expectedFollowModuleParams: { - profileFollowModule: true, - }, - }, - ])( - `should allow to contextually setup the $followPolicy.type follow policy`, - async ({ followPolicy, expectedFollowModuleParams }) => { - const request = mockCreateProfileRequest({ followPolicy }); - const relayerResult = mockRelayerResultFragment(); - - const apollo = mockLensApolloClient([ - mockCreateProfileResponse({ - request: { - handle: request.handle, - followModule: expectedFollowModuleParams, - profilePictureUri: null, - }, - result: relayerResult, - }), - ]); - - const profileTransactionGateway = setupProfileTransactionGateway({ apollo }); - - const result = await profileTransactionGateway.createProfileTransaction(request); - - expect(result.unwrap()).toBeInstanceOf(NativeTransaction); - }, - ); - - it(`should allow to contextually setup the profile image`, async () => { - const url = 'https://example.com/image.png'; - const request = mockCreateProfileRequest({ profileImage: url }); - const relayerResult = mockRelayerResultFragment(); - - const apollo = mockLensApolloClient([ - mockCreateProfileResponse({ - request: { - handle: request.handle, - followModule: null, - profilePictureUri: url, - }, - result: relayerResult, - }), - ]); - - const profileTransactionGateway = setupProfileTransactionGateway({ apollo }); - - const result = await profileTransactionGateway.createProfileTransaction(request); - - expect(result.unwrap()).toBeInstanceOf(NativeTransaction); - }); - - it.each([ - { - expected: new DuplicatedHandleError(request.handle), - relayError: mockRelayErrorFragment(RelayErrorReasons.HandleTaken), - }, - { - expected: new BroadcastingError(RelayErrorReasons.Rejected), - relayError: mockRelayErrorFragment(RelayErrorReasons.Rejected), - }, - ])( - `should fail w/ a ${BroadcastingError.name} in case of RelayError response with "$relayError.reason" reason`, - async ({ relayError, expected }) => { - const apollo = mockLensApolloClient([ - mockCreateProfileResponse({ - request: { - handle: request.handle, - followModule: null, - profilePictureUri: null, - }, - result: relayError, - }), - ]); - const profileTransactionGateway = setupProfileTransactionGateway({ apollo }); - - const result = await profileTransactionGateway.createProfileTransaction(request); - - expect(() => result.unwrap()).toThrow(expected); - }, - ); - }); -}); diff --git a/packages/react-v1/src/profile/adapters/useCreateProfileController.ts b/packages/react-v1/src/profile/adapters/useCreateProfileController.ts deleted file mode 100644 index fdd021f688..0000000000 --- a/packages/react-v1/src/profile/adapters/useCreateProfileController.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { CreateProfile, CreateProfileRequest } from '@lens-protocol/domain/use-cases/profile'; - -import { useSharedDependencies } from '../../shared'; -import { CreateProfilePresenter } from './CreateProfilePresenter'; -import { ProfileTransactionGateway } from './ProfileTransactionGateway'; - -export function useCreateProfileController() { - const { apolloClient, profileCacheManager, transactionFactory, transactionQueue } = - useSharedDependencies(); - - return async (request: CreateProfileRequest) => { - const presenter = new CreateProfilePresenter(profileCacheManager); - const gateway = new ProfileTransactionGateway(apolloClient, transactionFactory); - const createProfile = new CreateProfile(gateway, transactionQueue, presenter); - - await createProfile.execute(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/profile/adapters/useSwitchActiveProfileController.ts b/packages/react-v1/src/profile/adapters/useSwitchActiveProfileController.ts deleted file mode 100644 index 279194618d..0000000000 --- a/packages/react-v1/src/profile/adapters/useSwitchActiveProfileController.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { - SwitchActiveProfile, - SwitchActiveProfileRequest, -} from '@lens-protocol/domain/use-cases/profile'; - -import { useSharedDependencies } from '../../shared'; - -export function useSwitchActiveProfileController() { - const { activeProfileGateway, profileGateway, sessionPresenter } = useSharedDependencies(); - - return async (request: SwitchActiveProfileRequest) => { - const activeProfileLoader = new SwitchActiveProfile( - profileGateway, - activeProfileGateway, - sessionPresenter, - ); - - await activeProfileLoader.switch(request); - }; -} diff --git a/packages/react-v1/src/profile/index.ts b/packages/react-v1/src/profile/index.ts deleted file mode 100644 index e866a08aae..0000000000 --- a/packages/react-v1/src/profile/index.ts +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Profile hooks - */ -export * from './useActiveProfile'; -export * from './useActiveProfileSwitch'; -export * from './useCollectedPublications'; -export * from './useCreateProfile'; -export * from './useExploreProfiles'; -export * from './useMutualFollowers'; -export * from './useProfile'; -export * from './useProfileGuardian'; -export * from './useProfiles'; -export * from './useProfileFollowers'; -export * from './useProfileFollowing'; -export * from './useProfilesOwnedBy'; -export * from './useProfilesOwnedByMe'; -export * from './useProfilesToFollow'; -export * from './useSearchProfiles'; - -/** - * Follow policy - */ -export { FollowPolicyType } from '@lens-protocol/domain/use-cases/profile'; -export type { - FollowPolicyConfig, - ChargeFollowConfig, - NoFeeFollowConfig, -} from '@lens-protocol/domain/use-cases/profile'; -export type { - FollowPolicy, - ChargeFollowPolicy, - NoFeeFollowPolicy, - OpenFollowPolicy, -} from '@lens-protocol/api-bindings'; - -/** - * Profile fragments - */ -export type { - Attribute, - Follower, - Following, - FollowStatus, - NftImage, - Profile, - ProfileAttributeReader, - ProfileAttributes, - ProfileCoverMedia, - ProfileFields, - ProfileOwnedByMe, - ProfilePictureMedia, - ProfileStats, -} from '@lens-protocol/api-bindings'; - -/** - * Follow module fragments - */ -export type { - FeeFollowModuleSettings, - ProfileFollowModuleSettings, - RevertFollowModuleSettings, - UnknownFollowModuleSettings, -} from '@lens-protocol/api-bindings'; - -/** - * Helpers - */ -export { isProfileOwnedByMe, ProfileSortCriteria } from '@lens-protocol/api-bindings'; diff --git a/packages/react-v1/src/profile/infrastructure/ActiveProfileStorage.ts b/packages/react-v1/src/profile/infrastructure/ActiveProfileStorage.ts deleted file mode 100644 index ed7eaaad79..0000000000 --- a/packages/react-v1/src/profile/infrastructure/ActiveProfileStorage.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BaseStorageSchema, IStorageProvider, Storage } from '@lens-protocol/storage'; - -import { StoredActiveProfileData } from '../adapters/ActiveProfileGateway'; - -export function createActiveProfileStorage(storageProvider: IStorageProvider, namespace: string) { - const ActiveProfileStorageDataSchema = new BaseStorageSchema( - `lens.${namespace}.activeProfile`, - StoredActiveProfileData, - ); - return Storage.createForSchema(ActiveProfileStorageDataSchema, storageProvider); -} diff --git a/packages/react-v1/src/profile/useActiveProfile.ts b/packages/react-v1/src/profile/useActiveProfile.ts deleted file mode 100644 index 3aad1db48c..0000000000 --- a/packages/react-v1/src/profile/useActiveProfile.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { ProfileOwnedByMe, SessionType, UnspecifiedError } from '@lens-protocol/api-bindings'; - -import { ReadResult } from '../helpers/reads'; -import { useCurrentSession } from '../lifecycle/useCurrentSession'; - -/** - * `useActiveProfile` is a hook that lets you retrieve the active profile - * - * **Pro-tip**: Use the profile instance returned by this hook to perform actions - * that require a ProfileOwnedByMe instances (e.g. {@link useCollect}, {@link useFollow}). - * - * @category Profiles - * @group Hooks - * - * @example - * ```tsx - * import { useActiveProfile } from '@lens-protocol/react-web'; - * - * function ActiveProfile() { - * const { data, error, loading } = useActiveProfile(); - * - * if (loading) return

Loading...

; - * - * if (error) return

Error: {error.message}

; - * - * if (data === null) return

No active profile

; - * - * return ( - *
- *

Active profile: {data.handle}

- *
- * ); - * } - * ``` - */ -export function useActiveProfile(): ReadResult { - const { data: session, error, loading: bootstrapping } = useCurrentSession(); - - if (bootstrapping) { - return { - data: undefined, - error: undefined, - loading: true, - }; - } - - if (error) { - return { - data: undefined, - error, - loading: false, - }; - } - - if (session.type !== SessionType.WithProfile) { - return { - data: null, - error: undefined, - loading: false, - }; - } - - return { - data: session.profile, - error: undefined, - loading: false, - }; -} diff --git a/packages/react-v1/src/profile/useActiveProfileSwitch.ts b/packages/react-v1/src/profile/useActiveProfileSwitch.ts deleted file mode 100644 index 8176e89c8b..0000000000 --- a/packages/react-v1/src/profile/useActiveProfileSwitch.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { ProfileId } from '@lens-protocol/domain/entities'; -import { success } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useSwitchActiveProfileController } from './adapters/useSwitchActiveProfileController'; - -export type ActiveProfileSwitchOperation = Operation; - -/** - * `useActiveProfileSwitch` is a hook that lets you switch the active profile - * - * **Pro-tip**: use this in combination with {@link useActiveProfile} and {@link useProfilesOwnedByMe} - * to create a profile switcher interface. - * - * @category Profiles - * @group Hooks - * - * @example - * Profile switcher interface - * ```tsx - * import { useActiveProfileSwitch, useActiveProfile, useProfilesOwnedByMe } from '@lens-protocol/react-web'; - * - * function ProfileSwitcher() { - * const { data: activeProfile } = useActiveProfile(); - * const { execute: switchActiveProfile, isPending } = useActiveProfileSwitch(); - * const { data: profiles, error, loading } = useProfilesOwnedByMe({ limit: 50 }); - * - * if (loading) return

Loading...

; - * - * if (error) return

Error: {error.message}

; - * - * return ( - *
- *

Active profile: {activeProfile?.handle}

- *
    - * {profiles.map((profile) => ( - *
  • - * - *
  • - * ))} - *
- *
- * ); - * } - * ``` - */ -export function useActiveProfileSwitch(): ActiveProfileSwitchOperation { - const switchActiveProfile = useSwitchActiveProfileController(); - - return useOperation(async (profileId: ProfileId) => { - await switchActiveProfile({ profileId }); - return success(); - }); -} diff --git a/packages/react-v1/src/profile/useCollectedPublications.ts b/packages/react-v1/src/profile/useCollectedPublications.ts deleted file mode 100644 index 2830fbab6a..0000000000 --- a/packages/react-v1/src/profile/useCollectedPublications.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { AnyPublication, PublicationTypes, useGetPublications } from '@lens-protocol/api-bindings'; -import { EthereumAddress } from '@lens-protocol/shared-kernel'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -type UseCollectablesArgs = PaginatedArgs< - WithObserverIdOverride<{ - walletAddress: EthereumAddress; - }> ->; - -/** - * @category Publications - * @group Hooks - */ -export function useCollectedPublications({ - walletAddress, - observerId, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, -}: UseCollectablesArgs): PaginatedReadResult { - return usePaginatedReadResult( - useGetPublications( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - walletAddress, - publicationTypes: [ - PublicationTypes.Comment, - PublicationTypes.Mirror, - PublicationTypes.Post, - ], - limit: limit, - observerId, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/profile/useCreateProfile.ts b/packages/react-v1/src/profile/useCreateProfile.ts deleted file mode 100644 index 8d76352ce7..0000000000 --- a/packages/react-v1/src/profile/useCreateProfile.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { TransactionError, TransactionKind } from '@lens-protocol/domain/entities'; -import { DuplicatedHandleError, FollowPolicyConfig } from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { failure, PromiseResult, success, Url } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useCreateProfileController } from './adapters/useCreateProfileController'; - -export type CreateProfileArgs = { - /** - * The profile handle - */ - handle: string; - - /** - * The initial follow policy - * - * @defaultValue anyone can follow - */ - followPolicy?: FollowPolicyConfig; - - /** - * The profile image URL - * - * @defaultValue no profile image - */ - profileImage?: Url; -}; - -export { DuplicatedHandleError }; - -export type CreateProfileOperation = Operation< - Profile, - BroadcastingError | DuplicatedHandleError | TransactionError, - [CreateProfileArgs] ->; - -/** - * `useCreateProfile` is a hook that lets you create a new profile - * - * The hook `execute` function resolves with a {@link Result} when the corresponding transaction is settled. - * You can use the {@link Success.isSuccess | `Result.isSuccess`} (or {@link Failure.isFailure | `Result.isFailure`}) method - * to determine the outcome of the operation. - * - * @category Profiles - * @group Hooks - * - * @example - * Simple usage - * ```tsx - * import { useCreateProfile } from '@lens-protocol/react-web'; - * - * function CreateProfile() { - * const { error, execute, isPending } = useCreateProfile(); - * - * const onClick = async () => { - * const handle = window.prompt("Enter your handle"); - * - * const result = await execute({ handle }); - * - * if (result.isSuccess()) { - * console.log("Profile created!", result.value); - * } - * }; - * - * return ( - *
- * { error &&

{error.message}

} - * - *
- * ); - * } - * ``` - * - * @example - * Programmatic error handling - * ```tsx - * import { useCreateProfile, DuplicatedHandleError } from '@lens-protocol/react-web'; - * - * function CreateProfile() { - * const { execute, isPending } = useCreateProfile(); - * - * const onClick = async () => { - * const handle = window.prompt("Enter your handle"); - * - * const result = await execute({ handle }); - * - * if (result.isSuccess()) { - * console.log("Profile created!", result.value); - * return; - * } - * - * switch (result.error.constructor) { - * case DuplicatedHandleError: - * console.log("Handle already taken"); - * - * default: - * console.log(`Could not create profile due to: ${result.error.message}`); - * } - * }; - * - * return ( - *
- * - *
- * ); - * } - * ``` - */ -export function useCreateProfile(): CreateProfileOperation { - const createProfile = useCreateProfileController(); - - return useOperation( - async ({ - handle, - }: CreateProfileArgs): PromiseResult< - Profile, - BroadcastingError | DuplicatedHandleError | TransactionError - > => { - const broadcasted = await createProfile({ - handle, - kind: TransactionKind.CREATE_PROFILE, - }); - - if (broadcasted.isFailure()) { - return failure(broadcasted.error); - } - - const result = await broadcasted.value.waitForCompletion(); - - if (result.isFailure()) { - return failure(result.error); - } - - return success(result.value); - }, - ); -} diff --git a/packages/react-v1/src/profile/useExploreProfiles.ts b/packages/react-v1/src/profile/useExploreProfiles.ts deleted file mode 100644 index f70f526e21..0000000000 --- a/packages/react-v1/src/profile/useExploreProfiles.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - Profile, - ProfileSortCriteria, - useExploreProfiles as useUnderlyingQuery, -} from '@lens-protocol/api-bindings'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedReadResult, PaginatedArgs, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseExploreProfilesArgs = PaginatedArgs< - WithObserverIdOverride<{ - sortCriteria?: ProfileSortCriteria; - }> ->; - -/** - * `useExploreProfiles` is a paginated hook that lets you discover new profiles based on a defined criteria - * - * @category Discovery - * @group Hooks - * @param args - {@link UseExploreProfilesArgs} - * - * @example - * - * ```tsx - * import { useExploreProfiles } from '@lens-protocol/react-web'; - * - * function ExploreProfiles() { - * const { data, error, loading } = useExploreProfiles({ : ProfileSortCriteria.MostFollowers }); - * - * if (loading) return

Loading...

; - * - * if (error) return

Error: {error.message}

; - * - * return ( - *
    - * {data.map((profile) => ( - *
  • {profile.handle}
  • - * ))} - *
- * ); - * } - * ``` - */ -export function useExploreProfiles({ - observerId, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - sortCriteria = ProfileSortCriteria.MostComments, -}: UseExploreProfilesArgs = {}): PaginatedReadResult { - return usePaginatedReadResult( - useUnderlyingQuery( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ limit, observerId, sortCriteria }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/profile/useMutualFollowers.ts b/packages/react-v1/src/profile/useMutualFollowers.ts deleted file mode 100644 index 1227c89a2c..0000000000 --- a/packages/react-v1/src/profile/useMutualFollowers.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Profile, useMutualFollowersProfiles } from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; - -import { - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseMutualFollowersArgs = PaginatedArgs<{ - observerId: ProfileId; - viewingProfileId: ProfileId; -}>; - -/** - * @category Profiles - * @group Hooks - */ -export function useMutualFollowers({ - observerId, - viewingProfileId, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, -}: UseMutualFollowersArgs): PaginatedReadResult { - return usePaginatedReadResult( - useMutualFollowersProfiles( - useLensApolloClient({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ limit, observerId, viewingProfileId }), - ), - }), - ), - ); -} diff --git a/packages/react-v1/src/profile/useProfile.ts b/packages/react-v1/src/profile/useProfile.ts deleted file mode 100644 index 7e6f80b838..0000000000 --- a/packages/react-v1/src/profile/useProfile.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Profile, UnspecifiedError, useGetProfile } from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { invariant, Prettify, XOR } from '@lens-protocol/shared-kernel'; - -import { NotFoundError } from '../NotFoundError'; -import { - Skippable, - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { ReadResult, useReadResult } from '../helpers/reads'; - -export type UseProfileByIdArgs = { - profileId: ProfileId; -}; - -export type UseProfileByHandleArgs = { - handle: string; -}; - -/** - * {@link useProfile} hook arguments - */ -export type UseProfileArgs = Prettify< - Skippable>> ->; - -/** - * Get a profile by either a handle or profile Id. - * - * @category Profiles - * @group Hooks - * - * @param args - {@link UseProfileArgs} - */ -export function useProfile({ - observerId, - skip, - ...request -}: UseProfileArgs): ReadResult { - invariant( - request.profileId === undefined || request.handle === undefined, - "Only one of 'id' or 'handle' should be provided to 'useProfile' hook", - ); - - const { data, error, loading } = useReadResult( - useGetProfile( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - request, - observerId, - }), - ), - fetchPolicy: 'cache-and-network', - nextFetchPolicy: 'cache-first', - skip, - }), - ), - ), - ); - - if (loading) { - return { - data: undefined, - error: undefined, - loading: true, - }; - } - - if (error) { - return { - data: undefined, - error, - loading: false, - }; - } - - if (data === null) { - return { - data: undefined, - error: new NotFoundError(`Profile for ${JSON.stringify(request)}`), - loading: false, - }; - } - - return { - data, - error: undefined, - loading: false, - }; -} diff --git a/packages/react-v1/src/profile/useProfileFollowers.ts b/packages/react-v1/src/profile/useProfileFollowers.ts deleted file mode 100644 index 16db19ea0f..0000000000 --- a/packages/react-v1/src/profile/useProfileFollowers.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Follower, useProfileFollowers as useUnderlyingQuery } from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseProfileFollowersArgs = PaginatedArgs< - WithObserverIdOverride<{ - profileId: ProfileId; - }> ->; - -/** - * @category Profiles - * @group Hooks - */ -export function useProfileFollowers({ - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - observerId, - profileId, -}: UseProfileFollowersArgs): PaginatedReadResult { - return usePaginatedReadResult( - useUnderlyingQuery( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ profileId, limit, observerId }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/profile/useProfileFollowing.ts b/packages/react-v1/src/profile/useProfileFollowing.ts deleted file mode 100644 index f0ceedb8bc..0000000000 --- a/packages/react-v1/src/profile/useProfileFollowing.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Following, useProfileFollowing as useUnderlyingQuery } from '@lens-protocol/api-bindings'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseProfileFollowingArgs = PaginatedArgs< - WithObserverIdOverride<{ - walletAddress: string; - }> ->; - -/** - * @category Profiles - * @group Hooks - */ -export function useProfileFollowing({ - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - observerId, - walletAddress, -}: UseProfileFollowingArgs): PaginatedReadResult { - return usePaginatedReadResult( - useUnderlyingQuery( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - walletAddress, - limit, - observerId, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/profile/useProfileGuardian.ts b/packages/react-v1/src/profile/useProfileGuardian.ts deleted file mode 100644 index e237a14eff..0000000000 --- a/packages/react-v1/src/profile/useProfileGuardian.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { - ProfileGuardianResult, - useProfileGuardian as useUnderlyingQuery, -} from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; - -import { useLensApolloClient } from '../helpers/arguments'; -import { ReadResult, useReadResult } from '../helpers/reads'; - -export type UseProfileGuardianArgs = { - profileId: ProfileId; -}; - -export type { ProfileGuardianResult }; - -/** - * `useProfileGuardian` is a hook that lets you read the Profile Guardian settings of a given Profile - * - * You MUST be authenticated via {@link useWalletLogin} to use this hook. - * - * @experimental This hook is experimental and may change in future releases - * - * @category Profiles - * @group Hooks - * - * @param args - {@link UseProfileGuardianArgs} - * - * @example - * ```tsx - * import { ProfileId, useProfileGuardian } from '@lens-protocol/react-web'; - * - * function ProfileGuardianSettings({ profileId }: { profileId: ProfileId }) { - * const { data, loading, error } = useProfileGuardian({ profileId }); - * - * if (loading) { - * return

Loading...

; - * } - * - * if (error) { - * return

Error: {error.message}

; - * } - * - * return ( - * <> - *

- * Protected: {data.protected ? 'YES' : 'NO'} - *

- *

- * Cooldown Period ends on: {data.disablingProtectionTimestamp} - *

- * - * ); - * } - * ``` - */ -export function useProfileGuardian({ - profileId, -}: UseProfileGuardianArgs): ReadResult { - return useReadResult( - useUnderlyingQuery( - useLensApolloClient({ - variables: { - request: { - profileId, - }, - }, - }), - ), - ); -} diff --git a/packages/react-v1/src/profile/useProfiles.ts b/packages/react-v1/src/profile/useProfiles.ts deleted file mode 100644 index 78f090b210..0000000000 --- a/packages/react-v1/src/profile/useProfiles.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Profile, useGetAllProfiles } from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { invariant, Prettify, XOR } from '@lens-protocol/shared-kernel'; - -import { - Skippable, - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseProfilesByIdsArgs = { - profileIds: ProfileId[]; -}; - -export type UseProfilesByHandlesArgs = { - handles: string[]; -}; - -/** - * {@link useProfiles} hook arguments - */ -export type UseProfilesArgs = Prettify< - Skippable< - PaginatedArgs>> - > ->; - -/** - * Get a paginated list of profiles by either their handles or their profile Ids. - * - * @category Profiles - * @group Hooks - * - * @param args - {@link UseProfilesArgs} - * - * @example - * Get profiles by handles - * ```ts - * const { data, error, loading } = useProfiles({ handles: ['handle1', 'handle2'] }); - * - * if (loading) { - * return

Loading...

; - * } - * - * if (error) { - * return

Error: {error.message}

; - * } - * - * return ( - *
- * {data.map((profile) => ( - *
- *

Handle: {profile.handle}

- *
- * ))} - *
- * ); - * ``` - * - * @example - * Get profiles by profile Ids - * ```ts - * const { data, error, loading } = useProfiles({ profileIds: ['profileId1', 'profileId2'] }); - * - * if (loading) { - * return

Loading...

; - * } - * - * if (error) { - * return

Error: {error.message}

; - * } - * - * return ( - *
- * {data.map((profile) => ( - *
- *

Handle: {profile.handle}

- *
- * ))} - *
- * ); - * ``` - */ -export function useProfiles({ - handles: byHandles, - profileIds: byProfileIds, - observerId, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - skip, -}: UseProfilesArgs): PaginatedReadResult { - invariant( - byHandles === undefined || byProfileIds === undefined, - `Cannot provide both 'handles' and 'profileIds' to '${useProfiles.name}' hook`, - ); - - return usePaginatedReadResult( - useGetAllProfiles( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ byHandles, byProfileIds, limit, observerId }), - ), - skip, - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/profile/useProfilesOwnedBy.ts b/packages/react-v1/src/profile/useProfilesOwnedBy.ts deleted file mode 100644 index a769769268..0000000000 --- a/packages/react-v1/src/profile/useProfilesOwnedBy.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Profile, useGetAllProfiles } from '@lens-protocol/api-bindings'; -import { EthereumAddress } from '@lens-protocol/shared-kernel'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseProfilesOwnedByArgs = PaginatedArgs< - WithObserverIdOverride<{ - address: EthereumAddress; - }> ->; - -/** - * @category Profiles - * @group Hooks - */ -export function useProfilesOwnedBy({ - address, - observerId, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, -}: UseProfilesOwnedByArgs): PaginatedReadResult { - return usePaginatedReadResult( - useGetAllProfiles( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - byOwnerAddresses: [address], - observerId, - limit, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/profile/useProfilesOwnedByMe.ts b/packages/react-v1/src/profile/useProfilesOwnedByMe.ts deleted file mode 100644 index 1214fb3ed3..0000000000 --- a/packages/react-v1/src/profile/useProfilesOwnedByMe.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ProfileOwnedByMe, useGetAllProfiles, useSessionVar } from '@lens-protocol/api-bindings'; -import { constants } from 'ethers'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { useRecentProfiles } from '../transactions/adapters/responders/CreateProfileResponder'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseProfilesOwnedByMeArgs = PaginatedArgs; - -/** - * `useProfilesOwnedByMe` is a paginated hook that returns all profiles owned by the logged in wallet. - * - * @category Profiles - * @group Hooks - * @param args - {@link UseFeedArgs} - * - * @example - * ```tsx - * import { useProfilesOwnedByMe } from '@lens-protocol/react-web'; - * - * function MyProfiles() { - * const { data: profiles, error, loading } = useProfilesOwnedByMe(); - * - * if (loading) return
Loading...
; - * - * if (error) return
Error: {error.message}
; - * - * return ( - *
    - * {profiles.map((profile) => ( - *
  • {profile.name}
  • - * ))} - *
- * ); - * } - * ``` - */ -export function useProfilesOwnedByMe({ - observerId, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, -}: UseProfilesOwnedByMeArgs = {}): PaginatedReadResult { - const session = useSessionVar(); - const recentProfiles = useRecentProfiles(); - - const result = usePaginatedReadResult( - useGetAllProfiles( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - byOwnerAddresses: [ - session?.isAuthenticated() ? session.wallet.address : constants.AddressZero, - ], - observerId, - limit, - }), - ), - skip: session === null, - }), - ), - ), - ); - - return { - ...result, - data: result.data ? [...result.data, ...recentProfiles] : result.data, - } as PaginatedReadResult; -} diff --git a/packages/react-v1/src/profile/useProfilesToFollow.ts b/packages/react-v1/src/profile/useProfilesToFollow.ts deleted file mode 100644 index 63e030aafa..0000000000 --- a/packages/react-v1/src/profile/useProfilesToFollow.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { useProfilesToFollow as useUnderlyingQuery } from '@lens-protocol/api-bindings'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { useReadResult } from '../helpers/reads'; - -export type UseProfilesToFollowArgs = WithObserverIdOverride; - -/** - * `useProfilesToFollow` is an hook that returns a short-list of profiles that you may want to follow. - * - * In case the user is logged-in, the list is personalized for them using ML algorithms. - * - * @category Profiles - * @group Hooks - * @param args - {@link UseProfilesToFollowArgs} - * - * @example - * - * ```tsx - * import { useProfilesToFollow } from '@lens-protocol/react-web'; - * - * function ProfilesToFollow() { - * const { data, error, loading } = useProfilesToFollow(); - * - * if (loading) return

Loading...

; - * - * if (error) return

Error: {error.message}

; - * - * return ( - *
    - * {data.map((profile) => ( - *
  • {profile.handle}
  • - * ))} - *
- * ); - * } - * ``` - */ -export function useProfilesToFollow({ observerId }: UseProfilesToFollowArgs = {}) { - return useReadResult( - useUnderlyingQuery( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - observerId, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/profile/useSearchProfiles.ts b/packages/react-v1/src/profile/useSearchProfiles.ts deleted file mode 100644 index 5771dca955..0000000000 --- a/packages/react-v1/src/profile/useSearchProfiles.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Profile, useSearchProfiles as useUnderlyingQuery } from '@lens-protocol/api-bindings'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseSearchProfilesArgs = PaginatedArgs< - WithObserverIdOverride<{ - /** - * Search query - */ - query: string; - }> ->; - -/** - * `useSearchProfiles` is a paginated hook that lets you search for profiles based on a defined criteria - * - * @category Discovery - * @group Hooks - * @param args - {@link UseSearchProfilesArgs} - * - * @example - * ```tsx - * import { useSearchProfiles } from '@lens-protocol/react-web'; - * - * function SearchProfiles() { - * const { data, error, loading } = useSearchProfiles({ query: 'foo' }); - * - * if (loading) return

Loading...

; - * - * if (error) return

Error: {error.message}

; - * - * return ( - *
    - * {data.map((profile) => ( - *
  • {profile.handle}
  • - * ))} - *
- * ); - * } - * ``` - */ -export function useSearchProfiles({ - query, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - observerId, -}: UseSearchProfilesArgs): PaginatedReadResult { - return usePaginatedReadResult( - useUnderlyingQuery( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - query, - limit, - observerId, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/publication/__tests__/filters.spec.ts b/packages/react-v1/src/publication/__tests__/filters.spec.ts deleted file mode 100644 index 915ad112fc..0000000000 --- a/packages/react-v1/src/publication/__tests__/filters.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { PublicationMetadataFilters } from '@lens-protocol/api-bindings'; - -import { createPublicationMetadataFilters } from '../filters'; - -describe(`Given ${createPublicationMetadataFilters.name}`, () => { - describe('when supplied with allowed filters', () => { - it('should return the correct filter for the api', () => { - const expectedFilters: PublicationMetadataFilters = { - tags: { - oneOf: ['sports'], - }, - }; - - expect( - createPublicationMetadataFilters({ - restrictPublicationTagsTo: { - oneOf: ['sports'], - }, - }), - ).toEqual(expectedFilters); - - expect(createPublicationMetadataFilters(undefined)).toBeUndefined(); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useBookmarkToggle.spec.ts b/packages/react-v1/src/publication/__tests__/useBookmarkToggle.spec.ts deleted file mode 100644 index 4130e3bd1a..0000000000 --- a/packages/react-v1/src/publication/__tests__/useBookmarkToggle.spec.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { DocumentNode } from '@apollo/client'; -import { - AnyPublication, - FragmentMirror, - FragmentPost, - ProfileOwnedByMe, - isMirrorPublication, -} from '@lens-protocol/api-bindings'; -import { - mockAddToMyBookmarksResponse, - mockLensApolloClient, - mockMirrorFragment, - mockPostFragment, - mockProfileOwnedByMeFragment, - mockRemoveFromMyBookmarksResponse, - mockSources, -} from '@lens-protocol/api-bindings/mocks'; -import { RenderHookResult, act, waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { defaultMediaTransformsConfig } from '../../mediaTransforms'; -import { PublicationCacheManager } from '../../transactions/adapters/PublicationCacheManager'; -import { useBookmarkToggle } from '../useBookmarkToggle'; - -function setupTestScenario({ - fragment, - profile, - publication, -}: { - fragment: DocumentNode; - profile: ProfileOwnedByMe; - publication: AnyPublication; -}) { - const publicationId = isMirrorPublication(publication) ? publication.mirrorOf.id : publication.id; - - const apolloClient = mockLensApolloClient([ - mockAddToMyBookmarksResponse({ - request: { publicationId, profileId: profile.id }, - }), - mockRemoveFromMyBookmarksResponse({ - request: { publicationId, profileId: profile.id }, - }), - ]); - - apolloClient.cache.writeFragment({ - id: apolloClient.cache.identify(publication), - fragment, - fragmentName: publication.__typename, - data: publication, - }); - - const cacheManager = new PublicationCacheManager( - apolloClient, - mockSources(), - defaultMediaTransformsConfig, - ); - - return { - renderHook( - callback: (props: TProps) => TResult, - ): RenderHookResult { - return renderHookWithMocks(callback, { - mocks: { - apolloClient: apolloClient, - publicationCacheManager: cacheManager, - }, - }); - }, - - get updatedPublicationFragment() { - return apolloClient.cache.readFragment({ - id: apolloClient.cache.identify(publication), - fragment, - fragmentName: publication.__typename, - }); - }, - }; -} - -describe(`Given the ${useBookmarkToggle.name} hook`, () => { - describe('when invoking the hook callback', () => { - const profile = mockProfileOwnedByMeFragment(); - - it.each([ - { - initial: true, - expected: false, - }, - { - initial: false, - expected: true, - }, - ])( - 'should toggle the `publication.bookmarked` from "$initial" to "$expected"', - async ({ initial, expected }) => { - const publication = mockPostFragment({ - bookmarked: initial, - observedBy: profile.id, - }); - const scenario = setupTestScenario({ - fragment: FragmentPost, - profile, - publication, - }); - - const { result } = scenario.renderHook(() => useBookmarkToggle({ publication, profile })); - - act(() => { - void result.current.execute(); - }); - - expect(result.current).toMatchObject({ - isPending: true, - }); - - await waitFor(() => expect(result.current.isPending).toBe(false)); - expect(scenario.updatedPublicationFragment).toMatchObject({ - bookmarked: expected, - }); - }, - ); - - it('should update the `publication.mirrorOf.bookmarked` in case the `publication` is a Mirror', async () => { - const publication = mockMirrorFragment({ - mirrorOf: mockPostFragment({ - bookmarked: false, - observedBy: profile.id, - }), - }); - const scenario = setupTestScenario({ fragment: FragmentMirror, profile, publication }); - - const { result } = scenario.renderHook(() => useBookmarkToggle({ publication, profile })); - - act(() => { - void result.current.execute(); - }); - - await waitFor(() => expect(result.current.isPending).toBe(false)); - expect(scenario.updatedPublicationFragment).toMatchObject({ - mirrorOf: { - bookmarked: true, - }, - }); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useEncryptedPublication.spec.ts b/packages/react-v1/src/publication/__tests__/useEncryptedPublication.spec.ts deleted file mode 100644 index 19a34ecad9..0000000000 --- a/packages/react-v1/src/publication/__tests__/useEncryptedPublication.spec.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { - mockEncryptedFieldsOutputFragment, - mockEncryptionParamsOutputFragment, - mockEoaOwnershipAccessCondition, - mockMetadataOutputFragment, - mockPostFragment, - mockProfileFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { webCryptoProvider } from '@lens-protocol/gated-content/web'; -import { InMemoryStorageProvider } from '@lens-protocol/storage'; -import { act, waitFor } from '@testing-library/react'; -import { Wallet } from 'ethers'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { staging } from '../../environments'; -import { profileId } from '../../utils'; -import { useActiveWalletSigner } from '../../wallet'; -import { useEncryptedPublication } from '../useEncryptedPublication'; - -jest.mock('../../wallet/useActiveWalletSigner'); - -describe(`Given the "${useEncryptedPublication.name}" hook`, () => { - describe('when the provided publication is NOT gated', () => { - const post = mockPostFragment({ - isGated: false, - }); - - beforeAll(() => { - jest - .mocked(useActiveWalletSigner) - .mockReturnValue({ loading: false, data: Wallet.createRandom() }); - }); - - it('should just return publication with no loading state', async () => { - const { result } = renderHookWithMocks(() => - useEncryptedPublication({ - encryption: { - authentication: { - domain: 'localhost', - uri: 'https://localhost/login', - }, - provider: webCryptoProvider(), - }, - publication: post, - }), - ); - - expect(result.current.data).toEqual(post); - }); - }); - - describe('when the provided publication is gated', () => { - // This test has a lot of hardcoded values. It's relatively safe - // to assume that the underlying data is immutable, even though on Mumbai. - const signer = new Wallet('0xcc268eda1086b6c71f811801bd4a3f96e3c95ddde2d44b4ebb0554e800d353d2'); // address: 0x6E7c8Ea196E54Ca38C9A074374D6e39a84727536 - const profile = mockProfileFragment({ - id: profileId('0xa6'), - }); - - const post = mockPostFragment({ - isGated: true, - profile, - metadata: mockMetadataOutputFragment({ - encryptionParams: mockEncryptionParamsOutputFragment({ - ownerId: profile.id, - others: [ - mockEoaOwnershipAccessCondition({ - address: signer.address, - }), - ], - encryptionKey: - 'e689da704a53fe9c56698e11be4a4f9f04a1bd36c5149f894df98fc2637df83b8bbdf495d8a47b882c17e900b688f110fc2762772e1437f165b6c416e990bde072842b46f4376e2dd3051c228870a877dd99800924a364be22320340441b6d8863ebab2892d4102a14c060b222c61c8b7f47c670232670505389fd4a983205c000000000000000207171294fc14c9e6996f89eaac7bf36d30a3abb415595fd9e4d329eee6490349a134b5291fe25f167f3cded81ae8231b4', - encryptedFields: mockEncryptedFieldsOutputFragment({ - content: - '_ef7pOheqo9WZyZglm5eaqPGrJmNr_eZmeoVIIQGZUXRRpoZ7gcL8PJQBTsOMweZFpIqdTFk9ug2X9Cyw07yQrZuQ4d-BmTJ3k19mPb-YSistE4GiRKC74mTyjas882KKc8Og9nML1WwlJdCesFfxOTeOucyWKspGozIkJoG99cMjD_keMLGN6NdAi9A6pj9_beRaN5GjL8AzU0_0VqBJjM_j7dn4OxRqfoAzt9d2LTX7t3UUAwuNG5W_oJNuc_44Z8ojU0DNzsiHzrLsV_yCOFJO9X_L3I-GDCDLmR-dzJGwwNbss0FjfQvuMc8RzOSkeoEc1mGRW4wz20pGFY8VNJoqA1a--ILF_kVUevSi4HPdoubuVPkPvBecWBKM0VWw42zp63qY5YgnjIROk7AQgGxDNaLtBeIFo92syiOEZ3FAyHpCCcrxQbJ89tdSS1mNKe2xf0E4JT5j4k48NSL2Neq-3XLiRGcbUAHYlOpflc=', - }), - }), - }), - }); - - beforeAll(() => { - jest.mocked(useActiveWalletSigner).mockReturnValue({ loading: false, data: signer }); - }); - - // This test is disabled due to the fact the Lit SDK runs in a browser environment because of jsdom - // we cannot switch jest environment to node because react testing library relies on a DOM to be present. - // Ideally a future version od the Lit Protocol SDK will make a better distinction between the browser and node - // and we could attempt to run this test so that Lit can take advantage of the node environment. - xit('should allow to decrypt the metadata if the user matches the access condition criteria', async () => { - const { result } = renderHookWithMocks( - () => - useEncryptedPublication({ - encryption: { - authentication: { - domain: 'localhost', - uri: 'https://localhost/login', - }, - provider: webCryptoProvider(), - }, - publication: post, - }), - { - mocks: { - environment: staging, - storageProvider: new InMemoryStorageProvider(), - }, - }, - ); - - await act(async () => { - result.current.decrypt(); - }); - - await waitFor(() => expect(result.current.isPending).toBe(false), { timeout: 15_000 }); - - expect(result.current.data.metadata.content).toEqual('[insert decrypted content here]'); - }, 15_000); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useExplorePublications.spec.ts b/packages/react-v1/src/publication/__tests__/useExplorePublications.spec.ts deleted file mode 100644 index 8c472f65d2..0000000000 --- a/packages/react-v1/src/publication/__tests__/useExplorePublications.spec.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { - AnyPublication, - PublicationSortCriteria, - PublicationTypes, -} from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockPostFragment, - mockExplorePublicationsResponse, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../../utils'; -import { useExplorePublications, UseExplorePublicationsArgs } from '../useExplorePublications'; - -function setupTestScenario({ - expectedObserverId, - result, - ...args -}: UseExplorePublicationsArgs & { - expectedObserverId?: ProfileId; - result: AnyPublication[]; -}) { - const sources = mockSources(); - - return renderHookWithMocks(() => useExplorePublications(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - - apolloClient: mockLensApolloClient([ - mockExplorePublicationsResponse({ - variables: { - limit: DEFAULT_PAGINATED_QUERY_LIMIT, - sortCriteria: PublicationSortCriteria.Latest, - ...args, - sources, - observerId: expectedObserverId ?? null, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - items: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useExplorePublications.name} hook`, () => { - const publications = [mockPostFragment()]; - const expectations = publications.map(({ __typename, id }) => ({ __typename, id })); - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe('when invoked', () => { - it('should return publications that match the explore with default parameters', async () => { - const { result } = setupTestScenario({ result: publications }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(publications); - }); - - it('should return publications that match the explore with custom parameters', async () => { - const customParams = { - sortCriteria: PublicationSortCriteria.TopCollected, - limit: 20, - publicationTypes: [PublicationTypes.Comment, PublicationTypes.Post], - }; - const { result } = setupTestScenario({ ...customParams, result: publications }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - result: publications, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - observerId, - result: publications, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useMyBookmarks.spec.ts b/packages/react-v1/src/publication/__tests__/useMyBookmarks.spec.ts deleted file mode 100644 index 535d87fe2e..0000000000 --- a/packages/react-v1/src/publication/__tests__/useMyBookmarks.spec.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { SafeApolloClient } from '@lens-protocol/api-bindings'; -import { - mockGetProfileBookmarksResponse, - mockLensApolloClient, - mockPostFragment, - mockProfileOwnedByMeFragment, - mockSources, - simulateAuthenticatedProfile, - simulateAuthenticatedWallet, -} from '@lens-protocol/api-bindings/mocks'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { RenderHookResult, waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { useMyBookmarks } from '../useMyBookmarks'; - -const sources = mockSources(); - -function setupTestScenario({ client }: { client: SafeApolloClient }) { - return { - renderHook( - callback: (props: TProps) => TResult, - ): RenderHookResult { - return renderHookWithMocks(callback, { - mocks: { - apolloClient: client, - sources, - mediaTransforms: defaultMediaTransformsConfig, - }, - }); - }, - }; -} - -describe(`Given the ${useMyBookmarks.name} hook`, () => { - const profile = mockProfileOwnedByMeFragment(); - const publications = [mockPostFragment()]; - const expectations = publications.map(({ __typename, id }) => ({ __typename, id })); - - beforeAll(() => { - simulateAuthenticatedWallet(); - }); - - describe('when a profile is provided', () => { - const client = mockLensApolloClient([ - mockGetProfileBookmarksResponse({ - variables: { - profileId: profile.id, - observerId: null, - sources, - limit: 10, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publications, - }), - ]); - - it('should settle with the bookmarked publications', async () => { - const { renderHook } = setupTestScenario({ client }); - - const { result } = renderHook(() => useMyBookmarks({ profile })); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when a session with an Active Profile is set', () => { - const activeProfile = mockProfile(); - const client = mockLensApolloClient([ - mockGetProfileBookmarksResponse({ - variables: { - profileId: profile.id, - observerId: activeProfile.id, - sources, - limit: 10, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publications, - }), - ]); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - afterAll(() => { - simulateAuthenticatedWallet(); - }); - - it('should use the Active Profile as the queried publication observer', async () => { - const { renderHook } = setupTestScenario({ client }); - - const { result } = renderHook(() => useMyBookmarks({ profile })); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when an "observerId" is provided', () => { - const observerId = mockProfileId(); - const client = mockLensApolloClient([ - mockGetProfileBookmarksResponse({ - variables: { - profileId: profile.id, - observerId, - sources, - limit: 10, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publications, - }), - ]); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const { renderHook } = setupTestScenario({ client }); - - const { result } = renderHook(() => useMyBookmarks({ profile, observerId })); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useNotInterested.spec.ts b/packages/react-v1/src/publication/__tests__/useNotInterested.spec.ts deleted file mode 100644 index aaff216524..0000000000 --- a/packages/react-v1/src/publication/__tests__/useNotInterested.spec.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { DocumentNode } from '@apollo/client'; -import { - AnyPublication, - FragmentMirror, - FragmentPost, - ProfileOwnedByMe, - isMirrorPublication, -} from '@lens-protocol/api-bindings'; -import { - mockAddNotInterestedResponse, - mockLensApolloClient, - mockMirrorFragment, - mockPostFragment, - mockProfileOwnedByMeFragment, - mockRemoveNotInterestedResponse, - mockSources, -} from '@lens-protocol/api-bindings/mocks'; -import { RenderHookResult, act, waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { defaultMediaTransformsConfig } from '../../mediaTransforms'; -import { PublicationCacheManager } from '../../transactions/adapters/PublicationCacheManager'; -import { useNotInterested } from '../useNotInterested'; - -function setupTestScenario({ - fragment, - profile, - publication, -}: { - fragment: DocumentNode; - profile: ProfileOwnedByMe; - publication: AnyPublication; -}) { - const publicationId = isMirrorPublication(publication) ? publication.mirrorOf.id : publication.id; - - const apolloClient = mockLensApolloClient([ - mockAddNotInterestedResponse({ - request: { publicationId, profileId: profile.id }, - }), - mockRemoveNotInterestedResponse({ - request: { publicationId, profileId: profile.id }, - }), - ]); - - apolloClient.cache.writeFragment({ - id: apolloClient.cache.identify(publication), - fragment, - fragmentName: publication.__typename, - data: publication, - }); - - const cacheManager = new PublicationCacheManager( - apolloClient, - mockSources(), - defaultMediaTransformsConfig, - ); - - return { - renderHook( - callback: (props: TProps) => TResult, - ): RenderHookResult { - return renderHookWithMocks(callback, { - mocks: { - apolloClient: apolloClient, - publicationCacheManager: cacheManager, - }, - }); - }, - - get updatedPublicationFragment() { - return apolloClient.cache.readFragment({ - id: apolloClient.cache.identify(publication), - fragment, - fragmentName: publication.__typename, - }); - }, - }; -} - -describe(`Given the ${useNotInterested.name} hook`, () => { - describe('when invoking the hook callback', () => { - const profile = mockProfileOwnedByMeFragment(); - - it.each([ - { - initial: true, - expected: false, - }, - { - initial: false, - expected: true, - }, - ])( - 'should toggle the `publication.notInterested` from "$initial" to "$expected"', - async ({ initial, expected }) => { - const publication = mockPostFragment({ - notInterested: initial, - observedBy: profile.id, - }); - const scenario = setupTestScenario({ - fragment: FragmentPost, - profile, - publication, - }); - - const { result } = scenario.renderHook(() => useNotInterested({ publication, profile })); - - act(() => { - void result.current.execute(); - }); - - expect(result.current).toMatchObject({ - isPending: true, - }); - - await waitFor(() => expect(result.current.isPending).toBe(false)); - expect(scenario.updatedPublicationFragment).toMatchObject({ - notInterested: expected, - }); - }, - ); - - it('should update the `publication.mirrorOf.notInterested` in case the `publication` is a Mirror', async () => { - const publication = mockMirrorFragment({ - mirrorOf: mockPostFragment({ - notInterested: false, - observedBy: profile.id, - }), - }); - const scenario = setupTestScenario({ fragment: FragmentMirror, profile, publication }); - - const { result } = scenario.renderHook(() => useNotInterested({ publication, profile })); - - act(() => { - void result.current.execute(); - }); - - await waitFor(() => expect(result.current.isPending).toBe(false)); - expect(scenario.updatedPublicationFragment).toMatchObject({ - mirrorOf: { - notInterested: true, - }, - }); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useProfilePublicationsForSale.spec.ts b/packages/react-v1/src/publication/__tests__/useProfilePublicationsForSale.spec.ts deleted file mode 100644 index 82a2598ea7..0000000000 --- a/packages/react-v1/src/publication/__tests__/useProfilePublicationsForSale.spec.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { ContentPublication } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockPostFragment, - mockProfilePublicationsForSaleResponse, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { - useProfilePublicationsForSale, - UseProfilePublicationsForSaleArgs, -} from '../useProfilePublicationsForSale'; - -function setupTestScenario({ - expectedObserverId, - result, - ...args -}: UseProfilePublicationsForSaleArgs & { - expectedObserverId?: ProfileId; - result: ContentPublication[]; -}) { - const sources = mockSources(); - - return renderHookWithMocks(() => useProfilePublicationsForSale(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockProfilePublicationsForSaleResponse({ - variables: { - ...args, - limit: 10, - sources, - observerId: expectedObserverId ?? null, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - items: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useProfilePublicationsForSale.name} hook`, () => { - const profileId = mockProfileId(); - const publications = [mockPostFragment()]; - const expectations = publications.map(({ __typename, id }) => ({ __typename, id })); - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe('when the query returns data successfully', () => { - it('should return publications', async () => { - const { result } = setupTestScenario({ profileId, result: publications }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - profileId, - result: publications, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - profileId, - observerId, - result: publications, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/usePublication.spec.ts b/packages/react-v1/src/publication/__tests__/usePublication.spec.ts deleted file mode 100644 index 2486481819..0000000000 --- a/packages/react-v1/src/publication/__tests__/usePublication.spec.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { - mockLensApolloClient, - mockPostFragment, - mockSources, - mockGetPublicationResponse, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { RenderHookResult, waitFor } from '@testing-library/react'; - -import { NotFoundError } from '../../NotFoundError'; -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { usePublication } from '../usePublication'; - -const sources = mockSources(); - -function setupTestScenario(mocks: MockedResponse[]) { - const client = mockLensApolloClient(mocks); - - return { - renderHook( - callback: (props: TProps) => TResult, - ): RenderHookResult { - return renderHookWithMocks(callback, { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: client, - }, - }); - }, - }; -} - -describe(`Given the ${usePublication.name} hook`, () => { - const publication = mockPostFragment(); - const expectations = { __typename: 'Post', id: publication.id }; - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe('when the queried publication exists', () => { - const { renderHook } = setupTestScenario([ - mockGetPublicationResponse({ - variables: { - request: { - publicationId: publication.id, - }, - sources, - observerId: null, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publication, - }), - ]); - - it('should settle with the publication data', async () => { - const { result } = renderHook(() => usePublication({ publicationId: publication.id })); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when a session with an Active Profile is set', () => { - const activeProfile = mockProfile(); - const { renderHook } = setupTestScenario([ - mockGetPublicationResponse({ - variables: { - request: { - publicationId: publication.id, - }, - sources, - observerId: activeProfile.id, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publication, - }), - ]); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - afterAll(() => { - simulateNotAuthenticated(); - }); - - it('should use the Active Profile as the queried publication observer', async () => { - const { result } = renderHook(() => usePublication({ publicationId: publication.id })); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when an "observerId" is provided', () => { - const observerId = mockProfileId(); - const { renderHook } = setupTestScenario([ - mockGetPublicationResponse({ - variables: { - request: { - publicationId: publication.id, - }, - sources, - observerId, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publication, - }), - ]); - - it('should use it as the queried publication observer', async () => { - const { result } = renderHook(() => - usePublication({ - publicationId: publication.id, - observerId, - }), - ); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe(`when re-rendered`, () => { - const { renderHook } = setupTestScenario([ - mockGetPublicationResponse({ - variables: { - request: { - publicationId: publication.id, - }, - sources, - observerId: null, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publication: mockPostFragment({ id: publication.id }), - }), - mockGetPublicationResponse({ - variables: { - request: { - publicationId: publication.id, - }, - sources, - observerId: null, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publication, - }), - ]); - - it(`should return cached data and then update it with fresh data from the API`, async () => { - const first = renderHook(() => usePublication({ publicationId: publication.id })); - await waitFor(() => expect(first.result.current.loading).toBeFalsy()); - - const second = renderHook(() => usePublication({ publicationId: publication.id })); - - expect(second.result.current).toMatchObject({ - data: expectations, - loading: false, - }); - await waitFor(() => - expect(first.result.current.data).toMatchObject({ - stats: publication.stats, - }), - ); - }); - }); - - describe('when the queried publication does not exist', () => { - const { renderHook } = setupTestScenario([ - mockGetPublicationResponse({ - variables: { - request: { - publicationId: publication.id, - }, - sources, - observerId: null, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publication: null, - }), - ]); - - it(`should settle with a ${NotFoundError.name} state`, async () => { - const { result } = renderHook(() => usePublication({ publicationId: publication.id })); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.error).toBeInstanceOf(NotFoundError); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/usePublications.spec.ts b/packages/react-v1/src/publication/__tests__/usePublications.spec.ts deleted file mode 100644 index 99547602f0..0000000000 --- a/packages/react-v1/src/publication/__tests__/usePublications.spec.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { - mockLensApolloClient, - mockPostFragment, - mockGetPublicationsResponse, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, - mockPaginatedResultInfo, - mockCursor, -} from '@lens-protocol/api-bindings/mocks'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { RenderHookResult, waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { usePublications } from '../usePublications'; - -const sources = mockSources(); - -function setupTestScenario(mocks: MockedResponse[]) { - const client = mockLensApolloClient(mocks); - - return { - renderHook( - callback: (props: TProps) => TResult, - ): RenderHookResult { - return renderHookWithMocks(callback, { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: client, - }, - }); - }, - }; -} - -describe(`Given the ${usePublications.name} hook`, () => { - const profileId = mockProfileId(); - const publications = [mockPostFragment()]; - const expectations = publications.map(({ __typename, id }) => ({ __typename, id })); - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe('when the query returns data successfully', () => { - const { renderHook } = setupTestScenario([ - mockGetPublicationsResponse({ - variables: { - profileId, - observerId: null, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publications, - }), - ]); - - it('should settle with the publications', async () => { - const { result } = renderHook(() => usePublications({ profileId })); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when a session with an Active Profile is set', () => { - const activeProfile = mockProfile(); - const { renderHook } = setupTestScenario([ - mockGetPublicationsResponse({ - variables: { - profileId, - observerId: activeProfile.id, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publications, - }), - ]); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - afterAll(() => { - simulateNotAuthenticated(); - }); - - it('should use the Active Profile as the queried publication observer', async () => { - const { result } = renderHook(() => usePublications({ profileId })); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when an "observerId" is provided', () => { - const observerId = mockProfileId(); - const { renderHook } = setupTestScenario([ - mockGetPublicationsResponse({ - variables: { - profileId, - observerId, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publications, - }), - ]); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const { result } = renderHook(() => usePublications({ profileId, observerId })); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe(`when re-rendered`, () => { - const initialPageInfo = mockPaginatedResultInfo({ prev: mockCursor() }); - - const { renderHook } = setupTestScenario([ - mockGetPublicationsResponse({ - variables: { - profileId, - observerId: null, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publications, - info: initialPageInfo, - }), - - mockGetPublicationsResponse({ - variables: { - profileId, - observerId: null, - cursor: initialPageInfo.prev, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publications: [mockPostFragment()], - }), - ]); - - it(`should return cached data and then update the 'beforeCount' if new results are available`, async () => { - const first = renderHook(() => usePublications({ profileId })); - await waitFor(() => expect(first.result.current.loading).toBeFalsy()); - - const second = renderHook(() => usePublications({ profileId })); - - expect(second.result.current).toMatchObject({ - data: expectations, - loading: false, - }); - - await waitFor(() => expect(second.result.current.beforeCount).toEqual(1)); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useReaction.spec.ts b/packages/react-v1/src/publication/__tests__/useReaction.spec.ts deleted file mode 100644 index b284008750..0000000000 --- a/packages/react-v1/src/publication/__tests__/useReaction.spec.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { ReactionTypes } from '@lens-protocol/api-bindings'; -import { - mockAddReactionResponse, - mockLensApolloClient, - mockRemoveReactionResponse, - mockPostFragment, - mockSources, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { act } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { defaultMediaTransformsConfig } from '../../mediaTransforms'; -import { PublicationCacheManager } from '../../transactions/adapters/PublicationCacheManager'; -import { useReaction } from '../useReaction'; - -function setupUseReaction({ - mocks = [], - profileId, -}: { - profileId: ProfileId; - mocks?: ReadonlyArray>; -}) { - const apolloClient = mockLensApolloClient(mocks); - return renderHookWithMocks( - () => - useReaction({ - profileId: profileId, - }), - { - mocks: { - apolloClient: apolloClient, - publicationCacheManager: new PublicationCacheManager( - apolloClient, - mockSources(), - defaultMediaTransformsConfig, - ), - }, - }, - ); -} - -describe(`Given the ${useReaction.name} hook`, () => { - describe(`when adding a reaction`, () => { - it('should call correct mutation and resolve without errors', async () => { - const publication = mockPostFragment(); - const profileId = publication.profile.id; - - const mocks = [ - mockAddReactionResponse({ - variables: { - publicationId: publication.id, - profileId, - reaction: ReactionTypes.Upvote, - }, - }), - ]; - - const { result } = setupUseReaction({ - mocks, - profileId, - }); - - await act(async () => { - await result.current.addReaction({ - publication: publication, - reactionType: ReactionTypes.Upvote, - }); - }); - - expect(result.current.isPending).toBe(false); - }); - }); - - describe(`when removing a reaction`, () => { - it('should call correct mutation and resolve without errors', async () => { - const mockPublication = mockPostFragment(); - const profileId = mockPublication.profile.id; - - const mocks = [ - mockRemoveReactionResponse({ - variables: { - publicationId: mockPublication.id, - profileId, - reaction: ReactionTypes.Upvote, - }, - }), - ]; - const { result } = setupUseReaction({ profileId, mocks }); - - await act(async () => { - await result.current.removeReaction({ - publication: mockPublication, - reactionType: ReactionTypes.Upvote, - }); - }); - - expect(result.current.isPending).toBe(false); - }); - }); - - describe(`when checking if a profile has reacted to a given publication`, () => { - it('should verify the provided reaction matches the reaction in the publication object', async () => { - const mockPublicationWithReaction = mockPostFragment({ - reaction: ReactionTypes.Upvote, - }); - - const { result } = setupUseReaction({ - profileId: mockPublicationWithReaction.profile.id, - }); - - const hasReactionResult = result.current.hasReaction({ - publication: mockPublicationWithReaction, - reactionType: ReactionTypes.Upvote, - }); - - expect(hasReactionResult).toBe(true); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useSearchPublications.spec.ts b/packages/react-v1/src/publication/__tests__/useSearchPublications.spec.ts deleted file mode 100644 index eb8690f50e..0000000000 --- a/packages/react-v1/src/publication/__tests__/useSearchPublications.spec.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { ContentPublication } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockSearchPublicationsResponse, - mockCommentFragment, - mockPostFragment, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { useSearchPublications, UseSearchPublicationsArgs } from '../useSearchPublications'; - -function setupTestScenario({ - result, - expectedObserverId, - ...args -}: UseSearchPublicationsArgs & { - expectedObserverId?: ProfileId; - result: ContentPublication[]; -}) { - const sources = mockSources(); - - return renderHookWithMocks(() => useSearchPublications(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockSearchPublicationsResponse({ - variables: { - ...args, - observerId: expectedObserverId ?? null, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - items: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useSearchPublications.name} hook`, () => { - const query = 'query_test'; - const publications = [mockPostFragment(), mockCommentFragment()]; - const expectations = publications.map(({ __typename, id }) => ({ __typename, id })); - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe('when the query returns data successfully', () => { - it('should return publications that match the search result', async () => { - const { result } = setupTestScenario({ query, result: publications }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - query, - result: publications, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - query, - result: publications, - observerId, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useWhoCollectedPublication.spec.ts b/packages/react-v1/src/publication/__tests__/useWhoCollectedPublication.spec.ts deleted file mode 100644 index 58faff91b1..0000000000 --- a/packages/react-v1/src/publication/__tests__/useWhoCollectedPublication.spec.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { Wallet } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockWalletFragment, - mockWhoCollectedPublicationResponse, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId, mockPublicationId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { - useWhoCollectedPublication, - UseWhoCollectedPublicationArgs, -} from '../useWhoCollectedPublication'; - -function setupTestScenario({ - expectedObserverId, - result, - ...args -}: UseWhoCollectedPublicationArgs & { expectedObserverId?: ProfileId; result: Wallet[] }) { - const sources = mockSources(); - - return renderHookWithMocks(() => useWhoCollectedPublication(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockWhoCollectedPublicationResponse({ - variables: { - ...args, - observerId: expectedObserverId ?? null, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - wallets: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useWhoCollectedPublication.name} hook`, () => { - const publicationId = mockPublicationId(); - const collectors = [mockWalletFragment()]; - const expectations = collectors.map(({ __typename, address }) => ({ __typename, address })); - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe('when the query returns data successfully', () => { - it('should return wallets who collected the publication', async () => { - const { result } = setupTestScenario({ publicationId, result: collectors }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - publicationId, - result: collectors, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - publicationId, - result: collectors, - observerId, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useWhoMirroredPublication.spec.ts b/packages/react-v1/src/publication/__tests__/useWhoMirroredPublication.spec.ts deleted file mode 100644 index e5911d508c..0000000000 --- a/packages/react-v1/src/publication/__tests__/useWhoMirroredPublication.spec.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { - mockGetAllProfilesResponse, - mockLensApolloClient, - mockProfileFragment, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId, mockPublicationId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { - useWhoMirroredPublication, - UseWhoMirroredPublicationArgs, -} from '../useWhoMirroredPublication'; - -function setupTestScenario({ - expectedObserverId, - result, - publicationId, - ...others -}: UseWhoMirroredPublicationArgs & { expectedObserverId?: ProfileId; result: Profile[] }) { - const sources = mockSources(); - - return renderHookWithMocks(() => useWhoMirroredPublication({ publicationId, ...others }), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockGetAllProfilesResponse({ - variables: { - ...others, - byWhoMirroredPublicationId: publicationId, - observerId: expectedObserverId ?? null, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - profiles: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useWhoMirroredPublication.name} hook`, () => { - const publicationId = mockPublicationId(); - const profiles = [mockProfileFragment()]; - const expectations = profiles.map(({ __typename, id }) => ({ __typename, id })); - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe('when the query returns data successfully', () => { - it('should return profiles that mirrored the queried publication', async () => { - const { result } = setupTestScenario({ publicationId, result: profiles }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - publicationId, - result: profiles, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - publicationId, - result: profiles, - observerId, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/publication/__tests__/useWhoReacted.spec.ts b/packages/react-v1/src/publication/__tests__/useWhoReacted.spec.ts deleted file mode 100644 index 102e2948d6..0000000000 --- a/packages/react-v1/src/publication/__tests__/useWhoReacted.spec.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { WhoReactedResult } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockWhoReactedPublicationResponse, - mockSources, - mockWhoReactedResultFragment, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId, mockPublicationId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { useWhoReacted, UseWhoReactedArgs } from '../useWhoReacted'; - -function setupTestScenario({ - expectedObserverId, - result, - ...args -}: UseWhoReactedArgs & { - expectedObserverId?: ProfileId; - result: WhoReactedResult[]; -}) { - const sources = mockSources(); - - return renderHookWithMocks(() => useWhoReacted(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockWhoReactedPublicationResponse({ - variables: { - ...args, - observerId: expectedObserverId ?? null, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - items: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useWhoReacted.name} hook`, () => { - const publicationId = mockPublicationId(); - const reactions = [mockWhoReactedResultFragment()]; - const expectations = reactions.map(({ __typename, reactionId }) => ({ __typename, reactionId })); - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe('when the query returns data successfully', () => { - it('should return who reacted results', async () => { - const { result } = setupTestScenario({ publicationId, result: reactions }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - publicationId, - result: reactions, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - publicationId, - result: reactions, - observerId, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/publication/adapters/BookmarksGateway.ts b/packages/react-v1/src/publication/adapters/BookmarksGateway.ts deleted file mode 100644 index e06867811b..0000000000 --- a/packages/react-v1/src/publication/adapters/BookmarksGateway.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - AddToMyBookmarksData, - AddToMyBookmarksDocument, - AddToMyBookmarksVariables, - RemoveFromMyBookmarksData, - RemoveFromMyBookmarksDocument, - RemoveFromMyBookmarksVariables, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; -import { - ITogglablePropertyGateway, - TogglePropertyRequest, -} from '@lens-protocol/domain/use-cases/publications'; - -export type BookmarkRequest = TogglePropertyRequest; - -export class BookmarksGateway implements ITogglablePropertyGateway { - constructor(private apolloClient: SafeApolloClient) {} - - async add({ publicationId, profileId }: BookmarkRequest): Promise { - await this.apolloClient.mutate({ - mutation: AddToMyBookmarksDocument, - variables: { - request: { - publicationId, - profileId, - }, - }, - }); - } - - async remove({ publicationId, profileId }: BookmarkRequest): Promise { - await this.apolloClient.mutate({ - mutation: RemoveFromMyBookmarksDocument, - variables: { - request: { - publicationId, - profileId, - }, - }, - }); - } -} diff --git a/packages/react-v1/src/publication/adapters/BookmarksPresenter.ts b/packages/react-v1/src/publication/adapters/BookmarksPresenter.ts deleted file mode 100644 index d93a113d93..0000000000 --- a/packages/react-v1/src/publication/adapters/BookmarksPresenter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { isMirrorPublication } from '@lens-protocol/api-bindings'; -import { - ITogglablePropertyPresenter, - TogglePropertyRequest, -} from '@lens-protocol/domain/use-cases/publications'; - -import { PublicationCacheManager } from '../../transactions/adapters/PublicationCacheManager'; -import { BookmarkRequest } from './BookmarksGateway'; - -export class BookmarksPresenter implements ITogglablePropertyPresenter { - constructor(private readonly publicationCacheManager: PublicationCacheManager) {} - - async add({ publicationId }: TogglePropertyRequest) { - this.publicationCacheManager.update(publicationId, (current) => { - if (isMirrorPublication(current)) { - return current; - } - - return { - ...current, - bookmarked: true, - }; - }); - } - - async remove({ publicationId }: TogglePropertyRequest) { - this.publicationCacheManager.update(publicationId, (current) => { - if (isMirrorPublication(current)) { - return current; - } - - return { - ...current, - bookmarked: false, - }; - }); - } -} diff --git a/packages/react-v1/src/publication/adapters/HidePublicationGateway.ts b/packages/react-v1/src/publication/adapters/HidePublicationGateway.ts deleted file mode 100644 index cc220a97fa..0000000000 --- a/packages/react-v1/src/publication/adapters/HidePublicationGateway.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - HidePublicationDocument, - HidePublicationData, - HidePublicationVariables, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; -import { - HidePublicationRequest, - IHidePublicationGateway, -} from '@lens-protocol/domain/use-cases/publications'; - -export class HidePublicationGateway implements IHidePublicationGateway { - constructor(private apolloClient: SafeApolloClient) {} - - async hide(request: HidePublicationRequest) { - await this.apolloClient.mutate({ - mutation: HidePublicationDocument, - variables: { - publicationId: request.publicationId, - }, - }); - } -} diff --git a/packages/react-v1/src/publication/adapters/HidePublicationPresenter.ts b/packages/react-v1/src/publication/adapters/HidePublicationPresenter.ts deleted file mode 100644 index 9637f69f83..0000000000 --- a/packages/react-v1/src/publication/adapters/HidePublicationPresenter.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PublicationId } from '@lens-protocol/domain/entities'; -import { IHidePublicationPresenter } from '@lens-protocol/domain/use-cases/publications'; - -import { PublicationCacheManager } from '../../transactions/adapters/PublicationCacheManager'; - -export class HidePublicationPresenter implements IHidePublicationPresenter { - constructor(private readonly publicationCacheManager: PublicationCacheManager) {} - - present(publicationId: PublicationId) { - this.publicationCacheManager.update(publicationId, (current) => ({ ...current, hidden: true })); - } -} diff --git a/packages/react-v1/src/publication/adapters/NotInterestedGateway.ts b/packages/react-v1/src/publication/adapters/NotInterestedGateway.ts deleted file mode 100644 index 14db062c05..0000000000 --- a/packages/react-v1/src/publication/adapters/NotInterestedGateway.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - AddNotInterestedData, - AddNotInterestedDocument, - AddNotInterestedVariables, - RemoveNotInterestedData, - RemoveNotInterestedDocument, - RemoveNotInterestedVariables, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; -import { - ITogglablePropertyGateway, - TogglePropertyRequest, -} from '@lens-protocol/domain/use-cases/publications'; - -export type NotInterestedRequest = TogglePropertyRequest; - -export class NotInterestedGateway implements ITogglablePropertyGateway { - constructor(private apolloClient: SafeApolloClient) {} - - async add({ publicationId, profileId }: NotInterestedRequest): Promise { - await this.apolloClient.mutate({ - mutation: AddNotInterestedDocument, - variables: { - request: { - publicationId, - profileId, - }, - }, - }); - } - - async remove({ publicationId, profileId }: NotInterestedRequest): Promise { - await this.apolloClient.mutate({ - mutation: RemoveNotInterestedDocument, - variables: { - request: { - publicationId, - profileId, - }, - }, - }); - } -} diff --git a/packages/react-v1/src/publication/adapters/NotInterestedPresenter.ts b/packages/react-v1/src/publication/adapters/NotInterestedPresenter.ts deleted file mode 100644 index 6133ed1a4d..0000000000 --- a/packages/react-v1/src/publication/adapters/NotInterestedPresenter.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { isMirrorPublication } from '@lens-protocol/api-bindings'; -import { - ITogglablePropertyPresenter, - TogglePropertyRequest, -} from '@lens-protocol/domain/use-cases/publications'; - -import { PublicationCacheManager } from '../../transactions/adapters/PublicationCacheManager'; -import { NotInterestedRequest } from './NotInterestedGateway'; - -export class NotInterestedPresenter implements ITogglablePropertyPresenter { - constructor(private readonly publicationCacheManager: PublicationCacheManager) {} - - async add({ publicationId }: TogglePropertyRequest) { - this.publicationCacheManager.update(publicationId, (current) => { - if (isMirrorPublication(current)) { - return current; - } - - return { - ...current, - notInterested: true, - }; - }); - } - - async remove({ publicationId }: TogglePropertyRequest) { - this.publicationCacheManager.update(publicationId, (current) => { - if (isMirrorPublication(current)) { - return current; - } - - return { - ...current, - notInterested: false, - }; - }); - } -} diff --git a/packages/react-v1/src/publication/adapters/ReactionGateway.ts b/packages/react-v1/src/publication/adapters/ReactionGateway.ts deleted file mode 100644 index 1541059d7e..0000000000 --- a/packages/react-v1/src/publication/adapters/ReactionGateway.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { - AddReactionDocument, - AddReactionData, - AddReactionVariables, - RemoveReactionDocument, - RemoveReactionData, - RemoveReactionVariables, - ValidationError, - SafeApolloClient, - ReactionTypes, -} from '@lens-protocol/api-bindings'; -import { - TogglePropertyRequest, - ITogglablePropertyGateway, -} from '@lens-protocol/domain/use-cases/publications'; -import { assertError } from '@lens-protocol/shared-kernel'; - -export type ReactionRequest = TogglePropertyRequest & { - reactionType: ReactionTypes; - existingReactionType?: ReactionTypes | null; -}; - -export class ReactionGateway implements ITogglablePropertyGateway { - constructor(private apolloClient: SafeApolloClient) {} - - async add({ - profileId, - publicationId, - reactionType: reactionType, - existingReactionType, - }: ReactionRequest) { - if (existingReactionType === reactionType) { - return; - } - - if (existingReactionType && existingReactionType !== reactionType) { - await this.remove({ profileId, publicationId, reactionType: existingReactionType }); - } - - await this.apolloClient.mutate({ - mutation: AddReactionDocument, - variables: { - publicationId, - profileId, - reaction: reactionType, - }, - }); - } - - async remove({ profileId, publicationId, reactionType }: ReactionRequest) { - try { - await this.apolloClient.mutate({ - mutation: RemoveReactionDocument, - variables: { - publicationId, - profileId, - reaction: reactionType, - }, - }); - } catch (e) { - assertError(e); - - if (e instanceof ValidationError) { - return; - } - - throw e; - } - } -} diff --git a/packages/react-v1/src/publication/adapters/ReactionPresenter.ts b/packages/react-v1/src/publication/adapters/ReactionPresenter.ts deleted file mode 100644 index 72848c23fb..0000000000 --- a/packages/react-v1/src/publication/adapters/ReactionPresenter.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { isContentPublication, ReactionTypes } from '@lens-protocol/api-bindings'; -import { ITogglablePropertyPresenter } from '@lens-protocol/domain/use-cases/publications'; -import { assertNever, invariant } from '@lens-protocol/shared-kernel'; - -import { PublicationCacheManager } from '../../transactions/adapters/PublicationCacheManager'; -import { ReactionRequest } from './ReactionGateway'; - -const getReactionStatKey = (reactionType: ReactionTypes) => { - switch (reactionType) { - case ReactionTypes.Upvote: - return 'totalUpvotes' as const; - case ReactionTypes.Downvote: - return 'totalDownvotes' as const; - default: - assertNever(reactionType, 'Invalid reaction type'); - } -}; - -export class ReactionPresenter implements ITogglablePropertyPresenter { - constructor(private readonly publicationCacheManager: PublicationCacheManager) {} - - async add(request: ReactionRequest): Promise { - this.publicationCacheManager.update(request.publicationId, (current) => { - invariant( - isContentPublication(current), - `Reactions are not supported on ${current.__typename}`, - ); - - const removedStatKey = current.reaction ? getReactionStatKey(current.reaction) : undefined; - - const currentStatsValue = current.stats[getReactionStatKey(request.reactionType)]; - - invariant(typeof currentStatsValue === 'number', 'Invalid stats value'); - - return { - ...current, - stats: { - ...current.stats, - ...(removedStatKey && { [removedStatKey]: current.stats[removedStatKey] - 1 }), - [getReactionStatKey(request.reactionType)]: currentStatsValue + 1, - }, - reaction: request.reactionType, - }; - }); - } - - async remove(request: ReactionRequest): Promise { - const statKey = getReactionStatKey(request.reactionType); - - this.publicationCacheManager.update(request.publicationId, (current) => { - invariant( - isContentPublication(current), - `Reactions are not supported on ${current.__typename}`, - ); - - return { - ...current, - stats: { - ...current.stats, - [statKey]: current.stats[statKey] - 1, - }, - reaction: null, - }; - }); - } -} diff --git a/packages/react-v1/src/publication/adapters/ReportPublicationGateway.ts b/packages/react-v1/src/publication/adapters/ReportPublicationGateway.ts deleted file mode 100644 index 5afa7d56b7..0000000000 --- a/packages/react-v1/src/publication/adapters/ReportPublicationGateway.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { - SafeApolloClient, - PublicationReportingFraudSubreason, - PublicationReportingIllegalSubreason, - PublicationReportingReason, - PublicationReportingSensitiveSubreason, - PublicationReportingSpamSubreason, - ReportingReasonInputParams, - ReportPublicationDocument, - ReportPublicationData, - ReportPublicationVariables, -} from '@lens-protocol/api-bindings'; -import { ReportReason } from '@lens-protocol/domain/entities'; -import { - IReportPublicationGateway, - ReportPublicationRequest, -} from '@lens-protocol/domain/use-cases/publications'; -import { assertNever } from '@lens-protocol/shared-kernel'; - -const mapReportReasonToInput = (reason: ReportReason): ReportingReasonInputParams => { - switch (reason) { - case ReportReason.VIOLENCE: - return { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.Violence, - }, - }; - case ReportReason.SELF_HARM: - return { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.ThreatIndividual, - }, - }; - case ReportReason.DIRECT_THREAT: - return { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.DirectThreat, - }, - }; - case ReportReason.HARASSMENT: - case ReportReason.HATE_SPEECH: - return { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.HumanAbuse, - }, - }; - case ReportReason.ANIMAL_ABUSE: - return { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.AnimalAbuse, - }, - }; - case ReportReason.SCAM: - case ReportReason.UNAUTHORIZED_SALE: - return { - fraudReason: { - reason: PublicationReportingReason.Fraud, - subreason: PublicationReportingFraudSubreason.Scam, - }, - }; - case ReportReason.IMPERSONATION: - return { - fraudReason: { - reason: PublicationReportingReason.Fraud, - subreason: PublicationReportingFraudSubreason.Impersonation, - }, - }; - case ReportReason.NUDITY: - return { - sensitiveReason: { - reason: PublicationReportingReason.Sensitive, - subreason: PublicationReportingSensitiveSubreason.Nsfw, - }, - }; - case ReportReason.OFFENSIVE: - return { - sensitiveReason: { - reason: PublicationReportingReason.Sensitive, - subreason: PublicationReportingSensitiveSubreason.Offensive, - }, - }; - case ReportReason.MISLEADING: - return { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.Misleading, - }, - }; - case ReportReason.MISUSE_HASHTAGS: - return { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.MisuseHashtags, - }, - }; - case ReportReason.UNRELATED: - return { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.Unrelated, - }, - }; - case ReportReason.REPETITIVE: - return { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.Repetitive, - }, - }; - case ReportReason.FAKE_ENGAGEMENT: - return { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.FakeEngagement, - }, - }; - case ReportReason.MANIPULATION_ALGO: - return { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.ManipulationAlgo, - }, - }; - case ReportReason.SOMETHING_ELSE: - return { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.SomethingElse, - }, - }; - default: - assertNever(reason, `Unknown report type`); - } -}; - -export class ReportPublicationGateway implements IReportPublicationGateway { - constructor(private apolloClient: SafeApolloClient) {} - - async report({ additionalComments, publicationId, reason }: ReportPublicationRequest) { - await this.apolloClient.mutate({ - mutation: ReportPublicationDocument, - variables: { - publicationId, - additionalComments, - reason: { - ...mapReportReasonToInput(reason), - }, - }, - }); - } -} diff --git a/packages/react-v1/src/publication/adapters/__helpers__/mocks.ts b/packages/react-v1/src/publication/adapters/__helpers__/mocks.ts deleted file mode 100644 index 977f7cbaf6..0000000000 --- a/packages/react-v1/src/publication/adapters/__helpers__/mocks.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ReactionTypes } from '@lens-protocol/api-bindings'; -import { mockProfileId, mockPublicationId } from '@lens-protocol/domain/mocks'; - -import { ReactionRequest } from '../ReactionGateway'; - -export function mockReactionRequest(overrides?: Partial): ReactionRequest { - return { - profileId: mockProfileId(), - publicationId: mockPublicationId(), - reactionType: ReactionTypes.Upvote, - ...overrides, - }; -} diff --git a/packages/react-v1/src/publication/adapters/__tests__/HidePublicationGateway.spec.ts b/packages/react-v1/src/publication/adapters/__tests__/HidePublicationGateway.spec.ts deleted file mode 100644 index 5532a913c7..0000000000 --- a/packages/react-v1/src/publication/adapters/__tests__/HidePublicationGateway.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { - mockLensApolloClient, - mockHidePublicationResponse, -} from '@lens-protocol/api-bindings/mocks'; -import { mockHidePublicationRequest, mockPublicationId } from '@lens-protocol/domain/mocks'; - -import { HidePublicationGateway } from '../HidePublicationGateway'; - -describe(`Given an instance of the ${HidePublicationGateway.name}`, () => { - describe(`when the ${HidePublicationGateway.prototype.hide.name} method is invoked`, () => { - it(`should perform the expected mutation request`, async () => { - const publicationId = mockPublicationId(); - - const apolloClient = mockLensApolloClient([ - mockHidePublicationResponse({ - variables: { - publicationId, - }, - }), - ]); - - const gateway = new HidePublicationGateway(apolloClient); - const request = mockHidePublicationRequest({ - publicationId, - }); - - return expect(gateway.hide(request)).resolves.toBeUndefined(); - }); - }); -}); diff --git a/packages/react-v1/src/publication/adapters/__tests__/HidePublicationPresenter.spec.ts b/packages/react-v1/src/publication/adapters/__tests__/HidePublicationPresenter.spec.ts deleted file mode 100644 index 7a0ba7e924..0000000000 --- a/packages/react-v1/src/publication/adapters/__tests__/HidePublicationPresenter.spec.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Post, FragmentPost } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockPostFragment, - mockPublicationStatsFragment, - mockSources, -} from '@lens-protocol/api-bindings/mocks'; - -import { defaultMediaTransformsConfig } from '../../../mediaTransforms'; -import { PublicationCacheManager } from '../../../transactions/adapters/PublicationCacheManager'; -import { HidePublicationPresenter } from '../HidePublicationPresenter'; - -function setupTestScenario({ post }: { post: Post }) { - const client = mockLensApolloClient(); - - client.cache.writeFragment({ - id: client.cache.identify({ - __typename: 'Post', - id: post.id, - }), - fragment: FragmentPost, - fragmentName: 'Post', - data: post, - }); - - const publicationCacheManager = new PublicationCacheManager( - client, - mockSources(), - defaultMediaTransformsConfig, - ); - const presenter = new HidePublicationPresenter(publicationCacheManager); - - return { - presenter, - - get updatedPostFragment() { - return client.cache.readFragment({ - id: client.cache.identify({ - __typename: 'Post', - id: post.id, - }), - fragment: FragmentPost, - fragmentName: 'Post', - }); - }, - }; -} - -describe(`Given the ${HidePublicationPresenter.name}`, () => { - describe(`when "${HidePublicationPresenter.prototype.present.name}" method is invoked`, () => { - it(`should update apollo cache by flagging publication as hidden`, async () => { - const post = mockPostFragment({ - reaction: null, - stats: mockPublicationStatsFragment({ totalUpvotes: 1 }), - }); - - const scenario = setupTestScenario({ - post, - }); - - scenario.presenter.present(post.id); - - expect(scenario.updatedPostFragment).toEqual( - expect.objectContaining({ - hidden: true, - }), - ); - }); - }); -}); diff --git a/packages/react-v1/src/publication/adapters/__tests__/ReactionGateway.spec.ts b/packages/react-v1/src/publication/adapters/__tests__/ReactionGateway.spec.ts deleted file mode 100644 index 2a2ddfadf8..0000000000 --- a/packages/react-v1/src/publication/adapters/__tests__/ReactionGateway.spec.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { ReactionTypes, ValidationError } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockAddReactionResponse, - mockRemoveReactionResponse, - mockRemoveReactionResponseWithGraphqlValidationError, -} from '@lens-protocol/api-bindings/mocks'; -import { mockProfileId, mockPublicationId } from '@lens-protocol/domain/mocks'; - -import { ReactionGateway } from '../ReactionGateway'; -import { mockReactionRequest } from '../__helpers__/mocks'; - -describe(`Given an instance of the ${ReactionGateway.name}`, () => { - describe(`and the ${ReactionGateway.prototype.add.name} method`, () => { - it(`should add reaction with success`, async () => { - const profileId = mockProfileId(); - const publicationId = mockPublicationId(); - - const apolloClient = mockLensApolloClient([ - mockAddReactionResponse({ - variables: { - publicationId, - profileId, - reaction: ReactionTypes.Upvote, - }, - }), - ]); - - const gateway = new ReactionGateway(apolloClient); - const request = mockReactionRequest({ - publicationId, - profileId, - existingReactionType: undefined, - }); - - await gateway.add(request); - }); - - describe(`and there is already an existing reaction`, () => { - it(`should first remove existing reaction before adding a new one`, async () => { - const profileId = mockProfileId(); - const publicationId = mockPublicationId(); - - const apolloClient = mockLensApolloClient([ - mockRemoveReactionResponse({ - variables: { - publicationId, - profileId, - reaction: ReactionTypes.Downvote, - }, - }), - mockAddReactionResponse({ - variables: { - publicationId, - profileId, - reaction: ReactionTypes.Upvote, - }, - }), - ]); - - const gateway = new ReactionGateway(apolloClient); - const request = mockReactionRequest({ - publicationId, - profileId, - existingReactionType: ReactionTypes.Downvote, - }); - - await gateway.add(request); - }); - }); - }); - - describe(`and the ${ReactionGateway.prototype.remove.name} method`, () => { - it(`should remove reaction with success`, async () => { - const profileId = mockProfileId(); - const publicationId = mockPublicationId(); - - const apolloClient = mockLensApolloClient([ - mockRemoveReactionResponse({ - variables: { - publicationId, - profileId, - reaction: ReactionTypes.Upvote, - }, - }), - ]); - - const gateway = new ReactionGateway(apolloClient); - const request = mockReactionRequest({ - publicationId, - profileId, - }); - - await gateway.remove(request); - }); - - it(`should be resilient to ${ValidationError.name} and resolve the promise`, async () => { - const profileId = mockProfileId(); - const publicationId = mockPublicationId(); - const apolloClient = mockLensApolloClient([ - mockRemoveReactionResponseWithGraphqlValidationError({ - variables: { - publicationId, - profileId, - reaction: ReactionTypes.Upvote, - }, - }), - ]); - - const gateway = new ReactionGateway(apolloClient); - const request = mockReactionRequest({ - publicationId, - profileId, - }); - - await gateway.remove(request); - }); - - it(`should propagate any other error`, async () => { - const apolloClient = mockLensApolloClient([ - // no mocks on purpose to trigger network issue - ]); - - const gateway = new ReactionGateway(apolloClient); - const request = mockReactionRequest(); - - await expect(gateway.remove(request)).rejects.toThrow(); - }); - }); -}); diff --git a/packages/react-v1/src/publication/adapters/__tests__/ReactionPresenter.spec.ts b/packages/react-v1/src/publication/adapters/__tests__/ReactionPresenter.spec.ts deleted file mode 100644 index 0d644bc0f0..0000000000 --- a/packages/react-v1/src/publication/adapters/__tests__/ReactionPresenter.spec.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { Post, FragmentPost, ReactionTypes } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockPostFragment, - mockPublicationStatsFragment, - mockSources, -} from '@lens-protocol/api-bindings/mocks'; -import { TogglePropertyRequest } from '@lens-protocol/domain/use-cases/publications'; - -import { defaultMediaTransformsConfig } from '../../../mediaTransforms'; -import { PublicationCacheManager } from '../../../transactions/adapters/PublicationCacheManager'; -import { ReactionPresenter } from '../ReactionPresenter'; -import { mockReactionRequest } from '../__helpers__/mocks'; - -function setupTestScenario({ post, request }: { post: Post; request: TogglePropertyRequest }) { - const client = mockLensApolloClient(); - - client.cache.writeFragment({ - id: client.cache.identify({ - __typename: 'Post', - id: request.publicationId, - }), - fragment: FragmentPost, - fragmentName: 'Post', - data: post, - }); - - const publicationCacheManager = new PublicationCacheManager( - client, - mockSources(), - defaultMediaTransformsConfig, - ); - const presenter = new ReactionPresenter(publicationCacheManager); - - return { - presenter, - - get updatedPostFragment() { - return client.cache.readFragment({ - id: client.cache.identify({ - __typename: 'Post', - id: post.id, - }), - fragment: FragmentPost, - fragmentName: 'Post', - }); - }, - }; -} - -describe(`Given the ${ReactionPresenter.name}`, () => { - describe(`when the "${ReactionPresenter.prototype.add.name}" method is invoked`, () => { - it(`should update apollo cache with added upvote reaction`, async () => { - const post = mockPostFragment({ - reaction: null, - stats: mockPublicationStatsFragment({ totalUpvotes: 1 }), - }); - const request = mockReactionRequest({ - publicationId: post.id, - }); - - const scenario = setupTestScenario({ - post, - request, - }); - - await scenario.presenter.add(request); - - expect(scenario.updatedPostFragment).toEqual( - expect.objectContaining({ - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - stats: expect.objectContaining({ - totalUpvotes: post.stats.totalUpvotes + 1, - }), - reaction: ReactionTypes.Upvote, - }), - ); - }); - - it(`should update apollo cache with added downvote reaction`, async () => { - const post = mockPostFragment({ - reaction: null, - stats: mockPublicationStatsFragment({ totalDownvotes: 1 }), - }); - - const request = mockReactionRequest({ - publicationId: post.id, - reactionType: ReactionTypes.Downvote, - }); - - const scenario = setupTestScenario({ - post, - request, - }); - - await scenario.presenter.add(request); - - expect(scenario.updatedPostFragment).toEqual( - expect.objectContaining({ - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - stats: expect.objectContaining({ - totalDownvotes: post.stats.totalDownvotes + 1, - }), - reaction: ReactionTypes.Downvote, - }), - ); - }); - - it(`should update apollo cache with added reaction update the stats based on the previous reaction`, async () => { - const post = mockPostFragment({ - reaction: ReactionTypes.Upvote, - stats: mockPublicationStatsFragment({ - totalUpvotes: 1, - totalDownvotes: 0, - }), - }); - const request = mockReactionRequest({ - publicationId: post.id, - reactionType: ReactionTypes.Downvote, - }); - - const scenario = setupTestScenario({ - post, - request, - }); - - await scenario.presenter.add(request); - - expect(scenario.updatedPostFragment).toEqual( - expect.objectContaining({ - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - stats: expect.objectContaining({ - totalUpvotes: 0, - totalDownvotes: 1, - }), - reaction: ReactionTypes.Downvote, - }), - ); - }); - }); - - describe(`when the "${ReactionPresenter.prototype.remove.name}" method is invoked`, () => { - it(`should update apollo cache with removed reaction`, async () => { - const post = mockPostFragment({ - reaction: ReactionTypes.Upvote, - stats: mockPublicationStatsFragment({ totalUpvotes: 1 }), - }); - const request = mockReactionRequest({ - publicationId: post.id, - }); - - const scenario = setupTestScenario({ - post, - request, - }); - - await scenario.presenter.remove(request); - - expect(scenario.updatedPostFragment).toEqual( - expect.objectContaining({ - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - stats: expect.objectContaining({ - totalUpvotes: post.stats.totalUpvotes - 1, - }), - reaction: null, - }), - ); - }); - }); -}); diff --git a/packages/react-v1/src/publication/adapters/__tests__/ReportPublicationGateway.spec.ts b/packages/react-v1/src/publication/adapters/__tests__/ReportPublicationGateway.spec.ts deleted file mode 100644 index 0c17537f18..0000000000 --- a/packages/react-v1/src/publication/adapters/__tests__/ReportPublicationGateway.spec.ts +++ /dev/null @@ -1,210 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { - PublicationReportingFraudSubreason, - PublicationReportingIllegalSubreason, - PublicationReportingReason, - PublicationReportingSensitiveSubreason, - PublicationReportingSpamSubreason, -} from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockReportPublicationResponse, -} from '@lens-protocol/api-bindings/mocks'; -import { ReportReason } from '@lens-protocol/domain/entities'; -import { mockPublicationId, mockReportPublicationRequest } from '@lens-protocol/domain/mocks'; - -import { ReportPublicationGateway } from '../ReportPublicationGateway'; - -describe(`Given an instance of the ${ReportPublicationGateway.name}`, () => { - describe(`when invoking the ${ReportPublicationGateway.prototype.report.name} method`, () => { - it.each([ - { - reason: ReportReason.VIOLENCE, - expectedRequestReason: { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.Violence, - }, - }, - }, - { - reason: ReportReason.SELF_HARM, - expectedRequestReason: { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.ThreatIndividual, - }, - }, - }, - { - reason: ReportReason.DIRECT_THREAT, - expectedRequestReason: { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.DirectThreat, - }, - }, - }, - { - reason: ReportReason.HARASSMENT, - expectedRequestReason: { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.HumanAbuse, - }, - }, - }, - { - reason: ReportReason.HATE_SPEECH, - expectedRequestReason: { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.HumanAbuse, - }, - }, - }, - { - reason: ReportReason.ANIMAL_ABUSE, - expectedRequestReason: { - illegalReason: { - reason: PublicationReportingReason.Illegal, - subreason: PublicationReportingIllegalSubreason.AnimalAbuse, - }, - }, - }, - { - reason: ReportReason.SCAM, - expectedRequestReason: { - fraudReason: { - reason: PublicationReportingReason.Fraud, - subreason: PublicationReportingFraudSubreason.Scam, - }, - }, - }, - { - reason: ReportReason.UNAUTHORIZED_SALE, - expectedRequestReason: { - fraudReason: { - reason: PublicationReportingReason.Fraud, - subreason: PublicationReportingFraudSubreason.Scam, - }, - }, - }, - { - reason: ReportReason.IMPERSONATION, - expectedRequestReason: { - fraudReason: { - reason: PublicationReportingReason.Fraud, - subreason: PublicationReportingFraudSubreason.Impersonation, - }, - }, - }, - { - reason: ReportReason.NUDITY, - expectedRequestReason: { - sensitiveReason: { - reason: PublicationReportingReason.Sensitive, - subreason: PublicationReportingSensitiveSubreason.Nsfw, - }, - }, - }, - { - reason: ReportReason.OFFENSIVE, - expectedRequestReason: { - sensitiveReason: { - reason: PublicationReportingReason.Sensitive, - subreason: PublicationReportingSensitiveSubreason.Offensive, - }, - }, - }, - { - reason: ReportReason.MISLEADING, - expectedRequestReason: { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.Misleading, - }, - }, - }, - { - reason: ReportReason.MISUSE_HASHTAGS, - expectedRequestReason: { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.MisuseHashtags, - }, - }, - }, - { - reason: ReportReason.UNRELATED, - expectedRequestReason: { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.Unrelated, - }, - }, - }, - { - reason: ReportReason.REPETITIVE, - expectedRequestReason: { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.Repetitive, - }, - }, - }, - { - reason: ReportReason.FAKE_ENGAGEMENT, - expectedRequestReason: { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.FakeEngagement, - }, - }, - }, - { - reason: ReportReason.MANIPULATION_ALGO, - expectedRequestReason: { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.ManipulationAlgo, - }, - }, - }, - { - reason: ReportReason.SOMETHING_ELSE, - expectedRequestReason: { - spamReason: { - reason: PublicationReportingReason.Spam, - subreason: PublicationReportingSpamSubreason.SomethingElse, - }, - }, - }, - ])( - `should report the publication mapping the ReportReason.$reason to the expected request`, - async ({ reason, expectedRequestReason }) => { - const publicationId = mockPublicationId(); - const additionalComments = faker.lorem.sentence(); - - const apolloClient = mockLensApolloClient([ - mockReportPublicationResponse({ - variables: { - publicationId, - reason: expectedRequestReason, - additionalComments, - }, - }), - ]); - - const gateway = new ReportPublicationGateway(apolloClient); - const request = mockReportPublicationRequest({ - publicationId, - reason, - additionalComments, - }); - - return expect(gateway.report(request)).resolves.toBeUndefined(); - }, - ); - }); -}); diff --git a/packages/react-v1/src/publication/adapters/useBookmarkToggleController.ts b/packages/react-v1/src/publication/adapters/useBookmarkToggleController.ts deleted file mode 100644 index d7d7fdb5ae..0000000000 --- a/packages/react-v1/src/publication/adapters/useBookmarkToggleController.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ToggleProperty } from '@lens-protocol/domain/use-cases/publications'; - -import { useSharedDependencies } from '../../shared'; -import { BookmarkRequest, BookmarksGateway } from './BookmarksGateway'; -import { BookmarksPresenter } from './BookmarksPresenter'; - -export function useBookmarkToggleController() { - const { apolloClient, publicationCacheManager } = useSharedDependencies(); - - const add = async (request: BookmarkRequest) => { - const presenter = new BookmarksPresenter(publicationCacheManager); - const gateway = new BookmarksGateway(apolloClient); - const bookmark = new ToggleProperty(gateway, presenter); - - await bookmark.add(request); - }; - - const remove = async (request: BookmarkRequest) => { - const presenter = new BookmarksPresenter(publicationCacheManager); - const gateway = new BookmarksGateway(apolloClient); - const bookmark = new ToggleProperty(gateway, presenter); - - await bookmark.remove(request); - }; - - return { - add, - remove, - }; -} diff --git a/packages/react-v1/src/publication/adapters/useHidePublicationController.ts b/packages/react-v1/src/publication/adapters/useHidePublicationController.ts deleted file mode 100644 index 0e9e00b253..0000000000 --- a/packages/react-v1/src/publication/adapters/useHidePublicationController.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { PublicationId } from '@lens-protocol/domain/entities'; -import { HidePublication } from '@lens-protocol/domain/use-cases/publications'; - -import { useSharedDependencies } from '../../shared'; -import { HidePublicationGateway } from './HidePublicationGateway'; -import { HidePublicationPresenter } from './HidePublicationPresenter'; - -export type HidePublicationControllerRequest = { - publicationId: PublicationId; -}; - -export function useHidePublicationController() { - const { apolloClient, publicationCacheManager } = useSharedDependencies(); - - return async ({ publicationId }: HidePublicationControllerRequest) => { - const presenter = new HidePublicationPresenter(publicationCacheManager); - const gateway = new HidePublicationGateway(apolloClient); - const hidePublication = new HidePublication(gateway, presenter); - - await hidePublication.hide({ publicationId }); - }; -} diff --git a/packages/react-v1/src/publication/adapters/useNotInterestedController.ts b/packages/react-v1/src/publication/adapters/useNotInterestedController.ts deleted file mode 100644 index 322849c709..0000000000 --- a/packages/react-v1/src/publication/adapters/useNotInterestedController.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ToggleProperty } from '@lens-protocol/domain/use-cases/publications'; - -import { useSharedDependencies } from '../../shared'; -import { NotInterestedGateway, NotInterestedRequest } from './NotInterestedGateway'; -import { NotInterestedPresenter } from './NotInterestedPresenter'; - -export function useNotInterestedController() { - const { apolloClient, publicationCacheManager } = useSharedDependencies(); - - const add = async (request: NotInterestedRequest) => { - const presenter = new NotInterestedPresenter(publicationCacheManager); - const gateway = new NotInterestedGateway(apolloClient); - const reaction = new ToggleProperty(gateway, presenter); - - await reaction.add(request); - }; - - const remove = async (request: NotInterestedRequest) => { - const presenter = new NotInterestedPresenter(publicationCacheManager); - const gateway = new NotInterestedGateway(apolloClient); - const reaction = new ToggleProperty(gateway, presenter); - - await reaction.remove(request); - }; - - return { - add, - remove, - }; -} diff --git a/packages/react-v1/src/publication/adapters/useReactionController.ts b/packages/react-v1/src/publication/adapters/useReactionController.ts deleted file mode 100644 index 40b285338a..0000000000 --- a/packages/react-v1/src/publication/adapters/useReactionController.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ToggleProperty } from '@lens-protocol/domain/use-cases/publications'; - -import { useSharedDependencies } from '../../shared'; -import { ReactionRequest, ReactionGateway } from './ReactionGateway'; -import { ReactionPresenter } from './ReactionPresenter'; - -export function useReactionController() { - const { apolloClient, publicationCacheManager } = useSharedDependencies(); - - const add = async (request: ReactionRequest) => { - const presenter = new ReactionPresenter(publicationCacheManager); - const gateway = new ReactionGateway(apolloClient); - const reaction = new ToggleProperty(gateway, presenter); - - await reaction.add(request); - }; - - const remove = async (request: ReactionRequest) => { - const presenter = new ReactionPresenter(publicationCacheManager); - const gateway = new ReactionGateway(apolloClient); - const reaction = new ToggleProperty(gateway, presenter); - - await reaction.remove(request); - }; - - return { - add, - remove, - }; -} diff --git a/packages/react-v1/src/publication/adapters/useReportPublicationController.ts b/packages/react-v1/src/publication/adapters/useReportPublicationController.ts deleted file mode 100644 index a9b931e7ef..0000000000 --- a/packages/react-v1/src/publication/adapters/useReportPublicationController.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - ReportPublication, - ReportPublicationRequest, -} from '@lens-protocol/domain/use-cases/publications'; - -import { useSharedDependencies } from '../../shared'; -import { PromiseResultPresenter } from '../../transactions/adapters/PromiseResultPresenter'; -import { ReportPublicationGateway } from './ReportPublicationGateway'; - -export function useReportPublicationController() { - const { apolloClient } = useSharedDependencies(); - - return async (request: ReportPublicationRequest) => { - const gateway = new ReportPublicationGateway(apolloClient); - const presenter = new PromiseResultPresenter(); - - const reportPublication = new ReportPublication(gateway, presenter); - - await reportPublication.report(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/publication/filters.ts b/packages/react-v1/src/publication/filters.ts deleted file mode 100644 index c9ebb5ca45..0000000000 --- a/packages/react-v1/src/publication/filters.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { - PublicationContentWarning, - PublicationMainFocus, - PublicationMetadataFilters as LensPublicationMetadataFilters, -} from '@lens-protocol/api-bindings'; - -/** - * Filter publications by some of their metadata fields. - */ -export type PublicationMetadataFilters = { - restrictPublicationMainFocusTo?: PublicationMainFocus[]; - - /** - * A string that will be used to filter publications by their language and optionally regional dialect. - * - * It support a subset of the {@link https://www.rfc-editor.org/info/bcp47 | BCP-47} specification. - * - * You can specify a language restriction by providing the corresponding ISO 639-1 language code: - * - * @example - * ``` - * en # English language from any region - * it # Italian language from any region - * ``` - * - * You can also specify a language and region restriction by providing the corresponding ISO 639-1 language code and ISO 3166-1 alpha-2 region code: - * - * @example - * ``` - * en-US # English language from the United States - * en-GB # English language from the United Kingdom - * ``` - */ - restrictPublicationLocaleTo?: string; - showPublicationsWithContentWarnings?: { - oneOf: PublicationContentWarning[]; - }; - restrictPublicationTagsTo?: - | { - all: string[]; - } - | { - oneOf: string[]; - }; -}; - -export function createPublicationMetadataFilters( - filters: PublicationMetadataFilters | undefined, -): LensPublicationMetadataFilters | undefined { - if (!filters) { - return undefined; - } - - return { - locale: filters.restrictPublicationLocaleTo, - mainContentFocus: filters.restrictPublicationMainFocusTo, - tags: filters.restrictPublicationTagsTo, - ...(!!filters.showPublicationsWithContentWarnings?.oneOf && { - contentWarnings: { - includeOneOf: filters.showPublicationsWithContentWarnings.oneOf, - }, - }), - }; -} diff --git a/packages/react-v1/src/publication/index.ts b/packages/react-v1/src/publication/index.ts deleted file mode 100644 index 089960cd58..0000000000 --- a/packages/react-v1/src/publication/index.ts +++ /dev/null @@ -1,171 +0,0 @@ -export * from './useComments'; -export * from './usePublication'; -export * from './usePublications'; -export * from './useSearchPublications'; -export * from './useExplorePublications'; -export * from './useReaction'; -export * from './useWhoReacted'; -export * from './useReportPublication'; -export * from './useHidePublication'; -export * from './useWhoCollectedPublication'; -export * from './useWhoMirroredPublication'; -export * from './useProfilePublicationsForSale'; -export * from './useEncryptedPublication'; -export * from './useNotInterested'; -export * from './useMyBookmarks'; -export * from './useBookmarkToggle'; - -/** - * Domain entities - */ -export { - DecryptionCriteriaType, - Erc20ComparisonOperator, - NftContractType, -} from '@lens-protocol/domain/entities'; - -export type { - AddressOwnershipCriterion, - AndCriterion, - AnyCriterion, - CollectPublicationCriterion, - CollectThisPublicationCriterion, - DecryptionCriteria, - Erc20OwnershipCriterion, - FollowProfileCriterion, - NftOwnershipCriterion, - OrCriterion, - ProfileOwnershipCriterion, - SimpleCriterion, -} from '@lens-protocol/domain/entities'; - -/** - * Collect policy - */ -export type { - AaveFeeCollectPolicy, - CollectPolicy, - FeeCollectPolicy, - LimitedFeeCollectPolicy, - LimitedTimedFeeCollectPolicy, - MultirecipientFeeCollectPolicy, - NoCollectPolicy, - NoFeeCollectPolicy, - TimedFeeCollectPolicy, - VaultFeeCollectPolicy, -} from '@lens-protocol/api-bindings'; - -export type { - AaveFeeCollectModuleSettings, - Erc4626FeeCollectModuleSettings, - FeeCollectModuleSettings, - FreeCollectModuleSettings, - LimitedFeeCollectModuleSettings, - LimitedTimedFeeCollectModuleSettings, - MultirecipientFeeCollectModuleSettings, - RevertCollectModuleSettings, - SimpleCollectModuleSettings, - TimedFeeCollectModuleSettings, - UnknownCollectModuleSettings, -} from '@lens-protocol/api-bindings'; - -/** - * Reference policy - */ -export type { - ReferencePolicy, - FollowersOnlyPolicy, - UnknownPolicy, - DegreesOfSeparationPolicy, - AnyonePolicy, -} from '@lens-protocol/api-bindings'; - -export type { - DegreesOfSeparationReferenceModuleSettings, - FollowOnlyReferenceModuleSettings, - UnknownReferenceModuleSettings, -} from '@lens-protocol/api-bindings'; - -/** - * Other request models related - */ -export type { ReportPublicationRequest } from '@lens-protocol/domain/use-cases/publications'; - -/** - * Publication fragments - */ -export type { - AnyPublication, - Collectable, - CollectableComment, - CollectableMirror, - CollectablePost, - CollectablePublication, - Comment, - CommentBase, - ContentPublication, - Gated, - GatedComment, - GatedPost, - GatedPublication, - Media, - MetadataAttributeOutput, - MetadataOutput, - Mirror, - MirrorBase, - PendingPost, - Post, - ProfileCoverSet, - ProfilePictureSet, - PublicationMediaSet, - PublicationOwnedByMe, - PublicationStats, - RevenueAggregate, - WhoReactedResult, -} from '@lens-protocol/api-bindings'; - -/** - * Gated publication specific fragments - */ -export type { - AndConditionOutput, - AnyConditionOutput, - CollectConditionOutput, - ContentEncryptionKey, - ContractType, - EncryptedFieldsOutput, - EncryptedMedia, - EncryptionParamsOutput, - EncryptionProvider, - EoaOwnershipOutput, - Erc20OwnershipOutput, - FollowConditionOutput, - LeafConditionOutput, - NftOwnershipOutput, - OrConditionOutput, - ProfileOwnershipOutput, - RootConditionOutput, - ScalarOperator, -} from '@lens-protocol/api-bindings'; - -/** - * Helpers - */ -export { - CollectState, - CommentOrderingTypes, - CommentRankingFilter, - DecryptFailReason, - isCommentPublication, - isContentPublication, - isMirrorPublication, - isPostPublication, - isPublicationOwnedByMe, - PublicationContentWarning, - PublicationMainFocus, - PublicationSortCriteria, - PublicationTypes, - ReactionTypes, -} from '@lens-protocol/api-bindings'; - -export type { PublicationMetadataFilters } from './filters'; diff --git a/packages/react-v1/src/publication/useBookmarkToggle.ts b/packages/react-v1/src/publication/useBookmarkToggle.ts deleted file mode 100644 index 2e988234d0..0000000000 --- a/packages/react-v1/src/publication/useBookmarkToggle.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { AnyPublication, ProfileOwnedByMe, isMirrorPublication } from '@lens-protocol/api-bindings'; -import { invariant, success } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useBookmarkToggleController } from './adapters/useBookmarkToggleController'; - -export type UseBookmarkToggleArgs = { - profile: ProfileOwnedByMe; - publication: AnyPublication; -}; - -export type BookmarkOperation = Operation; - -/** - * `useBookmarkToggle` hook lets the user save or remove a publication from their bookmarks. - * - * You MUST be authenticated via {@link useWalletLogin} to use this hook. - * - * You can use the `Post.bookmarked` (or `Comment.bookmarked`) property to determine - * if the publication is bookmarked by the current observer. - * - * The `profile` argument MUST be the {@link ProfileOwnedByMe} instance that was used as observer when the publication got fetched. - * For the vast majority of the users this corresponds to the Profile returned by the {@link useActiveProfile} hook. - * - * In the rare occasions you provided an `observerId` to the hook used to fetch the publication, then you MUST provide - * the corresponding profile here. The profile MUST be owned by the authenticated wallet (i.e. instance of {@link ProfileOwnedByMe}). - * - * @category Publications - * @group Hooks - * @param args - {@link UseBookmarkToggleArgs} - * - * @example - * ```tsx - * import { AnyPublication, ProfileOwnedByMe, useBookmarkToggle } from '@lens-protocol/react-web'; - * - * function Publication({ profile, publication }: { profile: ProfileOwnedByMe, publication: AnyPublication }) { - * const { execute: toggle, isPending } = useBookmarkToggle({ profile, publication }); - * - * return ( - * - * ); - * } - * ``` - */ -export function useBookmarkToggle({ - publication, - profile, -}: UseBookmarkToggleArgs): BookmarkOperation { - const { add, remove } = useBookmarkToggleController(); - - const target = isMirrorPublication(publication) ? publication.mirrorOf : publication; - - invariant( - profile.ownedByMe, - `The provided 'profile' is not owned by the authenticated wallet.\n` + - `Use the 'useActiveProfile' or 'useProfilesOwnedByMe' hooks to get a 'ProfileOwnedByMe' instance.`, - ); - - invariant( - profile.id === target.observedBy, - `${publication.__typename}[ID:${publication.id}] was not fetched using Profile[ID:${profile.id}] as observer.\n` + - `If you didn't provide an explicit 'observerId' when fetching the publication,\n` + - `then you are likely just need to provide the current Active Profile returned by the 'useActiveProfile' hook.\n` + - `Otherwise, you MUST provide the Profile that was used as observer when fetching the publication.`, - ); - - return useOperation(async () => { - if (target.bookmarked) { - await remove({ - publicationId: target.id, - profileId: profile.id, - }); - } else { - await add({ - publicationId: target.id, - profileId: profile.id, - }); - } - - return success(); - }); -} diff --git a/packages/react-v1/src/publication/useComments.ts b/packages/react-v1/src/publication/useComments.ts deleted file mode 100644 index 383ee36b66..0000000000 --- a/packages/react-v1/src/publication/useComments.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { - Comment, - CommentOrderingTypes, - CommentRankingFilter, - useGetComments, -} from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; -import { XOR } from '@lens-protocol/shared-kernel'; - -import { - WithObserverIdOverride, - useActiveProfileAsDefaultObserver, - useSourcesFromConfig, - useLensApolloClient, - useMediaTransformFromConfig, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; -import { createPublicationMetadataFilters, PublicationMetadataFilters } from './filters'; - -export type UseCommentsArgs = PaginatedArgs< - WithObserverIdOverride< - { - commentsOf: PublicationId; - metadataFilter?: PublicationMetadataFilters; - } & XOR< - { - commentsOfOrdering: CommentOrderingTypes.Ranking; - commentsRankingFilter: CommentRankingFilter; - }, - { - commentsOfOrdering?: CommentOrderingTypes.Desc; - } - > - > ->; - -/** - * @category Publications - * @group Hooks - */ -export function useComments({ - metadataFilter, - commentsOf, - commentsOfOrdering = CommentOrderingTypes.Desc, - commentsRankingFilter, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - observerId, -}: UseCommentsArgs): PaginatedReadResult { - return usePaginatedReadResult( - useGetComments( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - metadata: createPublicationMetadataFilters(metadataFilter), - commentsOf, - commentsOfOrdering, - commentsRankingFilter, - limit, - observerId, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/publication/useEncryptedPublication.ts b/packages/react-v1/src/publication/useEncryptedPublication.ts deleted file mode 100644 index 98165895f0..0000000000 --- a/packages/react-v1/src/publication/useEncryptedPublication.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { - ContentPublication, - isGatedPublication, - MetadataOutput, - UnspecifiedError, -} from '@lens-protocol/api-bindings'; -import { failure, invariant, PromiseResult, success } from '@lens-protocol/shared-kernel'; -import { useCallback, useEffect, useMemo, useState } from 'react'; - -import { EncryptionConfig } from '../config'; -import { Operation, useOperation } from '../helpers/operations'; -import { useSharedDependencies } from '../shared'; -import { createGatedClient } from '../transactions/infrastructure/createGatedClient'; -import { useActiveWalletSigner } from '../wallet'; - -export type UseEncryptedPublicationArgs = { - encryption: EncryptionConfig; - publication: T; -}; - -export class DecryptionError extends Error { - name = 'DecryptionError' as const; - - constructor(public readonly message: string) { - super(message); - } -} - -export type UseEncryptedPublicationError = DecryptionError | UnspecifiedError; - -export type UseEncryptedPublicationResult = { - data: T; - decrypt: () => void; - error?: UseEncryptedPublicationError; - isPending: boolean; -}; - -function updateMetadata(publication: T, metadata: MetadataOutput) { - return Object.assign({}, publication, { metadata }); -} - -/** - * @category Publications - * @group Hooks - */ -export function useEncryptedPublication({ - encryption, - publication, -}: UseEncryptedPublicationArgs): UseEncryptedPublicationResult { - const [shouldDecrypt, signalDecryptionIntent] = useState(false); - const [metadata, setMetadata] = useState(publication.metadata); - - // Although publication Metadata is to be considered immutable, - // there are other things that can change (e.g. the publication could be deleted). - // useMemo keeps the immutability paradigm of Apollo Normalized Cache objects so no - // unnecessary downstream re-renderings are triggered. - const data = useMemo(() => updateMetadata(publication, metadata), [publication, metadata]); - - const { environment, storageProvider } = useSharedDependencies(); - - const { data: signer } = useActiveWalletSigner(); - - const { error, execute, isPending }: Operation = useOperation( - useCallback(async (): PromiseResult => { - invariant(isGatedPublication(publication), 'Publication is not gated'); - invariant(signer, `Cannot find the Active Wallet Signer`); - - if (!publication.canObserverDecrypt.result) { - return failure( - new DecryptionError( - `Publication cannot be decrypted by the observer because: ${ - publication.canObserverDecrypt.reasons?.join(', ') ?? 'unknown reason(s)' - })}. Make sure to check if canObserverDecrypt.result is true before calling decrypt().`, - ), - ); - } - - const createGatedClientFn = encryption.createGatedClient || createGatedClient; - - const client = createGatedClientFn({ - config: encryption.authentication, - signer, - encryptionProvider: encryption.provider, - environment, - storageProvider, - }); - - const result = await client.decryptPublication( - publication.metadata, - publication.metadata.encryptionParams, - ); - - if (result.isFailure()) { - return failure(new UnspecifiedError(result.error)); - } - - setMetadata(result.value); - - return success(); - }, [ - encryption.createGatedClient, - encryption.authentication, - encryption.provider, - environment, - publication, - signer, - storageProvider, - ]), - ); - - useEffect(() => { - if (signer && isGatedPublication(publication) && shouldDecrypt) { - void execute(); - } - }, [shouldDecrypt, execute, publication, signer]); - - return { - isPending, - decrypt: () => { - signalDecryptionIntent(true); - }, - error, - data, - }; -} diff --git a/packages/react-v1/src/publication/useExplorePublications.ts b/packages/react-v1/src/publication/useExplorePublications.ts deleted file mode 100644 index 20ba6a7c00..0000000000 --- a/packages/react-v1/src/publication/useExplorePublications.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { - AnyPublication, - PublicationSortCriteria, - PublicationTypes, - useExplorePublications as useUnderlyingQuery, -} from '@lens-protocol/api-bindings'; -import { AppId, ProfileId } from '@lens-protocol/domain/entities'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; -import { createPublicationMetadataFilters, PublicationMetadataFilters } from './filters'; - -export type UseExplorePublicationsArgs = PaginatedArgs< - WithObserverIdOverride<{ - /** - * Exclude publications from these profiles - */ - excludeProfileIds?: ProfileId[]; - - /** - * Filter publications by metadata details - */ - metadataFilter?: PublicationMetadataFilters; - - /** - * Filter publications by type - * - * @defaultValue empty - all types - */ - publicationTypes?: Array; - - /** - * Sort criteria - */ - sortCriteria?: PublicationSortCriteria; - - /** - * Timestamp to start from - */ - timestamp?: number; - - /** - * If you want the randomizer off - * - * @defaultValue false - */ - noRandomize?: boolean; - - /** - * @defaultValue defaults to the value provided in {@link LensConfig} - */ - sources?: AppId[]; - }> ->; - -/** - * `useExplorePublications` is a paginated hook that lets you discover new publications base on a defined criteria - * - * @category Discovery - * @group Hooks - * @param args - {@link UseExplorePublicationsArgs} - * - * @example - * - * ```tsx - * import { PublicationSortCriteria, useExplorePublications } from '@lens-protocol/react-web'; - * - * function ExplorePublications() { - * const { data, error, loading } = useExplorePublications({ sortCriteria: PublicationSortCriteria.MostComments }); - * - * if (loading) return

Loading...

; - * - * if (error) return

Error: {error.message}

; - * - * return ( - *
    - * {data.map((publication) => ( - *
  • - * // render publication details - *
  • - * ))} - *
- * ); - * } - * ``` - */ -export function useExplorePublications({ - observerId, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - sortCriteria = PublicationSortCriteria.Latest, - timestamp, - noRandomize, - publicationTypes, - excludeProfileIds, - metadataFilter, - sources, -}: UseExplorePublicationsArgs = {}): PaginatedReadResult> { - return usePaginatedReadResult( - useUnderlyingQuery( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - excludeProfileIds, - limit, - metadata: createPublicationMetadataFilters(metadataFilter), - publicationTypes, - sortCriteria, - timestamp, - noRandomize, - observerId, - sources, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/publication/useHidePublication.ts b/packages/react-v1/src/publication/useHidePublication.ts deleted file mode 100644 index 389748fbe4..0000000000 --- a/packages/react-v1/src/publication/useHidePublication.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { PublicationOwnedByMe } from '@lens-protocol/api-bindings'; -import { invariant, success } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useHidePublicationController } from './adapters/useHidePublicationController'; - -export type UseHidePublicationArgs = { - publication: PublicationOwnedByMe; -}; - -export type HidePublicationOperation = Operation; - -/** - * @category Publications - * @group Hooks - */ -export function useHidePublication({ - publication, -}: UseHidePublicationArgs): HidePublicationOperation { - const hide = useHidePublicationController(); - - return useOperation(async () => { - invariant( - publication.profile.ownedByMe, - 'Publication not owned by the active wallet. Make sure that publication is owned by the wallet (for .e.g. by calling `isPublicationOwnedByMe`) before trying to hide it?', - ); - - await hide({ - publicationId: publication.id, - }); - return success(); - }); -} diff --git a/packages/react-v1/src/publication/useMyBookmarks.ts b/packages/react-v1/src/publication/useMyBookmarks.ts deleted file mode 100644 index 74440e0a9d..0000000000 --- a/packages/react-v1/src/publication/useMyBookmarks.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { - ContentPublication, - ProfileOwnedByMe, - useGetProfileBookmarks, -} from '@lens-protocol/api-bindings'; -import { invariant } from '@lens-protocol/shared-kernel'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; -import { PublicationMetadataFilters } from './filters'; - -export type UseMyBookmarksArgs = PaginatedArgs< - WithObserverIdOverride<{ - metadataFilter?: PublicationMetadataFilters; - /** - * The profile to fetch bookmarked publications for. - */ - profile: ProfileOwnedByMe; - }> ->; - -/** - * `useMyBookmarks` is a paginated hook that lets you fetch the bookmarks of a profile owned by the logged in wallet. - * - * You MUST be authenticated via {@link useWalletLogin} to use this hook. - * By default it will fetch the bookmarks of the Active Profile. - * - * @category Bookmarks - * @group Hooks - * @param args - {@link UseMyBookmarksArgs} - */ -export function useMyBookmarks({ - profile, - observerId, - metadataFilter, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, -}: UseMyBookmarksArgs): PaginatedReadResult { - invariant( - profile.ownedByMe, - `The provided 'profile' is not owned by the authenticated wallet.\n` + - `Use the 'useActiveProfile' or 'useProfilesOwnedByMe' hooks to get a 'ProfileOwnedByMe' instance.`, - ); - - return usePaginatedReadResult( - useGetProfileBookmarks( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - profileId: profile.id, - metadataFilter, - limit, - observerId, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/publication/useNotInterested.ts b/packages/react-v1/src/publication/useNotInterested.ts deleted file mode 100644 index 262d5ad1f5..0000000000 --- a/packages/react-v1/src/publication/useNotInterested.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { AnyPublication, ProfileOwnedByMe, isMirrorPublication } from '@lens-protocol/api-bindings'; -import { invariant, success } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useNotInterestedController } from './adapters/useNotInterestedController'; - -export type UseNotInterestedArgs = { - profile: ProfileOwnedByMe; - publication: AnyPublication; -}; - -export type NotInterestedOperation = Operation; - -/** - * `useNotInterested` hook let the user flag they are not interested in a publication. - * - * You MUST be authenticated via {@link useWalletLogin} to use this hook. - * - * You can use the `Post.notInterested` (or `Comment.notInterested`) property to determine - * the interest associated with the provided publication observer. - * - * The `profile` argument MUST be the {@link ProfileOwnedByMe} instance that was used as observer when the publication got fetched. - * For the vast majority of the users this corresponds to the Profile returned by the {@link useActiveProfile} hook. - * - * In the rare occasions you provided an `observerId` to the hook used to fetch the publication, then you MUST provide - * the corresponding profile here. The profile MUST be owned by the authenticated wallet (i.e. instance of {@link ProfileOwnedByMe}). - * - * @category Publications - * @group Hooks - * @param args - {@link UseNotInterestedArgs} - * - * @example - * ```tsx - * import { AnyPublication, ProfileOwnedByMe, useNotInterested } from '@lens-protocol/react-web'; - * - * function Publication({ profile, publication }: { profile: ProfileOwnedByMe, publication: AnyPublication }) { - * const { execute: toggle, isPending } = useNotInterested({ profile, publication }); - * - * return ( - * - * ); - * } - * ``` - */ -export function useNotInterested({ - publication, - profile, -}: UseNotInterestedArgs): NotInterestedOperation { - const { add, remove } = useNotInterestedController(); - - const target = isMirrorPublication(publication) ? publication.mirrorOf : publication; - - invariant( - profile.ownedByMe, - `The provided 'profile' is not owned by the authenticated wallet.\n` + - `Use the 'useActiveProfile' or 'useProfilesOwnedByMe' hooks to get a 'ProfileOwnedByMe' instance.`, - ); - - invariant( - profile.id === target.observedBy, - `${publication.__typename}[ID:${publication.id}] was not fetched using Profile[ID:${profile.id}] as observer.\n` + - `If you didn't provide an explicit 'observerId' when fetching the publication,\n` + - `then you are likely just need to provide the current Active Profile returned by the 'useActiveProfile' hook.\n` + - `Otherwise, you MUST provide the Profile that was used as observer when fetching the publication.`, - ); - - return useOperation(async () => { - if (target.notInterested) { - await remove({ - publicationId: target.id, - profileId: profile.id, - }); - } else { - await add({ - publicationId: target.id, - profileId: profile.id, - }); - } - - return success(); - }); -} diff --git a/packages/react-v1/src/publication/useProfilePublicationsForSale.ts b/packages/react-v1/src/publication/useProfilePublicationsForSale.ts deleted file mode 100644 index 2bb2bd9dbd..0000000000 --- a/packages/react-v1/src/publication/useProfilePublicationsForSale.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - AnyPublication, - useProfilePublicationsForSale as useUnderlyingQuery, -} from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseProfilePublicationsForSaleArgs = PaginatedArgs< - WithObserverIdOverride<{ - profileId: ProfileId; - }> ->; - -/** - * @category Publications - * @group Hooks - */ -export function useProfilePublicationsForSale({ - profileId, - observerId, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, -}: UseProfilePublicationsForSaleArgs): PaginatedReadResult { - return usePaginatedReadResult( - useUnderlyingQuery( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - profileId, - observerId, - limit, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/publication/usePublication.ts b/packages/react-v1/src/publication/usePublication.ts deleted file mode 100644 index e42100c10b..0000000000 --- a/packages/react-v1/src/publication/usePublication.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { AnyPublication, UnspecifiedError, useGetPublication } from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; - -import { NotFoundError } from '../NotFoundError'; -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { ReadResult, useReadResult } from '../helpers/reads'; - -export type UsePublicationArgs = WithObserverIdOverride<{ - publicationId: PublicationId; -}>; - -/** - * @category Publications - * @group Hooks - */ -export function usePublication({ - publicationId, - observerId, -}: UsePublicationArgs): ReadResult { - const { data, error, loading } = useReadResult( - useGetPublication( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - request: { - publicationId, - }, - observerId, - }), - ), - fetchPolicy: 'cache-and-network', - nextFetchPolicy: 'cache-first', - }), - ), - ), - ); - - if (loading) { - return { - data: undefined, - error: undefined, - loading: true, - }; - } - - if (error) { - return { - data: undefined, - error, - loading: false, - }; - } - - if (data === null) { - return { - data: undefined, - error: new NotFoundError(`Publication with id: ${publicationId}`), - loading: false, - }; - } - - return { - data, - error: undefined, - loading: false, - }; -} diff --git a/packages/react-v1/src/publication/usePublications.ts b/packages/react-v1/src/publication/usePublications.ts deleted file mode 100644 index 0d1283b9a1..0000000000 --- a/packages/react-v1/src/publication/usePublications.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { AnyPublication, PublicationTypes, useGetPublications } from '@lens-protocol/api-bindings'; -import { ProfileId, PublicationId } from '@lens-protocol/domain/entities'; -import { OneOf, XOR } from '@lens-protocol/shared-kernel'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; -import { createPublicationMetadataFilters, PublicationMetadataFilters } from './filters'; - -export type UsePublicationsArgs = PaginatedArgs< - WithObserverIdOverride<{ - metadataFilter?: PublicationMetadataFilters; - }> & - XOR< - OneOf<{ profileId: ProfileId; profileIds: ProfileId[] }> & { - publicationTypes?: PublicationTypes[]; - }, - { publicationIds: PublicationId[] } - > ->; - -/** - * `usePublications` is a paginated hook that lets you fetch publications based on a set of filters. - * - * @category Publications - * @group Hooks - * - * @example - * Fetch publications by a Profile ID - * ```tsx - * const { data, loading, error } = usePublications({ - * profileId: profileId('0x0635') - * }); - * ``` - * - * @example - * Fetch publications by several Profile IDs - * ```tsx - * const { data, loading, error } = usePublications({ - * profileIds: [ profileId('0x0635'), profileId('0x0f') ] - * }); - * ``` - * - * @example - * Filter publications by type - * ```tsx - * const { data, loading, error } = usePublications({ - * profileId: profileId('0x0635') - * publicationTypes: [ PublicationTypes.Post ] - * }); - * ``` - */ -export function usePublications({ - metadataFilter, - observerId, - profileId, - profileIds, - publicationIds, - publicationTypes, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, -}: UsePublicationsArgs): PaginatedReadResult { - return usePaginatedReadResult( - useGetPublications( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - limit, - metadata: createPublicationMetadataFilters(metadataFilter), - observerId, - profileId, - profileIds, - publicationIds, - publicationTypes, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/publication/useReaction.ts b/packages/react-v1/src/publication/useReaction.ts deleted file mode 100644 index 17aca02f02..0000000000 --- a/packages/react-v1/src/publication/useReaction.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { ContentPublication, ReactionTypes } from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { useState } from 'react'; - -import { ReactionType } from '../deprecated'; -import { useReactionController } from './adapters/useReactionController'; - -export type UseReactionArgs = { - profileId: ProfileId; -}; - -export type ReactionArgs = { - publication: ContentPublication; - reactionType: ReactionTypes | ReactionType; -}; - -/** - * @category Publications - * @group Hooks - */ -export function useReaction({ profileId }: UseReactionArgs) { - const [isPending, setIsPending] = useState(false); - const { add, remove } = useReactionController(); - - const addReaction = async (args: ReactionArgs) => { - setIsPending(true); - - try { - await add({ - publicationId: args.publication.id, - reactionType: args.reactionType as ReactionTypes, - existingReactionType: args.publication.reaction, - profileId, - }); - } finally { - setIsPending(false); - } - }; - - const removeReaction = async (args: ReactionArgs) => { - setIsPending(true); - - try { - await remove({ - publicationId: args.publication.id, - reactionType: args.reactionType as ReactionTypes, - profileId, - }); - } finally { - setIsPending(false); - } - }; - - const hasReaction = ({ publication, reactionType }: ReactionArgs) => { - return publication.reaction === reactionType; - }; - - return { - addReaction, - removeReaction, - hasReaction, - isPending, - }; -} diff --git a/packages/react-v1/src/publication/useReportPublication.ts b/packages/react-v1/src/publication/useReportPublication.ts deleted file mode 100644 index 09f2cbe853..0000000000 --- a/packages/react-v1/src/publication/useReportPublication.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Comment, Mirror, Post } from '@lens-protocol/api-bindings'; -import { ReportReason } from '@lens-protocol/domain/entities'; -import { ReportPublicationRequest } from '@lens-protocol/domain/use-cases/publications'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useReportPublicationController } from './adapters/useReportPublicationController'; - -export { ReportReason }; - -export type UseReportPublicationArgs = { - publication: Comment | Mirror | Post; -}; - -export type ReportPublicationArgs = Pick; - -export type ReportPublicationOperation = Operation; - -/** - * @category Publications - * @group Hooks - */ -export function useReportPublication({ - publication, -}: UseReportPublicationArgs): ReportPublicationOperation { - const reportPublication = useReportPublicationController(); - - return useOperation(async ({ additionalComments, reason }: ReportPublicationArgs) => - reportPublication({ - additionalComments, - reason, - publicationId: publication.id, - }), - ); -} diff --git a/packages/react-v1/src/publication/useSearchPublications.ts b/packages/react-v1/src/publication/useSearchPublications.ts deleted file mode 100644 index 07bb944a95..0000000000 --- a/packages/react-v1/src/publication/useSearchPublications.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { - ContentPublication, - useSearchPublications as useUnderlyingQuery, -} from '@lens-protocol/api-bindings'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseSearchPublicationsArgs = PaginatedArgs< - WithObserverIdOverride<{ - /** - * Search query - */ - query: string; - }> ->; - -/** - * `useSearchPublications` is a paginated hook that lets you search for publications based on a defined criteria - * - * @category Discovery - * @group Hooks - * @param args - {@link UseSearchPublicationsArgs} - * - * @example - * ```tsx - * import { useSearchPublications } from '@lens-protocol/react-web'; - * - * function SearchPublication() { - * const { data, error, loading } = useSearchPublications({ query: 'foo' }); - * - * if (loading) return

Loading...

; - * - * if (error) return

Error: {error.message}

; - * - * return ( - *
    - * {data.map((publication) => ( - *
  • - * // render publication details - *
  • - * ))} - *
- * ); - * } - * ``` - */ -export function useSearchPublications({ - query, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - observerId, -}: UseSearchPublicationsArgs): PaginatedReadResult { - return usePaginatedReadResult( - useUnderlyingQuery( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - query, - limit, - observerId, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/publication/useWhoCollectedPublication.ts b/packages/react-v1/src/publication/useWhoCollectedPublication.ts deleted file mode 100644 index 42c800ca7b..0000000000 --- a/packages/react-v1/src/publication/useWhoCollectedPublication.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - useWhoCollectedPublication as useUnderlyingQuery, - Wallet, -} from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedReadResult, PaginatedArgs, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseWhoCollectedPublicationArgs = PaginatedArgs< - WithObserverIdOverride<{ - publicationId: PublicationId; - }> ->; - -/** - * @category Publications - * @group Hooks - */ -export function useWhoCollectedPublication({ - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - observerId, - publicationId, -}: UseWhoCollectedPublicationArgs): PaginatedReadResult { - return usePaginatedReadResult( - useUnderlyingQuery( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ limit, publicationId, observerId }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/publication/useWhoMirroredPublication.ts b/packages/react-v1/src/publication/useWhoMirroredPublication.ts deleted file mode 100644 index a1b4625f16..0000000000 --- a/packages/react-v1/src/publication/useWhoMirroredPublication.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Profile, useGetAllProfiles } from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseWhoMirroredPublicationArgs = PaginatedArgs< - WithObserverIdOverride<{ - limit?: number; - publicationId: PublicationId; - }> ->; - -/** - * @category Publications - * @group Hooks - */ -export function useWhoMirroredPublication({ - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - publicationId, - observerId, -}: UseWhoMirroredPublicationArgs): PaginatedReadResult { - return usePaginatedReadResult( - useGetAllProfiles( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - byWhoMirroredPublicationId: publicationId, - observerId, - limit, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/publication/useWhoReacted.ts b/packages/react-v1/src/publication/useWhoReacted.ts deleted file mode 100644 index 045bb7d19f..0000000000 --- a/packages/react-v1/src/publication/useWhoReacted.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { WhoReactedResult, useWhoReactedPublication } from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedReadResult, PaginatedArgs, usePaginatedReadResult } from '../helpers/reads'; - -export type UseWhoReactedArgs = PaginatedArgs< - WithObserverIdOverride<{ - publicationId: PublicationId; - }> ->; - -/** - * @category Publications - * @group Hooks - */ -export function useWhoReacted(args: UseWhoReactedArgs): PaginatedReadResult { - return usePaginatedReadResult( - useWhoReactedPublication( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - publicationId: args.publicationId, - observerId: args?.observerId, - limit: args?.limit ?? 10, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/revenue/__tests__/useProfileFollowRevenue.spec.ts b/packages/react-v1/src/revenue/__tests__/useProfileFollowRevenue.spec.ts deleted file mode 100644 index edce9622ba..0000000000 --- a/packages/react-v1/src/revenue/__tests__/useProfileFollowRevenue.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - mockLensApolloClient, - mockProfileFollowRevenueResponse, - mockProfileFollowRevenueFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { mockProfileId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { useProfileFollowRevenue } from '../useProfileFollowRevenue'; - -describe(`Given the ${useProfileFollowRevenue.name} hook`, () => { - describe('when the query returns data successfully', () => { - const profileId = mockProfileId(); - - const mockRevenues = mockProfileFollowRevenueFragment(); - - it(`should return the revenue generated by the profile's following`, async () => { - const { result } = renderHookWithMocks(() => useProfileFollowRevenue({ profileId }), { - mocks: { - apolloClient: mockLensApolloClient([ - mockProfileFollowRevenueResponse({ - variables: { profileId }, - revenues: mockRevenues, - }), - ]), - }, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toEqual(mockRevenues.revenues); - }); - }); -}); diff --git a/packages/react-v1/src/revenue/__tests__/useProfilePublicationRevenue.spec.ts b/packages/react-v1/src/revenue/__tests__/useProfilePublicationRevenue.spec.ts deleted file mode 100644 index 54537720fc..0000000000 --- a/packages/react-v1/src/revenue/__tests__/useProfilePublicationRevenue.spec.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { PublicationRevenue } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockGetProfilePublicationRevenueResponse, - mockPublicationRevenueFragment, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { - useProfilePublicationRevenue, - UseProfilePublicationRevenueArgs, -} from '../useProfilePublicationRevenue'; - -function setupTestScenario({ - expectedObserverId, - result, - ...args -}: UseProfilePublicationRevenueArgs & { - expectedObserverId?: ProfileId; - result: PublicationRevenue[]; -}) { - const sources = mockSources(); - - return renderHookWithMocks(() => useProfilePublicationRevenue(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockGetProfilePublicationRevenueResponse({ - variables: { - ...args, - observerId: expectedObserverId ?? null, - limit: 10, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - items: result, - }), - ]), - }, - }); -} - -describe(`Given the ${useProfilePublicationRevenue.name} hook`, () => { - const profileId = mockProfileId(); - const revenues = [mockPublicationRevenueFragment()]; - const expectations = revenues.map(({ __typename }) => ({ __typename })); - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe('when the query returns data successfully', () => { - it('should return all publications with revenue', async () => { - const { result } = setupTestScenario({ profileId, result: revenues }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); - - describe('when there is an Active Profile defined', () => { - const activeProfile = mockProfile(); - - beforeAll(() => { - simulateAuthenticatedProfile(activeProfile); - }); - - it('should use the Active Profile Id as the "observerId"', async () => { - const { result } = setupTestScenario({ - profileId, - result: revenues, - expectedObserverId: activeProfile.id, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to override the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - profileId, - result: revenues, - observerId, - expectedObserverId: observerId, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - }); -}); diff --git a/packages/react-v1/src/revenue/__tests__/usePublicationRevenue.spec.ts b/packages/react-v1/src/revenue/__tests__/usePublicationRevenue.spec.ts deleted file mode 100644 index 1914f8c345..0000000000 --- a/packages/react-v1/src/revenue/__tests__/usePublicationRevenue.spec.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { PublicationRevenue } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockGetPublicationRevenueResponse, - mockPublicationRevenueFragment, - mockSources, - simulateAuthenticatedProfile, - simulateNotAuthenticated, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId, mockPublicationId } from '@lens-protocol/domain/mocks'; -import { waitFor } from '@testing-library/react'; - -import { NotFoundError } from '../../NotFoundError'; -import { renderHookWithMocks } from '../../__helpers__/testing-library'; -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { usePublicationRevenue, UsePublicationRevenueArgs } from '../usePublicationRevenue'; - -function setupTestScenario({ - expectedObserverId, - result, - ...args -}: UsePublicationRevenueArgs & { - expectedObserverId?: ProfileId; - result: PublicationRevenue | null; -}) { - const sources = mockSources(); - - return renderHookWithMocks(() => usePublicationRevenue(args), { - mocks: { - sources, - mediaTransforms: defaultMediaTransformsConfig, - apolloClient: mockLensApolloClient([ - mockGetPublicationRevenueResponse({ - variables: { - ...args, - observerId: expectedObserverId ?? null, - sources, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - revenue: result, - }), - ]), - }, - }); -} - -describe(`Given the ${usePublicationRevenue.name} hook`, () => { - const revenue = mockPublicationRevenueFragment(); - const publicationId = mockPublicationId(); - const expectations = { __typename: revenue.__typename }; - - beforeAll(() => { - simulateNotAuthenticated(); - }); - - describe.each([ - { - description: 'when NO Active Profile is set', - activeProfileValue: null, - }, - { - description: 'when an Active Profile is set', - activeProfileValue: mockProfile(), - }, - ])('$description', ({ activeProfileValue }) => { - beforeAll(() => { - if (activeProfileValue) { - simulateAuthenticatedProfile(activeProfileValue); - } - }); - - it('should settle with the publication revenue details', async () => { - const { result } = setupTestScenario({ - observerId: activeProfileValue?.id, - expectedObserverId: activeProfileValue?.id, - publicationId, - result: revenue, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it('should allow to specify the "observerId" on a per-call basis', async () => { - const observerId = mockProfileId(); - - const { result } = setupTestScenario({ - observerId: observerId, - expectedObserverId: observerId, - publicationId, - result: revenue, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.data).toMatchObject(expectations); - }); - - it(`should settle with a ${NotFoundError.name} if not found`, async () => { - const { result } = setupTestScenario({ - publicationId, - expectedObserverId: activeProfileValue?.id, - result: null, - }); - - await waitFor(() => expect(result.current.loading).toBeFalsy()); - expect(result.current.error).toBeInstanceOf(NotFoundError); - }); - }); -}); diff --git a/packages/react-v1/src/revenue/index.ts b/packages/react-v1/src/revenue/index.ts deleted file mode 100644 index 502e50791c..0000000000 --- a/packages/react-v1/src/revenue/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './useProfileFollowRevenue'; -export * from './usePublicationRevenue'; -export * from './useProfilePublicationRevenue'; - -export type { PublicationRevenue } from '@lens-protocol/api-bindings'; diff --git a/packages/react-v1/src/revenue/useProfileFollowRevenue.ts b/packages/react-v1/src/revenue/useProfileFollowRevenue.ts deleted file mode 100644 index 09a20b7ec2..0000000000 --- a/packages/react-v1/src/revenue/useProfileFollowRevenue.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { - RevenueAggregate, - useProfileFollowRevenue as useUnderlyingQuery, -} from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; - -import { useLensApolloClient } from '../helpers/arguments'; -import { ReadResult, useReadResult } from '../helpers/reads'; - -export type UseProfileFollowRevenueArgs = { - profileId: ProfileId; -}; - -/** - * @category Revenues - * @group Hooks - */ -export function useProfileFollowRevenue({ - profileId, -}: UseProfileFollowRevenueArgs): ReadResult { - const { data, error, loading } = useReadResult( - useUnderlyingQuery( - useLensApolloClient({ - variables: { - profileId, - }, - }), - ), - ); - - if (loading) { - return { - data: undefined, - error: undefined, - loading: true, - }; - } - - if (error) { - return { - data: undefined, - error: error, - loading: false, - }; - } - - return { - data: data.revenues, - error: undefined, - loading: false, - }; -} diff --git a/packages/react-v1/src/revenue/useProfilePublicationRevenue.ts b/packages/react-v1/src/revenue/useProfilePublicationRevenue.ts deleted file mode 100644 index ec909f3a63..0000000000 --- a/packages/react-v1/src/revenue/useProfilePublicationRevenue.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - PublicationRevenue, - PublicationTypes, - useGetProfilePublicationRevenue, -} from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; - -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads'; -import { DEFAULT_PAGINATED_QUERY_LIMIT } from '../utils'; - -export type UseProfilePublicationRevenueArgs = PaginatedArgs< - WithObserverIdOverride<{ - profileId: ProfileId; - publicationTypes?: PublicationTypes[]; - }> ->; - -/** - * @category Revenues - * @group Hooks - */ -export function useProfilePublicationRevenue({ - profileId, - observerId, - limit = DEFAULT_PAGINATED_QUERY_LIMIT, - publicationTypes, -}: UseProfilePublicationRevenueArgs): PaginatedReadResult { - return usePaginatedReadResult( - useGetProfilePublicationRevenue( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - limit, - publicationTypes, - observerId, - profileId, - }), - ), - }), - ), - ), - ); -} diff --git a/packages/react-v1/src/revenue/usePublicationRevenue.ts b/packages/react-v1/src/revenue/usePublicationRevenue.ts deleted file mode 100644 index 00b79eebd4..0000000000 --- a/packages/react-v1/src/revenue/usePublicationRevenue.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { - UnspecifiedError, - PublicationRevenue, - useGetPublicationRevenue, -} from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; - -import { NotFoundError } from '../NotFoundError'; -import { - useActiveProfileAsDefaultObserver, - useLensApolloClient, - useMediaTransformFromConfig, - useSourcesFromConfig, - WithObserverIdOverride, -} from '../helpers/arguments'; -import { ReadResult, useReadResult } from '../helpers/reads'; - -export type UsePublicationRevenueArgs = WithObserverIdOverride<{ - publicationId: PublicationId; -}>; - -/** - * @category Revenues - * @group Hooks - */ -export function usePublicationRevenue({ - publicationId, - observerId, -}: UsePublicationRevenueArgs): ReadResult { - const { data, error, loading } = useReadResult( - useGetPublicationRevenue( - useLensApolloClient( - useActiveProfileAsDefaultObserver({ - variables: useMediaTransformFromConfig( - useSourcesFromConfig({ - publicationId, - observerId, - }), - ), - }), - ), - ), - ); - - if (loading) { - return { - data: undefined, - error: undefined, - loading: true, - }; - } - - if (error) { - return { - data: undefined, - error, - loading: false, - }; - } - - if (data === null) { - return { - data: undefined, - error: new NotFoundError(`Publication with id: ${publicationId}`), - loading: false, - }; - } - - return { - data, - error: undefined, - loading: false, - }; -} diff --git a/packages/react-v1/src/shared.tsx b/packages/react-v1/src/shared.tsx deleted file mode 100644 index 54bcbd66d8..0000000000 --- a/packages/react-v1/src/shared.tsx +++ /dev/null @@ -1,301 +0,0 @@ -import { - createAuthApolloClient, - createLensApolloClient, - SafeApolloClient, - Sources, -} from '@lens-protocol/api-bindings'; -import { AppId, TransactionKind } from '@lens-protocol/domain/entities'; -import { - AnyTransactionRequest, - TransactionQueue, - TransactionResponders, -} from '@lens-protocol/domain/use-cases/transactions'; -import { - ActiveWallet, - TokenAvailability, - WalletLogout, -} from '@lens-protocol/domain/use-cases/wallets'; -import { ILogger, invariant } from '@lens-protocol/shared-kernel'; -import { IStorage, IStorageProvider } from '@lens-protocol/storage'; -import React, { ReactNode, useContext } from 'react'; - -import { ConsoleLogger } from './ConsoleLogger'; -import { ErrorHandler } from './ErrorHandler'; -import { IBindings, LensConfig } from './config'; -import { EnvironmentConfig } from './environments'; -import { DisableConversationsGateway } from './inbox/adapters/DisableConversationsGateway'; -import { createInboxKeyStorage } from './inbox/infrastructure/InboxKeyStorage'; -import { LogoutHandler, SessionPresenter } from './lifecycle/adapters/SessionPresenter'; -import { defaultMediaTransformsConfig, MediaTransformsConfig } from './mediaTransforms'; -import { ActiveProfileGateway } from './profile/adapters/ActiveProfileGateway'; -import { ProfileGateway } from './profile/adapters/ProfileGateway'; -import { createActiveProfileStorage } from './profile/infrastructure/ActiveProfileStorage'; -import { FollowPolicyCallGateway } from './transactions/adapters/FollowPolicyCallGateway'; -import { OffChainRelayer } from './transactions/adapters/OffChainRelayer'; -import { OnChainRelayer } from './transactions/adapters/OnChainRelayer'; -import { PendingTransactionGateway } from './transactions/adapters/PendingTransactionGateway'; -import { PublicationCacheManager } from './transactions/adapters/PublicationCacheManager'; -import { - FailedTransactionError, - TransactionQueuePresenter, -} from './transactions/adapters/TransactionQueuePresenter'; -import { CollectPublicationResponder } from './transactions/adapters/responders/CollectPublicationResponder'; -import { CreateMirrorResponder } from './transactions/adapters/responders/CreateMirrorResponder'; -import { CreatePostResponder } from './transactions/adapters/responders/CreatePostResponder'; -import { CreateProfileResponder } from './transactions/adapters/responders/CreateProfileResponder'; -import { FollowProfilesResponder } from './transactions/adapters/responders/FollowProfilesResponder'; -import { NoopResponder } from './transactions/adapters/responders/NoopResponder'; -import { UnfollowProfileResponder } from './transactions/adapters/responders/UnfollowProfileResponder'; -import { UpdateDispatcherConfigResponder } from './transactions/adapters/responders/UpdateDispatcherConfigResponder'; -import { UpdateFollowPolicyResponder } from './transactions/adapters/responders/UpdateFollowPolicyResponder'; -import { UpdateProfileImageResponder } from './transactions/adapters/responders/UpdateProfileImageResponder'; -import { UpdateProfileMetadataResponder } from './transactions/adapters/responders/UpdateProfileMetadataResponder'; -import { ProfileCacheManager } from './transactions/infrastructure/ProfileCacheManager'; -import { TransactionFactory } from './transactions/infrastructure/TransactionFactory'; -import { TransactionObserver } from './transactions/infrastructure/TransactionObserver'; -import { createTransactionStorage } from './transactions/infrastructure/TransactionStorage'; -import { BalanceGateway } from './wallet/adapters/BalanceGateway'; -import { CredentialsExpiryController } from './wallet/adapters/CredentialsExpiryController'; -import { CredentialsFactory } from './wallet/adapters/CredentialsFactory'; -import { CredentialsGateway } from './wallet/adapters/CredentialsGateway'; -import { TokenGateway } from './wallet/adapters/TokenGateway'; -import { WalletFactory } from './wallet/adapters/WalletFactory'; -import { WalletGateway } from './wallet/adapters/WalletGateway'; -import { AccessTokenStorage } from './wallet/infrastructure/AccessTokenStorage'; -import { AuthApi } from './wallet/infrastructure/AuthApi'; -import { CredentialsStorage } from './wallet/infrastructure/CredentialsStorage'; -import { - createNotificationStorage, - UnreadNotificationsData, -} from './wallet/infrastructure/NotificationStorage'; -import { ProviderFactory } from './wallet/infrastructure/ProviderFactory'; -import { SignerFactory } from './wallet/infrastructure/SignerFactory'; -import { createWalletStorage } from './wallet/infrastructure/WalletStorage'; - -export type Handlers = { - onLogout: LogoutHandler; - onError: ErrorHandler; -}; - -export type SharedDependencies = { - accessTokenStorage: AccessTokenStorage; - activeProfileGateway: ActiveProfileGateway; - activeWallet: ActiveWallet; - apolloClient: SafeApolloClient; - appId?: AppId; - bindings: IBindings; - credentialsFactory: CredentialsFactory; - credentialsGateway: CredentialsGateway; - environment: EnvironmentConfig; - followPolicyCallGateway: FollowPolicyCallGateway; - inboxKeyStorage: IStorage; - logger: ILogger; - mediaTransforms: MediaTransformsConfig; - notificationStorage: IStorage; - offChainRelayer: OffChainRelayer; - onChainRelayer: OnChainRelayer; - onError: Handlers['onError']; - profileCacheManager: ProfileCacheManager; - profileGateway: ProfileGateway; - providerFactory: ProviderFactory; - publicationCacheManager: PublicationCacheManager; - sessionPresenter: SessionPresenter; - sources: Sources; - storageProvider: IStorageProvider; - tokenAvailability: TokenAvailability; - transactionFactory: TransactionFactory; - transactionGateway: PendingTransactionGateway; - transactionQueue: TransactionQueue; - walletLogout: WalletLogout; - walletFactory: WalletFactory; - walletGateway: WalletGateway; -}; - -export function createSharedDependencies( - config: LensConfig, - { onLogout, onError }: Handlers, -): SharedDependencies { - const sources = (config.sources as Sources) ?? []; - const logger = config.logger ?? new ConsoleLogger(); - const mediaTransforms = config.mediaTransforms ?? defaultMediaTransformsConfig; - - // storages - const activeProfileStorage = createActiveProfileStorage(config.storage, config.environment.name); - const credentialsStorage = new CredentialsStorage(config.storage, config.environment.name); - const walletStorage = createWalletStorage(config.storage, config.environment.name); - const notificationStorage = createNotificationStorage(config.storage, config.environment.name); - const transactionStorage = createTransactionStorage(config.storage, config.environment.name); - const inboxKeyStorage = createInboxKeyStorage(config.storage, config.environment.name); - - // apollo client - const anonymousApolloClient = createAuthApolloClient({ - backendURL: config.environment.backend, - logger, - }); - const authApi = new AuthApi(anonymousApolloClient); - const accessTokenStorage = new AccessTokenStorage(authApi, credentialsStorage); - const apolloClient = createLensApolloClient({ - backendURL: config.environment.backend, - accessTokenStorage, - pollingInterval: config.environment.timings.pollingInterval, - logger, - contentMatchers: [config.environment.snapshot.matcher], - }); - const publicationCacheManager = new PublicationCacheManager( - apolloClient, - sources, - mediaTransforms, - ); - const profileCacheManager = new ProfileCacheManager( - apolloClient, - sources, - mediaTransforms, - config.environment.handleResolver, - ); - - // adapters - const providerFactory = new ProviderFactory(config.bindings, config.environment.chains); - const transactionObserver = new TransactionObserver( - providerFactory, - apolloClient, - config.environment.timings, - ); - const transactionFactory = new TransactionFactory(transactionObserver); - const transactionGateway = new PendingTransactionGateway(transactionStorage, transactionFactory); - const signerFactory = new SignerFactory(config.bindings, config.environment.chains); - const credentialsFactory = new CredentialsFactory(authApi); - const credentialsGateway = new CredentialsGateway(credentialsStorage); - const walletFactory = new WalletFactory(signerFactory, transactionFactory); - const walletGateway = new WalletGateway(walletStorage, walletFactory); - const balanceGateway = new BalanceGateway(providerFactory); - const tokenGateway = new TokenGateway(providerFactory); - const followPolicyCallGateway = new FollowPolicyCallGateway(apolloClient); - - const profileGateway = new ProfileGateway(apolloClient, mediaTransforms); - const activeProfileGateway = new ActiveProfileGateway(activeProfileStorage); - const sessionPresenter = new SessionPresenter(onLogout); - - const responders: TransactionResponders = { - [TransactionKind.APPROVE_MODULE]: new NoopResponder(), - [TransactionKind.COLLECT_PUBLICATION]: new CollectPublicationResponder( - apolloClient, - sources, - mediaTransforms, - ), - [TransactionKind.CREATE_COMMENT]: new NoopResponder(), - [TransactionKind.CREATE_POST]: new CreatePostResponder( - profileCacheManager, - apolloClient, - sources, - mediaTransforms, - ), - [TransactionKind.CREATE_PROFILE]: new CreateProfileResponder(profileCacheManager), - [TransactionKind.FOLLOW_PROFILES]: new FollowProfilesResponder(apolloClient.cache), - [TransactionKind.MIRROR_PUBLICATION]: new CreateMirrorResponder( - apolloClient, - sources, - mediaTransforms, - ), - [TransactionKind.UNFOLLOW_PROFILE]: new UnfollowProfileResponder(apolloClient.cache), - [TransactionKind.UPDATE_DISPATCHER_CONFIG]: new UpdateDispatcherConfigResponder( - profileCacheManager, - ), - [TransactionKind.UPDATE_FOLLOW_POLICY]: new UpdateFollowPolicyResponder(profileCacheManager), - [TransactionKind.UPDATE_PROFILE_DETAILS]: new UpdateProfileMetadataResponder( - profileCacheManager, - ), - [TransactionKind.UPDATE_PROFILE_IMAGE]: new UpdateProfileImageResponder(profileCacheManager), - }; - const transactionQueuePresenter = new TransactionQueuePresenter(onError); - - const onChainRelayer = new OnChainRelayer(apolloClient, transactionFactory, logger); - const offChainRelayer = new OffChainRelayer(apolloClient, transactionFactory, logger); - - // common interactors - const activeWallet = new ActiveWallet(credentialsGateway, walletGateway); - const transactionQueue = TransactionQueue.create( - responders, - transactionGateway, - transactionQueuePresenter, - ); - const tokenAvailability = new TokenAvailability(balanceGateway, tokenGateway, activeWallet); - const conversationGateway = new DisableConversationsGateway(inboxKeyStorage); - const walletLogout = new WalletLogout( - walletGateway, - credentialsGateway, - activeWallet, - activeProfileGateway, - conversationGateway, - sessionPresenter, - ); - - // controllers - const credentialsExpiryController = new CredentialsExpiryController(walletLogout); - credentialsExpiryController.subscribe(accessTokenStorage); - - return { - accessTokenStorage, - activeProfileGateway, - activeWallet, - apolloClient, - appId: config.appId, - bindings: config.bindings, - credentialsFactory, - credentialsGateway, - environment: config.environment, - followPolicyCallGateway, - inboxKeyStorage, - logger, - mediaTransforms, - notificationStorage, - offChainRelayer, - onChainRelayer, - onError, - profileCacheManager, - profileGateway, - providerFactory, - publicationCacheManager, - sessionPresenter, - sources, - storageProvider: config.storage, - tokenAvailability, - transactionFactory, - transactionGateway, - transactionQueue, - walletLogout, - walletFactory, - walletGateway, - }; -} - -const SharedDependenciesContext = React.createContext(null); - -type SharedDependenciesProviderProps = { - children: ReactNode; - dependencies: SharedDependencies; -}; - -export function SharedDependenciesProvider({ - children, - dependencies: context, -}: SharedDependenciesProviderProps) { - return ( - - {children} - - ); -} - -/** - * @internal DO NOT USE THIS HOOK OUTSIDE OF THE LENS SDK - */ -export function useSharedDependencies(): SharedDependencies { - const context = useContext(SharedDependenciesContext); - - invariant( - context, - 'Could not find Lens SDK context, ensure your code is wrapped in a ', - ); - - return context; -} diff --git a/packages/react-v1/src/sources.ts b/packages/react-v1/src/sources.ts deleted file mode 100644 index a272cc1ef9..0000000000 --- a/packages/react-v1/src/sources.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { AppId } from '@lens-protocol/domain/entities'; - -import { appId } from './utils'; - -export const sources: Record = { - lenster: appId('lenster'), - orb: appId('orb'), -} as const; diff --git a/packages/react-v1/src/transactions/adapters/ApproveTransactionGateway.ts b/packages/react-v1/src/transactions/adapters/ApproveTransactionGateway.ts deleted file mode 100644 index 5af5e2f367..0000000000 --- a/packages/react-v1/src/transactions/adapters/ApproveTransactionGateway.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { TransactionRequest } from '@ethersproject/providers'; -import { erc20, bigNumber } from '@lens-protocol/blockchain-bindings'; -import { Wallet, UnsignedTransaction } from '@lens-protocol/domain/entities'; -import { - IApproveTransactionGateway, - TokenAllowanceLimit, - TokenAllowanceRequest, -} from '@lens-protocol/domain/use-cases/wallets'; -import { - Amount, - BigDecimal, - ChainType, - CryptoAsset, - CryptoNativeAsset, - getID, -} from '@lens-protocol/shared-kernel'; -import { BigNumber, constants } from 'ethers'; - -import { ITransactionRequest } from '../../wallet/adapters/ConcreteWallet'; -import { IProviderFactory } from '../../wallet/adapters/IProviderFactory'; -import { - Eip1559GasPriceEstimator, - TransactionExecutionSpeed, -} from '../infrastructure/Eip1559GasPriceEstimator'; - -export class UnsignedApproveTransaction< - Request extends TokenAllowanceRequest = TokenAllowanceRequest, - > - extends UnsignedTransaction - implements ITransactionRequest -{ - constructor( - chainType: ChainType, - request: Request, - readonly transactionRequest: TransactionRequest, - ) { - super(getID(), chainType, request); - } -} - -function createCryptoNativeAmountFactoryFor( - asset: CryptoAsset, -): CryptoNativeAmountFactory { - switch (asset.chainType) { - case ChainType.ETHEREUM: - return (value) => Amount.ether(value); - case ChainType.POLYGON: - return (value) => Amount.matic(value); - } -} - -export type CryptoNativeAmountFactory = ( - value: BigDecimal, -) => Amount; - -function resolveApproveAmount(request: TokenAllowanceRequest): BigNumber { - switch (request.limit) { - case TokenAllowanceLimit.EXACT: - return bigNumber(request.amount); - case TokenAllowanceLimit.INFINITE: - return constants.MaxUint256; - } -} - -export class ApproveTransactionGateway implements IApproveTransactionGateway { - constructor(private readonly providerFactory: IProviderFactory) {} - - async createApproveTransaction( - request: TokenAllowanceRequest, - wallet: Wallet, - ): Promise { - const provider = await this.providerFactory.createProvider({ - chainType: request.amount.asset.chainType, - }); - const contract = erc20(request.amount.asset.address, provider); - - const amount = resolveApproveAmount(request); - - const gasLimit = await contract.estimateGas.approve(request.spender, amount, { - from: wallet.address, - }); - - const gasEstimator = new Eip1559GasPriceEstimator( - provider, - createCryptoNativeAmountFactoryFor(request.amount.asset), - ); - - const gasPriceEstimate = await gasEstimator.estimate(TransactionExecutionSpeed.FAST); - - const transactionRequest = await contract.populateTransaction.approve(request.spender, amount, { - from: wallet.address, - gasLimit, - maxFeePerGas: bigNumber(gasPriceEstimate.maxFeePerGas), - maxPriorityFeePerGas: bigNumber(gasPriceEstimate.maxPriorityFeePerGas), - type: 2, // EIP-1559 - }); - - return new UnsignedApproveTransaction( - request.amount.asset.chainType, - request, - transactionRequest, - ); - } -} diff --git a/packages/react-v1/src/transactions/adapters/AsyncTransactionResult.ts b/packages/react-v1/src/transactions/adapters/AsyncTransactionResult.ts deleted file mode 100644 index 1ae703b10d..0000000000 --- a/packages/react-v1/src/transactions/adapters/AsyncTransactionResult.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { TransactionError } from '@lens-protocol/domain/entities'; -import { PromiseResult } from '@lens-protocol/shared-kernel'; - -export type AsyncTransactionResult = { - /** - * @experimental This method can change in the future - */ - waitForCompletion(): PromiseResult; -}; diff --git a/packages/react-v1/src/transactions/adapters/CollectPublicationGateway.ts b/packages/react-v1/src/transactions/adapters/CollectPublicationGateway.ts deleted file mode 100644 index 3c85f0beaa..0000000000 --- a/packages/react-v1/src/transactions/adapters/CollectPublicationGateway.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { - CreateCollectTypedDataData, - CreateCollectTypedDataDocument, - CreateCollectTypedDataVariables, - omitTypename, - ProxyActionData, - ProxyActionDocument, - ProxyActionRequest, - ProxyActionVariables, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { Nonce, ProxyTransaction } from '@lens-protocol/domain/entities'; -import { CollectRequest, FreeCollectRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - IOnChainProtocolCallGateway, - ISignlessSubsidizedCallRelayer, -} from '@lens-protocol/domain/use-cases/transactions'; -import { - ChainType, - ILogger, - PromiseResult, - assertError, - failure, - getID, - invariant, - success, -} from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../wallet/adapters/ConcreteWallet'; -import { ITransactionFactory } from './ITransactionFactory'; -import { ProxyReceipt } from './ProxyReceipt'; -import { Data, SelfFundedProtocolTransactionRequest } from './SelfFundedProtocolTransactionRequest'; - -export class CollectPublicationGateway - implements - IOnChainProtocolCallGateway, - ISignlessSubsidizedCallRelayer -{ - constructor( - private apolloClient: SafeApolloClient, - private factory: ITransactionFactory, - private logger: ILogger, - ) {} - - async createProxyTransaction( - request: FreeCollectRequest, - ): PromiseResult, BroadcastingError> { - const proxyReceipt = await this.proxy(request); - - if (proxyReceipt.isFailure()) { - return failure(proxyReceipt.error); - } - - return success( - this.factory.createProxyTransaction({ - chainType: ChainType.POLYGON, - id: getID(), - request, - proxyId: proxyReceipt.value.proxyId, - }), - ); - } - - async createUnsignedProtocolCall( - request: CollectRequest, - nonce?: Nonce, - ): Promise> { - const data = await this.generateCollectTypedData(request, nonce); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data), - }); - } - - private createRequestFallback( - request: CollectRequest, - data: CreateCollectTypedDataData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.result.typedData.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('collect', [ - data.result.typedData.message.profileId, - data.result.typedData.message.pubId, - data.result.typedData.message.data, - ]); - return { - ...request, - contractAddress: data.result.typedData.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } - - private async proxy(request: FreeCollectRequest): PromiseResult { - try { - const broadcastResult = await this.broadcast({ - collect: { - freeCollect: { - publicationId: request.publicationId, - }, - }, - }); - return success(broadcastResult); - } catch (error) { - assertError(error); - this.logger.error(error, 'It was not possible to relay the transaction'); - return failure( - new BroadcastingError( - error.message, - this.createRequestFallback(request, await this.generateCollectTypedData(request)), - ), - ); - } - } - - private async broadcast(request: ProxyActionRequest): Promise { - const { data } = await this.apolloClient.mutate({ - mutation: ProxyActionDocument, - variables: { - request, - }, - }); - - return { proxyId: data.result }; - } - - private async generateCollectTypedData( - request: CollectRequest, - nonce?: Nonce, - ): Promise { - const { data } = await this.apolloClient.mutate< - CreateCollectTypedDataData, - CreateCollectTypedDataVariables - >({ - mutation: CreateCollectTypedDataDocument, - variables: { - request: { - publicationId: request.publicationId, - }, - options: nonce ? { overrideSigNonce: nonce } : undefined, - }, - }); - - invariant(data, 'Cannot generate typed data for collect'); - - return data; - } -} diff --git a/packages/react-v1/src/transactions/adapters/CreateCommentController.ts b/packages/react-v1/src/transactions/adapters/CreateCommentController.ts deleted file mode 100644 index cba1b0a04f..0000000000 --- a/packages/react-v1/src/transactions/adapters/CreateCommentController.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { SafeApolloClient } from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { CreateComment, CreateCommentRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - IMetaTransactionNonceGateway, - IOnChainRelayer, - SubsidizeOnChain, - AnyTransactionRequest, - TransactionQueue, - IOffChainRelayer, - DelegableSigning, - SubsidizeOffChain, -} from '@lens-protocol/domain/use-cases/transactions'; -import { ActiveWallet } from '@lens-protocol/domain/use-cases/wallets'; - -import { IMetadataUploader } from './IMetadataUploader'; -import { ITransactionFactory } from './ITransactionFactory'; -import { TransactionResultPresenter } from './TransactionResultPresenter'; -import { CreateOffChainCommentGateway } from './publication-call-gateways/CreateOffChainCommentGateway'; -import { CreateOnChainCommentGateway } from './publication-call-gateways/CreateOnChainCommentGateway'; - -export type CreateCommentControllerArgs = { - activeWallet: ActiveWallet; - apolloClient: SafeApolloClient; - offChainRelayer: IOffChainRelayer; - onChainRelayer: IOnChainRelayer; - transactionFactory: ITransactionFactory; - transactionGateway: IMetaTransactionNonceGateway; - transactionQueue: TransactionQueue; - uploader: IMetadataUploader; -}; - -export class CreateCommentController { - private readonly presenter = new TransactionResultPresenter< - CreateCommentRequest, - BroadcastingError | PendingSigningRequestError | UserRejectedError | WalletConnectionError - >(); - - private readonly createComment: CreateComment; - - constructor({ - activeWallet, - apolloClient, - offChainRelayer, - onChainRelayer, - transactionFactory, - transactionGateway, - transactionQueue, - uploader, - }: CreateCommentControllerArgs) { - const onChainGateway = new CreateOnChainCommentGateway( - apolloClient, - transactionFactory, - uploader, - ); - - const onChainComment = new SubsidizeOnChain( - activeWallet, - transactionGateway, - onChainGateway, - onChainRelayer, - transactionQueue, - this.presenter, - ); - - const delegableOnChainComment = new DelegableSigning( - onChainComment, - onChainGateway, - transactionQueue, - this.presenter, - ); - - const offChainGateway = new CreateOffChainCommentGateway( - apolloClient, - transactionFactory, - uploader, - ); - - const offChainComment = new SubsidizeOffChain( - activeWallet, - offChainGateway, - offChainRelayer, - transactionQueue, - this.presenter, - ); - - const delegableOffChainComment = new DelegableSigning( - offChainComment, - offChainGateway, - transactionQueue, - this.presenter, - ); - - this.createComment = new CreateComment(delegableOnChainComment, delegableOffChainComment); - } - - async execute(request: CreateCommentRequest) { - await this.createComment.execute(request); - return this.presenter.asResult(); - } -} diff --git a/packages/react-v1/src/transactions/adapters/CreatePostController.ts b/packages/react-v1/src/transactions/adapters/CreatePostController.ts deleted file mode 100644 index cc80d4ac30..0000000000 --- a/packages/react-v1/src/transactions/adapters/CreatePostController.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { SafeApolloClient } from '@lens-protocol/api-bindings'; -import { CreatePost, CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - IMetaTransactionNonceGateway, - IOnChainRelayer, - SubsidizeOnChain, - AnyTransactionRequest, - TransactionQueue, - DelegableSigning, - IOffChainRelayer, - SubsidizeOffChain, -} from '@lens-protocol/domain/use-cases/transactions'; -import { ActiveWallet } from '@lens-protocol/domain/use-cases/wallets'; - -import { CreatePostPresenter, INewPostCacheManager } from './CreatePostPresenter'; -import { IMetadataUploader } from './IMetadataUploader'; -import { ITransactionFactory } from './ITransactionFactory'; -import { CreateOffChainPostGateway } from './publication-call-gateways/CreateOffChainPostGateway'; -import { CreateOnChainPostGateway } from './publication-call-gateways/CreateOnChainPostGateway'; - -export type CreatePostControllerArgs = { - activeWallet: ActiveWallet; - apolloClient: SafeApolloClient; - offChainRelayer: IOffChainRelayer; - onChainRelayer: IOnChainRelayer; - publicationCacheManager: INewPostCacheManager; - transactionFactory: ITransactionFactory; - transactionGateway: IMetaTransactionNonceGateway; - transactionQueue: TransactionQueue; - uploader: IMetadataUploader; -}; - -export class CreatePostController { - private readonly presenter: CreatePostPresenter; - - private readonly createPost: CreatePost; - - constructor({ - activeWallet, - apolloClient, - offChainRelayer, - onChainRelayer, - publicationCacheManager, - transactionFactory, - transactionGateway, - transactionQueue, - uploader, - }: CreatePostControllerArgs) { - this.presenter = new CreatePostPresenter(publicationCacheManager); - - const onChainGateway = new CreateOnChainPostGateway(apolloClient, transactionFactory, uploader); - - const onChainPost = new SubsidizeOnChain( - activeWallet, - transactionGateway, - onChainGateway, - onChainRelayer, - transactionQueue, - this.presenter, - ); - - const delegableOnChainPost = new DelegableSigning( - onChainPost, - onChainGateway, - transactionQueue, - this.presenter, - ); - - const offChainGateway = new CreateOffChainPostGateway( - apolloClient, - transactionFactory, - uploader, - ); - - const offChainPost = new SubsidizeOffChain( - activeWallet, - offChainGateway, - offChainRelayer, - transactionQueue, - this.presenter, - ); - - const delegableOffChainPost = new DelegableSigning( - offChainPost, - offChainGateway, - transactionQueue, - this.presenter, - ); - - this.createPost = new CreatePost(delegableOnChainPost, delegableOffChainPost); - } - - async execute(request: CreatePostRequest) { - await this.createPost.execute(request); - return this.presenter.asResult(); - } -} diff --git a/packages/react-v1/src/transactions/adapters/CreatePostPresenter.ts b/packages/react-v1/src/transactions/adapters/CreatePostPresenter.ts deleted file mode 100644 index 60ee9e36d6..0000000000 --- a/packages/react-v1/src/transactions/adapters/CreatePostPresenter.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Post } from '@lens-protocol/api-bindings'; -import { TransactionError } from '@lens-protocol/domain/entities'; -import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - IDelegatedTransactionPresenter, - ISubsidizeOffChainPresenter, - ISubsidizeOnChainPresenter, - TransactionData, -} from '@lens-protocol/domain/use-cases/transactions'; -import { Deferred, failure, Failure, Result, success } from '@lens-protocol/shared-kernel'; - -import { AsyncTransactionResult } from './AsyncTransactionResult'; - -export interface INewPostCacheManager { - fetchNewPost({ id, txHash }: TransactionData): Promise; -} - -export type CreatePostAsyncResult = AsyncTransactionResult; - -export class CreatePostPresenter - implements - IDelegatedTransactionPresenter, - ISubsidizeOnChainPresenter, - ISubsidizeOffChainPresenter -{ - private deferredResult = new Deferred>(); - - private earlyFailure: Failure | null = null; - - constructor(private readonly cacheManager: INewPostCacheManager) {} - - async present( - result: Result, BroadcastingError | TransactionError>, - ) { - if (result.isFailure()) { - if (result.error instanceof BroadcastingError) { - this.earlyFailure = failure(result.error); - return; - } - - this.deferredResult.resolve(failure(result.error)); - return; - } - const post = await this.cacheManager.fetchNewPost(result.value); - - this.deferredResult.resolve(success(post)); - } - - asResult(): Result { - if (this.earlyFailure) { - return this.earlyFailure; - } - - return success({ - waitForCompletion: async () => { - return this.deferredResult.promise; - }, - }); - } -} diff --git a/packages/react-v1/src/transactions/adapters/DispatcherConfigCallGateway.ts b/packages/react-v1/src/transactions/adapters/DispatcherConfigCallGateway.ts deleted file mode 100644 index 5ef0270abe..0000000000 --- a/packages/react-v1/src/transactions/adapters/DispatcherConfigCallGateway.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { - CreateSetDispatcherTypedDataDocument, - CreateSetDispatcherTypedDataData, - CreateSetDispatcherTypedDataVariables, - SafeApolloClient, - omitTypename, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { Nonce } from '@lens-protocol/domain/entities'; -import { UpdateDispatcherConfigRequest } from '@lens-protocol/domain/use-cases/profile'; -import { IOnChainProtocolCallGateway } from '@lens-protocol/domain/use-cases/transactions'; - -import { UnsignedProtocolCall } from '../../wallet/adapters/ConcreteWallet'; -import { Data, SelfFundedProtocolTransactionRequest } from './SelfFundedProtocolTransactionRequest'; - -export class DispatcherConfigCallGateway - implements IOnChainProtocolCallGateway -{ - constructor(private apolloClient: SafeApolloClient) {} - - async createUnsignedProtocolCall( - request: UpdateDispatcherConfigRequest, - nonce?: Nonce, - ): Promise> { - const { data } = await this.apolloClient.mutate< - CreateSetDispatcherTypedDataData, - CreateSetDispatcherTypedDataVariables - >({ - mutation: CreateSetDispatcherTypedDataDocument, - variables: { - request: { - profileId: request.profileId, - enable: request.enabled, - }, - options: nonce ? { overrideSigNonce: nonce } : undefined, - }, - }); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data), - }); - } - - private createRequestFallback( - request: UpdateDispatcherConfigRequest, - data: CreateSetDispatcherTypedDataData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.result.typedData.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('setDispatcher', [ - data.result.typedData.message.profileId, - data.result.typedData.message.dispatcher, - ]); - return { - ...request, - contractAddress: data.result.typedData.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/FollowPolicyCallGateway.ts b/packages/react-v1/src/transactions/adapters/FollowPolicyCallGateway.ts deleted file mode 100644 index 0d4f77db5b..0000000000 --- a/packages/react-v1/src/transactions/adapters/FollowPolicyCallGateway.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { - omitTypename, - CreateSetFollowModuleTypedDataDocument, - CreateSetFollowModuleTypedDataData, - CreateSetFollowModuleTypedDataVariables, - SafeApolloClient, - FollowModuleParams, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { Nonce } from '@lens-protocol/domain/entities'; -import { - FollowPolicyConfig, - FollowPolicyType, - UpdateFollowPolicyRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { IOnChainProtocolCallGateway } from '@lens-protocol/domain/use-cases/transactions'; - -import { UnsignedProtocolCall } from '../../wallet/adapters/ConcreteWallet'; -import { Data, SelfFundedProtocolTransactionRequest } from './SelfFundedProtocolTransactionRequest'; - -export function resolveFollowModuleParams(policy: FollowPolicyConfig): FollowModuleParams { - switch (policy.type) { - case FollowPolicyType.CHARGE: - return { - feeFollowModule: { - amount: { - currency: policy.amount.asset.address, - value: policy.amount.toSignificantDigits(), - }, - recipient: policy.recipient, - }, - }; - case FollowPolicyType.ANYONE: - return { - freeFollowModule: true, - }; - case FollowPolicyType.NO_ONE: - return { - revertFollowModule: true, - }; - case FollowPolicyType.ONLY_PROFILE_OWNERS: - return { - profileFollowModule: true, - }; - } -} - -export class FollowPolicyCallGateway - implements IOnChainProtocolCallGateway -{ - constructor(private apolloClient: SafeApolloClient) {} - - async createUnsignedProtocolCall( - request: UpdateFollowPolicyRequest, - nonce?: Nonce, - ): Promise> { - const { data } = await this.apolloClient.mutate< - CreateSetFollowModuleTypedDataData, - CreateSetFollowModuleTypedDataVariables - >({ - mutation: CreateSetFollowModuleTypedDataDocument, - variables: { - request: { - profileId: request.profileId, - followModule: resolveFollowModuleParams(request.policy), - }, - options: nonce ? { overrideSigNonce: nonce } : undefined, - }, - }); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data), - }); - } - - private createRequestFallback( - request: UpdateFollowPolicyRequest, - data: CreateSetFollowModuleTypedDataData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.result.typedData.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('setFollowModule', [ - data.result.typedData.message.profileId, - data.result.typedData.message.followModule, - data.result.typedData.message.followModuleInitData, - ]); - return { - ...request, - contractAddress: data.result.typedData.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/FollowProfilesGateway.ts b/packages/react-v1/src/transactions/adapters/FollowProfilesGateway.ts deleted file mode 100644 index 51e2c88abd..0000000000 --- a/packages/react-v1/src/transactions/adapters/FollowProfilesGateway.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { - CreateFollowTypedDataData, - CreateFollowTypedDataDocument, - CreateFollowTypedDataVariables, - Follow, - moduleFeeAmountParams, - omitTypename, - ProxyActionData, - ProxyActionDocument, - ProxyActionRequest, - ProxyActionVariables, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { Nonce, ProxyTransaction } from '@lens-protocol/domain/entities'; -import { - FollowRequest, - UnconstrainedFollowRequest, - isPaidFollowRequest, - isProfileOwnerFollowRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { - BroadcastingError, - IOnChainProtocolCallGateway, - ISignlessSubsidizedCallRelayer, -} from '@lens-protocol/domain/use-cases/transactions'; -import { - ChainType, - ILogger, - PromiseResult, - assertError, - failure, - getID, - success, -} from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../wallet/adapters/ConcreteWallet'; -import { ITransactionFactory } from './ITransactionFactory'; -import { ProxyReceipt } from './ProxyReceipt'; -import { Data, SelfFundedProtocolTransactionRequest } from './SelfFundedProtocolTransactionRequest'; - -function resolveProfileFollow(request: FollowRequest): Follow[] { - if (isPaidFollowRequest(request)) { - return [ - { - profile: request.profileId, - followModule: { - feeFollowModule: { - amount: moduleFeeAmountParams({ from: request.fee.amount }), - }, - }, - }, - ]; - } - if (isProfileOwnerFollowRequest(request)) { - return [ - { - profile: request.profileId, - followModule: { - profileFollowModule: { - profileId: request.followerProfileId, - }, - }, - }, - ]; - } - return [{ profile: request.profileId }]; -} - -export class FollowProfilesGateway - implements - IOnChainProtocolCallGateway, - ISignlessSubsidizedCallRelayer -{ - constructor( - private apolloClient: SafeApolloClient, - private factory: ITransactionFactory, - private logger: ILogger, - ) {} - - async createProxyTransaction( - request: UnconstrainedFollowRequest, - nonce?: Nonce, - ): PromiseResult, BroadcastingError> { - const proxyReceipt = await this.proxy(request, nonce); - - if (proxyReceipt.isFailure()) { - return failure(proxyReceipt.error); - } - - return success( - this.factory.createProxyTransaction({ - chainType: ChainType.POLYGON, - id: getID(), - request, - proxyId: proxyReceipt.value.proxyId, - }), - ); - } - - async createUnsignedProtocolCall( - request: FollowRequest, - nonce?: Nonce, - ): Promise> { - const data = await this.createFollowTypedData(request, nonce); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data), - }); - } - - private async proxy( - request: UnconstrainedFollowRequest, - nonce?: Nonce, - ): PromiseResult { - try { - const broadcastResult = await this.broadcast({ - follow: { - freeFollow: { - profileId: request.profileId, - }, - }, - }); - return success(broadcastResult); - } catch (error) { - assertError(error); - this.logger.error(error, 'It was not possible to relay the transaction'); - return failure( - new BroadcastingError( - error.message, - this.createRequestFallback(request, await this.createFollowTypedData(request, nonce)), - ), - ); - } - } - - private async broadcast(request: ProxyActionRequest): Promise { - const { data } = await this.apolloClient.mutate({ - mutation: ProxyActionDocument, - variables: { - request, - }, - }); - - return { proxyId: data.result }; - } - - private async createFollowTypedData( - request: FollowRequest, - nonce?: Nonce, - ): Promise { - const { data } = await this.apolloClient.mutate< - CreateFollowTypedDataData, - CreateFollowTypedDataVariables - >({ - mutation: CreateFollowTypedDataDocument, - variables: { - request: { - follow: resolveProfileFollow(request), - }, - options: nonce ? { overrideSigNonce: nonce } : undefined, - }, - }); - - return data; - } - - private createRequestFallback( - request: FollowRequest, - data: CreateFollowTypedDataData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.result.typedData.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('follow', [ - data.result.typedData.message.profileIds, - data.result.typedData.message.datas, - ]); - return { - ...request, - contractAddress: data.result.typedData.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/IMetadataUploader.ts b/packages/react-v1/src/transactions/adapters/IMetadataUploader.ts deleted file mode 100644 index 44fab5b33a..0000000000 --- a/packages/react-v1/src/transactions/adapters/IMetadataUploader.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Url, CausedError } from '@lens-protocol/shared-kernel'; - -export class FailedUploadError extends CausedError { - name = 'FailedUploadError' as const; -} - -export interface IMetadataUploader { - upload(request: T): Promise; -} diff --git a/packages/react-v1/src/transactions/adapters/IProfileCacheManager.ts b/packages/react-v1/src/transactions/adapters/IProfileCacheManager.ts deleted file mode 100644 index 2bb0ae0ed2..0000000000 --- a/packages/react-v1/src/transactions/adapters/IProfileCacheManager.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; - -export interface IProfileCacheManager { - fetchProfile(id: ProfileId): Promise; - - fetchNewProfile(handlePrefix: string): Promise; - - refreshProfile(id: ProfileId): Promise; - - updateProfile(id: ProfileId, updateFn: (current: Profile) => Profile): void; -} diff --git a/packages/react-v1/src/transactions/adapters/ITransactionFactory.ts b/packages/react-v1/src/transactions/adapters/ITransactionFactory.ts deleted file mode 100644 index 48db399af8..0000000000 --- a/packages/react-v1/src/transactions/adapters/ITransactionFactory.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { - AnyTransactionRequestModel, - MetaTransaction, - NativeTransaction, - Nonce, - ProxyTransaction, - ProxyActionStatus, - JustProtocolRequest, - DataTransaction, -} from '@lens-protocol/domain/entities'; -import { ChainType } from '@lens-protocol/shared-kernel'; - -export type NativeTransactionData = { - chainType: ChainType; - id: string; - indexingId?: string; - request: T; - txHash: string; -}; - -export type MetaTransactionData = { - chainType: ChainType; - id: string; - indexingId: string; - nonce: Nonce; - request: T; - txHash: string; -}; - -export type ProxyTransactionData = { - chainType: ChainType; - id: string; - request: T; - proxyId: string; - txHash?: string; - status?: ProxyActionStatus; -}; - -export type DataTransactionData = { - id: string; - request: T; -}; - -export interface ITransactionFactory { - createMetaTransaction>( - init: MetaTransactionData, - ): MetaTransaction; - - createNativeTransaction( - init: NativeTransactionData, - ): NativeTransaction; - - createProxyTransaction>( - init: ProxyTransactionData, - ): ProxyTransaction; - - createDataTransaction>( - init: DataTransactionData, - ): DataTransaction; -} diff --git a/packages/react-v1/src/transactions/adapters/IUpdatePublicationCacheManager.ts b/packages/react-v1/src/transactions/adapters/IUpdatePublicationCacheManager.ts deleted file mode 100644 index 037a5b3091..0000000000 --- a/packages/react-v1/src/transactions/adapters/IUpdatePublicationCacheManager.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { AnyPublication } from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; - -export interface IUpdatePublicationCacheManager { - update( - publicationId: PublicationId, - updateFn: (current: TPublication) => TPublication, - ): void; -} diff --git a/packages/react-v1/src/transactions/adapters/MetadataUploadHandler.ts b/packages/react-v1/src/transactions/adapters/MetadataUploadHandler.ts deleted file mode 100644 index b65933088f..0000000000 --- a/packages/react-v1/src/transactions/adapters/MetadataUploadHandler.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Url } from '@lens-protocol/shared-kernel'; - -/** - * A function that uploads metadata to a remote server and returns the URL of the uploaded file. - * - * The URL provided MUST be publicly accessible in the Internet and served as `Content-Type: application/json`. - * - * @param data - The metadata to upload, an opaque JS Object safe for serialization - * @returns The URL where the JSON file will be served from - */ -export type MetadataUploadHandler = (data: unknown) => Promise; diff --git a/packages/react-v1/src/transactions/adapters/OffChainRelayer.ts b/packages/react-v1/src/transactions/adapters/OffChainRelayer.ts deleted file mode 100644 index d2cdd92467..0000000000 --- a/packages/react-v1/src/transactions/adapters/OffChainRelayer.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { - SafeApolloClient, - BroadcastOffChainData, - BroadcastOffChainVariables, - BroadcastOffChainDocument, -} from '@lens-protocol/api-bindings'; -import { DataTransaction } from '@lens-protocol/domain/entities'; -import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - IOffChainRelayer, - ProtocolTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { - assertError, - failure, - ILogger, - PromiseResult, - success, -} from '@lens-protocol/shared-kernel'; - -import { SignedProtocolCall } from '../../wallet/adapters/ConcreteWallet'; -import { ITransactionFactory } from './ITransactionFactory'; -import { handleRelayError, OffChainBroadcastReceipt } from './relayer'; - -export class OffChainRelayer implements IOffChainRelayer { - constructor( - private apolloClient: SafeApolloClient, - private factory: ITransactionFactory, - private logger: ILogger, - ) {} - - async relayProtocolCall( - signedCall: SignedProtocolCall, - ): PromiseResult, BroadcastingError> { - const result = await this.broadcast(signedCall); - - if (result.isFailure()) return failure(result.error); - - const receipt = result.value; - - const transaction = this.factory.createDataTransaction({ - id: receipt.id, - request: signedCall.request, - }); - - return success(transaction); - } - - private async broadcast( - signedCall: SignedProtocolCall, - ): PromiseResult { - try { - const { data } = await this.apolloClient.mutate< - BroadcastOffChainData, - BroadcastOffChainVariables - >({ - mutation: BroadcastOffChainDocument, - variables: { - request: { - id: signedCall.id, - signature: signedCall.signature, - }, - }, - }); - - if (data.result.__typename === 'RelayError') { - return handleRelayError(data.result, signedCall.fallback); - } - - return success({ - id: data.result.id, - }); - } catch (err) { - this.logger.error(err, `It was not possible to relay the transaction for ${signedCall.id}`); - assertError(err); - return failure(new BroadcastingError(err.message)); - } - } -} diff --git a/packages/react-v1/src/transactions/adapters/OnChainRelayer.ts b/packages/react-v1/src/transactions/adapters/OnChainRelayer.ts deleted file mode 100644 index d0a51d2d89..0000000000 --- a/packages/react-v1/src/transactions/adapters/OnChainRelayer.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { - BroadcastOnChainData, - BroadcastOnChainDocument, - BroadcastOnChainVariables, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; -import { MetaTransaction } from '@lens-protocol/domain/entities'; -import { - IOnChainRelayer, - BroadcastingError, - ProtocolTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { - assertError, - ChainType, - failure, - ILogger, - PromiseResult, - success, -} from '@lens-protocol/shared-kernel'; - -import { SignedProtocolCall } from '../../wallet/adapters/ConcreteWallet'; -import { ITransactionFactory } from './ITransactionFactory'; -import { handleRelayError, OnChainBroadcastReceipt } from './relayer'; - -export class OnChainRelayer implements IOnChainRelayer { - constructor( - private apolloClient: SafeApolloClient, - private factory: ITransactionFactory, - private logger: ILogger, - ) {} - - async relayProtocolCall( - signedCall: SignedProtocolCall, - ): PromiseResult, BroadcastingError> { - const result = await this.broadcast(signedCall); - - if (result.isFailure()) return failure(result.error); - - const receipt = result.value; - - const transaction = this.factory.createMetaTransaction({ - chainType: ChainType.POLYGON, - id: signedCall.id, - request: signedCall.request, - nonce: signedCall.nonce, - indexingId: receipt.indexingId, - txHash: receipt.txHash, - }); - - return success(transaction); - } - - private async broadcast( - signedCall: SignedProtocolCall, - ): PromiseResult { - try { - const { data } = await this.apolloClient.mutate< - BroadcastOnChainData, - BroadcastOnChainVariables - >({ - mutation: BroadcastOnChainDocument, - variables: { - request: { - id: signedCall.id, - signature: signedCall.signature, - }, - }, - }); - - if (data.result.__typename === 'RelayError') { - return handleRelayError(data.result, signedCall.fallback); - } - - return success({ - indexingId: data.result.txId, - txHash: data.result.txHash, - }); - } catch (err) { - this.logger.error(err, `It was not possible to relay the transaction for ${signedCall.id}`); - assertError(err); - return failure(new BroadcastingError(err.message)); - } - } -} diff --git a/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/ISerializableTransactionFactory.ts b/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/ISerializableTransactionFactory.ts deleted file mode 100644 index 47a4a66607..0000000000 --- a/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/ISerializableTransactionFactory.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { - DataTransaction, - MetaTransaction, - NativeTransaction, - ProxyTransaction, -} from '@lens-protocol/domain/entities'; -import { - ProtocolTransactionRequest, - AnyTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { - DataTransactionData, - ITransactionFactory, - MetaTransactionData, - NativeTransactionData, - ProxyTransactionData, -} from '../ITransactionFactory'; - -export interface ISerializableMetaTransaction - extends MetaTransaction { - toTransactionData(): MetaTransactionData; -} - -export interface ISerializableNativeTransaction - extends NativeTransaction { - toTransactionData(): NativeTransactionData; -} - -export interface ISerializableProxyTransaction - extends ProxyTransaction { - toTransactionData(): ProxyTransactionData; -} - -export interface ISerializableDataTransaction - extends DataTransaction { - toTransactionData(): DataTransactionData; -} - -export interface ISerializableTransactionFactory - extends ITransactionFactory { - createMetaTransaction( - init: MetaTransactionData, - ): ISerializableMetaTransaction; - - createNativeTransaction( - init: NativeTransactionData, - ): ISerializableNativeTransaction; - - createProxyTransaction( - init: ProxyTransactionData, - ): ISerializableProxyTransaction; - - createDataTransaction( - init: DataTransactionData, - ): ISerializableDataTransaction; -} diff --git a/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/PendingTransactionGateway.ts b/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/PendingTransactionGateway.ts deleted file mode 100644 index 95b44cffcc..0000000000 --- a/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/PendingTransactionGateway.ts +++ /dev/null @@ -1,221 +0,0 @@ -import { - MetaTransaction, - NativeTransaction, - JustProtocolRequest, - ProxyTransaction, - TransactionKind, - DataTransaction, -} from '@lens-protocol/domain/entities'; -import { - IMetaTransactionNonceGateway, - IPendingTransactionGateway, - NewTransactionsSubscriber, - AnyTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { assertNever, invariant } from '@lens-protocol/shared-kernel'; -import { IStorage } from '@lens-protocol/storage'; -import differenceBy from 'lodash/differenceBy.js'; - -import { - TransactionSchema, - TransactionStorageSchema, - TransactionType, -} from '../schemas/transactions'; -import { - ISerializableDataTransaction, - ISerializableMetaTransaction, - ISerializableNativeTransaction, - ISerializableProxyTransaction, - ISerializableTransactionFactory, -} from './ISerializableTransactionFactory'; - -const lensHubTransactionKinds = [ - TransactionKind.COLLECT_PUBLICATION, - TransactionKind.CREATE_COMMENT, - TransactionKind.CREATE_POST, - TransactionKind.FOLLOW_PROFILES, - TransactionKind.MIRROR_PUBLICATION, - TransactionKind.UPDATE_DISPATCHER_CONFIG, - TransactionKind.UPDATE_PROFILE_IMAGE, - TransactionKind.UPDATE_FOLLOW_POLICY, -]; - -const lensPeripheryTransactionKinds = [TransactionKind.UPDATE_PROFILE_DETAILS]; - -const transactionKindToFilterGroup: { [k in TransactionKind]: TransactionKind[] } = { - [TransactionKind.COLLECT_PUBLICATION]: lensHubTransactionKinds, - [TransactionKind.CREATE_COMMENT]: lensHubTransactionKinds, - [TransactionKind.CREATE_POST]: lensHubTransactionKinds, - [TransactionKind.FOLLOW_PROFILES]: lensHubTransactionKinds, - [TransactionKind.MIRROR_PUBLICATION]: lensHubTransactionKinds, - [TransactionKind.UPDATE_DISPATCHER_CONFIG]: lensHubTransactionKinds, - [TransactionKind.UPDATE_PROFILE_IMAGE]: lensHubTransactionKinds, - [TransactionKind.UPDATE_FOLLOW_POLICY]: lensHubTransactionKinds, - - [TransactionKind.UPDATE_PROFILE_DETAILS]: lensPeripheryTransactionKinds, - - [TransactionKind.APPROVE_MODULE]: [], - [TransactionKind.CREATE_PROFILE]: [], - [TransactionKind.UNFOLLOW_PROFILE]: [], -}; - -function isSerializableMetaTransaction( - tx: ISerializableTransaction, -): tx is ISerializableMetaTransaction> { - return tx instanceof MetaTransaction; -} - -type ISerializableTransaction = - | ISerializableNativeTransaction - | ISerializableMetaTransaction> - | ISerializableProxyTransaction> - | ISerializableDataTransaction>; - -function toTransactionSchema( - tx: ISerializableTransaction, -): TransactionSchema { - if (tx instanceof MetaTransaction) { - return { - type: TransactionType.Meta, - ...tx.toTransactionData(), - }; - } - - if (tx instanceof NativeTransaction) { - return { - type: TransactionType.Native, - ...tx.toTransactionData(), - }; - } - - if (tx instanceof ProxyTransaction) { - return { - type: TransactionType.Proxy, - ...tx.toTransactionData(), - }; - } - - if (tx instanceof DataTransaction) { - return { - type: TransactionType.Data, - ...tx.toTransactionData(), - }; - } - - assertNever(tx, 'Transaction type not supported'); -} - -export class PendingTransactionGateway - implements IPendingTransactionGateway, IMetaTransactionNonceGateway -{ - private cache?: ISerializableTransaction[]; - - constructor( - private readonly storage: IStorage, - private readonly transactionFactory: ISerializableTransactionFactory, - ) {} - - async save(tx: ISerializableTransaction): Promise { - const transactions = await this.getAll(); - const newTransactions = [...transactions]; - - const idx = transactions.findIndex((entry) => entry.id === tx.id); - if (idx > -1) { - newTransactions.splice(idx, 1, tx); - await this.update(newTransactions); - return; - } - - if (tx instanceof MetaTransaction) { - const expectedNonce = await this.getNextMetaTransactionNonceFor(tx.request.kind); - - if (expectedNonce) { - invariant( - expectedNonce === tx.nonce, - `Nonce mismatch, was expecting ${expectedNonce}, got ${tx.nonce}`, - ); - } - } - - newTransactions.unshift(tx); - await this.update(newTransactions); - } - - async remove(id: string): Promise { - const transactions = await this.getAll(); - await this.update(transactions.filter((tx) => tx.id !== id)); - } - - async getAll(): Promise[]> { - if (this.cache) { - return this.cache.slice(); - } - const data = await this.storage.get(); - - if (data === null) { - return []; - } - - return data.map((entry) => this.toEntity(entry)); - } - - async getNextMetaTransactionNonceFor(kind: TransactionKind) { - const all = await this.getAll(); - - if (all.length === 0) { - return undefined; - } - - const metaTransactions = all.filter(isSerializableMetaTransaction); - if (metaTransactions.length === 0) { - return undefined; - } - - if (kind in transactionKindToFilterGroup) { - const filter = transactionKindToFilterGroup[kind]; - const firstOfKind = metaTransactions.find((tx) => filter.includes(tx.request.kind)); - - return firstOfKind ? firstOfKind.nonce + 1 : undefined; - } - return undefined; - } - - subscribe(subscriber: NewTransactionsSubscriber): void { - this.storage.subscribe(async (newData, oldData) => { - if (newData === null) { - return; - } - const updatedTransactions = newData.map((entry) => this.toEntity(entry)); - const previousTransactions = oldData?.map((entry) => this.toEntity(entry)) ?? []; - - const newTransaction = differenceBy(updatedTransactions, previousTransactions, (tx) => tx.id); - - if (newTransaction.length > 0) { - subscriber(newTransaction); - } - }); - } - - private async update( - transactions: ISerializableTransaction[], - ): Promise { - this.cache = transactions; - const data = transactions.map(toTransactionSchema); - await this.storage.set(data); - } - - private toEntity(data: TransactionSchema): ISerializableTransaction { - switch (data.type) { - case TransactionType.Meta: - return this.transactionFactory.createMetaTransaction(data); - case TransactionType.Native: - return this.transactionFactory.createNativeTransaction(data); - case TransactionType.Proxy: - return this.transactionFactory.createProxyTransaction(data); - case TransactionType.Data: - return this.transactionFactory.createDataTransaction(data); - default: - assertNever(data, 'Transaction type not supported'); - } - } -} diff --git a/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/__tests__/PendingTransactionGateway.spec.ts b/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/__tests__/PendingTransactionGateway.spec.ts deleted file mode 100644 index a741f01659..0000000000 --- a/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/__tests__/PendingTransactionGateway.spec.ts +++ /dev/null @@ -1,297 +0,0 @@ -import { MetaTransaction, TransactionKind } from '@lens-protocol/domain/entities'; -import { - mockCreateProfileRequest, - mockUnconstrainedFollowRequest, - mockUnfollowRequest, - mockUpdateDispatcherConfigRequest, - mockUpdateFollowPolicyRequest, - mockUpdateOffChainProfileImageRequest, - mockUpdateProfileDetailsRequest, - mockCreateCommentRequest, - mockCreateMirrorRequest, - mockCreatePostRequest, - mockFreeCollectRequest, - mockTokenAllowanceRequest, -} from '@lens-protocol/domain/mocks'; -import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; -import { InvariantError } from '@lens-protocol/shared-kernel'; -import { IStorage, Storage } from '@lens-protocol/storage'; -import { mockStorage } from '@lens-protocol/storage/mocks'; - -import { TransactionFactory } from '../../../infrastructure/TransactionFactory'; -import { - mockITransactionFactory, - mockMetaTransactionData, - mockNativeTransactionData, -} from '../../__helpers__/mocks'; -import { TransactionStorageSchema } from '../../schemas/transactions'; -import { PendingTransactionGateway } from '../PendingTransactionGateway'; - -function setupPendingTransactionGateway({ - factory = mockITransactionFactory(), - storage = mockStorage(), -}: { - factory?: TransactionFactory; - storage?: IStorage; -}) { - return new PendingTransactionGateway(storage, factory); -} - -type TransactionRequest = { - [K in TransactionKind]: Extract; -}; - -const requests: TransactionRequest = { - [TransactionKind.APPROVE_MODULE]: mockTokenAllowanceRequest(), - [TransactionKind.COLLECT_PUBLICATION]: mockFreeCollectRequest(), - [TransactionKind.CREATE_COMMENT]: mockCreateCommentRequest(), - [TransactionKind.CREATE_POST]: mockCreatePostRequest(), - [TransactionKind.FOLLOW_PROFILES]: mockUnconstrainedFollowRequest(), - [TransactionKind.MIRROR_PUBLICATION]: mockCreateMirrorRequest(), - [TransactionKind.UPDATE_FOLLOW_POLICY]: mockUpdateFollowPolicyRequest(), - [TransactionKind.UPDATE_PROFILE_DETAILS]: mockUpdateProfileDetailsRequest(), - [TransactionKind.UPDATE_PROFILE_IMAGE]: mockUpdateOffChainProfileImageRequest(), - [TransactionKind.CREATE_PROFILE]: mockCreateProfileRequest(), - [TransactionKind.UNFOLLOW_PROFILE]: mockUnfollowRequest(), - [TransactionKind.UPDATE_DISPATCHER_CONFIG]: mockUpdateDispatcherConfigRequest(), -}; - -const lensHubTransactionKinds = [ - TransactionKind.COLLECT_PUBLICATION, - TransactionKind.CREATE_COMMENT, - TransactionKind.CREATE_POST, - TransactionKind.FOLLOW_PROFILES, - TransactionKind.MIRROR_PUBLICATION, - TransactionKind.UPDATE_DISPATCHER_CONFIG, - TransactionKind.UPDATE_FOLLOW_POLICY, - TransactionKind.UPDATE_PROFILE_IMAGE, -] as const; - -const lensPeripheryTransactionKinds = [TransactionKind.UPDATE_PROFILE_DETAILS] as const; - -describe(`Given an instance of the ${PendingTransactionGateway.name}`, () => { - const factory = mockITransactionFactory(); - - describe(`when the "${PendingTransactionGateway.prototype.save.name}" method is invoked`, () => { - const request = mockCreatePostRequest(); - - it(`should save in memory all the given Transaction alongside existing ones`, async () => { - const gateway = setupPendingTransactionGateway({ factory }); - - const init = mockMetaTransactionData({ request }); - const tx = factory.createMetaTransaction(init); - - await gateway.save(tx); - - const actual = await gateway.getAll(); - expect(actual).toEqual([tx]); - }); - - it('should update the existing tx if provided a second time', async () => { - const gateway = setupPendingTransactionGateway({ factory }); - - const init = mockMetaTransactionData({ request }); - const tx = factory.createMetaTransaction(init); - - await gateway.save(tx); - await gateway.save(tx); - - const actual = await gateway.getAll(); - expect(actual).toEqual([tx]); - }); - - it(`should throw an ${InvariantError.name} in case of ${MetaTransaction.name} with Nonce out of sequence`, async () => { - const initTx1 = mockMetaTransactionData({ request }); - const tx1 = factory.createMetaTransaction(initTx1); - - const gateway = setupPendingTransactionGateway({ factory }); - await gateway.save(tx1); - - const initTx2 = mockMetaTransactionData({ request, nonce: initTx1.nonce + 4002 }); - const tx2 = factory.createMetaTransaction(initTx2); - - await expect(() => gateway.save(tx2)).rejects.toThrow(InvariantError); - }); - }); - - describe(`when the "${PendingTransactionGateway.prototype.remove.name}" method is invoked`, () => { - const request = mockCreatePostRequest(); - const init = mockMetaTransactionData({ request }); - const tx = factory.createMetaTransaction(init); - - it(`should remove the Transaction for the given Id`, async () => { - const gateway = setupPendingTransactionGateway({ factory }); - await gateway.save(tx); - - await gateway.remove(tx.id); - - const actual = await gateway.getAll(); - expect(actual).toEqual([]); - }); - }); - - describe(`when the underlying ${Storage.name} emits new data`, () => { - const request = mockCreatePostRequest(); - const init = mockNativeTransactionData({ request }); - const tx = factory.createNativeTransaction(init); - const mainStorage = mockStorage(); - const mainGateway = setupPendingTransactionGateway({ factory, storage: mainStorage }); - - beforeAll(async () => { - await mainGateway.save(tx); - }); - - it('should emit new transactions', async () => { - const secondaryStorage = mockStorage(); - const underTestGateway = setupPendingTransactionGateway({ - factory, - storage: secondaryStorage, - }); - - const transactionsData = await mainStorage.get(); - const subscriber = jest.fn(); - underTestGateway.subscribe(subscriber); - secondaryStorage.simulateUpdate(transactionsData, null); - - expect(subscriber).toHaveBeenCalledWith([ - expect.objectContaining({ - id: tx.id, - }), - ]); - }); - - it('should not emit in case of updated transactions only', async () => { - const underTestGateway = setupPendingTransactionGateway({ - factory, - storage: mainStorage, - }); - - const transactionsData = await mainStorage.get(); - const subscriber = jest.fn(); - underTestGateway.subscribe(subscriber); - mainStorage.simulateUpdate(transactionsData, transactionsData); - - expect(subscriber).not.toHaveBeenCalled(); - }); - - it('should not emit in case of cleared storage event', async () => { - const storage = mockStorage(); - const underTestGateway = setupPendingTransactionGateway({ - factory, - storage, - }); - - const subscriber = jest.fn(); - underTestGateway.subscribe(subscriber); - const transactionsData = await mainStorage.get(); - storage.simulateUpdate(null, transactionsData); - - expect(subscriber).not.toHaveBeenCalled(); - }); - }); - - describe(`when the "${PendingTransactionGateway.prototype.getNextMetaTransactionNonceFor.name}" method is invoked`, () => { - const request = mockCreatePostRequest(); - - it('should return undefined if empty', async () => { - const gateway = setupPendingTransactionGateway({ factory }); - - const nonce = await gateway.getNextMetaTransactionNonceFor(request.kind); - - expect(nonce).toBeUndefined(); - }); - - it(`should return undefined if no ${MetaTransaction.name}s are present`, async () => { - const init = mockNativeTransactionData({ request }); - const tx = factory.createNativeTransaction(init); - const gateway = setupPendingTransactionGateway({ factory }); - await gateway.save(tx); - - const nonce = await gateway.getNextMetaTransactionNonceFor(TransactionKind.CREATE_POST); - - expect(nonce).toBeUndefined(); - }); - - describe('for a TransactionKind corresponding to a protocol method exposed on the LensHub.sol contract', () => { - it(`should compute the next Nonce based on the most recent ${MetaTransaction.name} exposed from the same contract`, async () => { - const gateway = setupPendingTransactionGateway({ factory }); - - for (let idx = 0; idx < lensHubTransactionKinds.length; idx++) { - const kind = lensHubTransactionKinds[idx]; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const init = mockMetaTransactionData({ request: requests[kind!], nonce: idx }); - const tx = factory.createMetaTransaction(init); - - await gateway.save(tx); - - expect(await gateway.getNextMetaTransactionNonceFor(TransactionKind.CREATE_POST)).toBe( - tx.nonce + 1, - ); - } - }); - - it(`should not be affected by ${MetaTransaction.name} for methods exposed on LensPeriphery.sol contract`, async () => { - const request = mockUpdateProfileDetailsRequest(); - const gateway = setupPendingTransactionGateway({ factory }); - const init = mockMetaTransactionData({ request }); - const tx = factory.createMetaTransaction(init); - await gateway.save(tx); - - const nonce = await gateway.getNextMetaTransactionNonceFor(TransactionKind.CREATE_POST); - - expect(nonce).toBeUndefined(); - }); - }); - - describe('for a TransactionKind corresponding to a protocol method exposed on the LensPeriphery.sol contract', () => { - it(`should compute the next Nonce based on the most recent ${MetaTransaction.name} exposed from the same contract`, async () => { - const gateway = setupPendingTransactionGateway({ factory }); - - for (let idx = 0; idx < lensPeripheryTransactionKinds.length; idx++) { - const kind = lensPeripheryTransactionKinds[idx]; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const init = mockMetaTransactionData({ request: requests[kind!], nonce: idx }); - const tx = factory.createMetaTransaction(init); - - await gateway.save(tx); - - expect( - await gateway.getNextMetaTransactionNonceFor(TransactionKind.UPDATE_PROFILE_DETAILS), - ).toBe(tx.nonce + 1); - } - }); - - it(`should not be affected by ${MetaTransaction.name} for methods exposed on LensHub.sol contract`, async () => { - const request = mockCreatePostRequest(); - const gateway = setupPendingTransactionGateway({ factory }); - const init = mockMetaTransactionData({ request }); - const tx = factory.createMetaTransaction(init); - await gateway.save(tx); - - const nonce = await gateway.getNextMetaTransactionNonceFor( - TransactionKind.UPDATE_PROFILE_DETAILS, - ); - - expect(nonce).toBeUndefined(); - }); - }); - - describe(`for ${TransactionKind.UNFOLLOW_PROFILE} meta-tx`, () => { - const request = mockUnfollowRequest(); - const init = mockMetaTransactionData({ request }); - const tx = factory.createMetaTransaction(init); - - it(`should always return undefined cause the burn method is on Follow NFT contract - and keeping accurate tracking of nonces is more complex and not worth it`, async () => { - const gateway = setupPendingTransactionGateway({ factory }); - await gateway.save(tx); - - const nonce = await gateway.getNextMetaTransactionNonceFor( - TransactionKind.UNFOLLOW_PROFILE, - ); - - expect(nonce).toBeUndefined(); - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/index.ts b/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/index.ts deleted file mode 100644 index 498f9a086c..0000000000 --- a/packages/react-v1/src/transactions/adapters/PendingTransactionGateway/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export type { - ISerializableTransactionFactory, - ISerializableMetaTransaction, - ISerializableNativeTransaction, - ISerializableProxyTransaction, -} from './ISerializableTransactionFactory'; -export { PendingTransactionGateway } from './PendingTransactionGateway'; diff --git a/packages/react-v1/src/transactions/adapters/ProfileImageCallGateway.ts b/packages/react-v1/src/transactions/adapters/ProfileImageCallGateway.ts deleted file mode 100644 index 7a8890822c..0000000000 --- a/packages/react-v1/src/transactions/adapters/ProfileImageCallGateway.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { - CreateSetProfileImageUriTypedDataDocument, - CreateSetProfileImageUriTypedDataData, - CreateSetProfileImageUriTypedDataVariables, - CreateSetProfileImageUriViaDispatcherDocument, - CreateSetProfileImageUriViaDispatcherData, - CreateSetProfileImageUriViaDispatcherVariables, - omitTypename, - UpdateProfileImageRequest as UpdateProfileImageRequestArgs, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { NativeTransaction, Nonce } from '@lens-protocol/domain/entities'; -import { UpdateProfileImageRequest } from '@lens-protocol/domain/use-cases/profile'; -import { - BroadcastingError, - IDelegatedTransactionGateway, - IOnChainProtocolCallGateway, -} from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; -import { v4 } from 'uuid'; - -import { UnsignedProtocolCall } from '../../wallet/adapters/ConcreteWallet'; -import { ITransactionFactory } from './ITransactionFactory'; -import { Data, SelfFundedProtocolTransactionRequest } from './SelfFundedProtocolTransactionRequest'; -import { handleRelayError, OnChainBroadcastReceipt } from './relayer'; - -export class ProfileImageCallGateway - implements - IDelegatedTransactionGateway, - IOnChainProtocolCallGateway -{ - constructor( - private apolloClient: SafeApolloClient, - private readonly transactionFactory: ITransactionFactory, - ) {} - - async createDelegatedTransaction( - request: UpdateProfileImageRequest, - ): PromiseResult, BroadcastingError> { - const result = await this.broadcast(request); - - if (result.isFailure()) return failure(result.error); - - const receipt = result.value; - - const transaction = this.transactionFactory.createNativeTransaction({ - chainType: ChainType.POLYGON, - id: v4(), - request, - indexingId: receipt.indexingId, - txHash: receipt.txHash, - }); - - return success(transaction); - } - - async createUnsignedProtocolCall( - request: UpdateProfileImageRequest, - nonce?: Nonce, - ): Promise> { - const requestArg = this.resolveMutationRequestArg(request); - - const data = await this.createTypedData(requestArg, nonce); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data), - }); - } - - private async broadcast( - request: UpdateProfileImageRequest, - ): PromiseResult { - const requestArg = this.resolveMutationRequestArg(request); - - const { data } = await this.apolloClient.mutate< - CreateSetProfileImageUriViaDispatcherData, - CreateSetProfileImageUriViaDispatcherVariables - >({ - mutation: CreateSetProfileImageUriViaDispatcherDocument, - variables: { - request: requestArg, - }, - }); - - if (data.result.__typename === 'RelayError') { - const typedData = await this.createTypedData(requestArg); - const fallback = this.createRequestFallback(request, typedData); - - return handleRelayError(data.result, fallback); - } - - return success({ - indexingId: data.result.txId, - txHash: data.result.txHash, - }); - } - - private async createTypedData( - requestArg: UpdateProfileImageRequestArgs, - nonce?: Nonce, - ): Promise { - const { data } = await this.apolloClient.mutate< - CreateSetProfileImageUriTypedDataData, - CreateSetProfileImageUriTypedDataVariables - >({ - mutation: CreateSetProfileImageUriTypedDataDocument, - variables: { - request: requestArg, - options: nonce ? { overrideSigNonce: nonce } : undefined, - }, - }); - return data; - } - - private resolveMutationRequestArg( - request: UpdateProfileImageRequest, - ): UpdateProfileImageRequestArgs { - if ('signature' in request) { - return { - profileId: request.profileId, - nftData: { - id: request.signature.id, - signature: request.signature.signature, - }, - }; - } - return { - profileId: request.profileId, - url: request.url, - }; - } - - private createRequestFallback( - request: UpdateProfileImageRequest, - data: CreateSetProfileImageUriTypedDataData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.result.typedData.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('setProfileImageURI', [ - data.result.typedData.message.profileId, - data.result.typedData.message.imageURI, - ]); - return { - ...request, - contractAddress: data.result.typedData.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/ProfileMetadataCallGateway.ts b/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/ProfileMetadataCallGateway.ts deleted file mode 100644 index 7c00377aa5..0000000000 --- a/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/ProfileMetadataCallGateway.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { - CreateSetProfileMetadataTypedDataDocument, - CreateSetProfileMetadataTypedDataData, - CreateSetProfileMetadataTypedDataVariables, - CreateSetProfileMetadataViaDispatcherDocument, - CreateSetProfileMetadataViaDispatcherData, - CreateSetProfileMetadataViaDispatcherVariables, - GetProfileDocument, - GetProfileData, - GetProfileVariables, - omitTypename, - Profile, - CreatePublicSetProfileMetadataUriRequest, - SafeApolloClient, - ProfileMetadata, -} from '@lens-protocol/api-bindings'; -import { lensPeriphery } from '@lens-protocol/blockchain-bindings'; -import { NativeTransaction, Nonce, ProfileId } from '@lens-protocol/domain/entities'; -import { UpdateProfileDetailsRequest } from '@lens-protocol/domain/use-cases/profile'; -import { - IOnChainProtocolCallGateway, - BroadcastingError, - IDelegatedTransactionGateway, -} from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, failure, never, PromiseResult, success } from '@lens-protocol/shared-kernel'; -import { v4 } from 'uuid'; - -import { - MediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../../mediaTransforms'; -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { IMetadataUploader } from '../IMetadataUploader'; -import { ITransactionFactory } from '../ITransactionFactory'; -import { - Data, - SelfFundedProtocolTransactionRequest, -} from '../SelfFundedProtocolTransactionRequest'; -import { handleRelayError, OnChainBroadcastReceipt } from '../relayer'; -import { createProfileMetadata } from './createProfileMetadata'; - -export class ProfileMetadataCallGateway - implements - IDelegatedTransactionGateway, - IOnChainProtocolCallGateway -{ - constructor( - private readonly apolloClient: SafeApolloClient, - private readonly transactionFactory: ITransactionFactory, - private readonly uploader: IMetadataUploader, - private readonly mediaTransforms: MediaTransformsConfig, - ) {} - - async createDelegatedTransaction( - request: UpdateProfileDetailsRequest, - ): PromiseResult, BroadcastingError> { - const result = await this.broadcast(request); - - if (result.isFailure()) return failure(result.error); - - const receipt = result.value; - - const transaction = this.transactionFactory.createNativeTransaction({ - chainType: ChainType.POLYGON, - id: v4(), - request, - indexingId: receipt.indexingId, - txHash: receipt.txHash, - }); - - return success(transaction); - } - - async createUnsignedProtocolCall( - request: UpdateProfileDetailsRequest, - nonce?: Nonce, - ): Promise> { - const requestArg = await this.resolveCreateSetProfileMetadataUriRequest(request); - - const data = await this.createTypedData(requestArg, nonce); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data), - }); - } - - private async broadcast( - request: UpdateProfileDetailsRequest, - ): PromiseResult { - const requestArg = await this.resolveCreateSetProfileMetadataUriRequest(request); - - const { data } = await this.apolloClient.mutate< - CreateSetProfileMetadataViaDispatcherData, - CreateSetProfileMetadataViaDispatcherVariables - >({ - mutation: CreateSetProfileMetadataViaDispatcherDocument, - variables: { - request: requestArg, - }, - }); - - if (data.result.__typename === 'RelayError') { - const typedData = await this.createTypedData(requestArg); - const fallback = this.createRequestFallback(request, typedData); - - return handleRelayError(data.result, fallback); - } - - return success({ - indexingId: data.result.txId, - txHash: data.result.txHash, - }); - } - - private async createTypedData( - request: CreatePublicSetProfileMetadataUriRequest, - nonce?: Nonce, - ): Promise { - const { data } = await this.apolloClient.mutate< - CreateSetProfileMetadataTypedDataData, - CreateSetProfileMetadataTypedDataVariables - >({ - mutation: CreateSetProfileMetadataTypedDataDocument, - variables: { - request, - options: nonce ? { overrideSigNonce: nonce } : undefined, - }, - }); - - return data; - } - - private async resolveCreateSetProfileMetadataUriRequest( - request: UpdateProfileDetailsRequest, - ): Promise { - const existingProfile = await this.retrieveProfileDetails(request.profileId); - const metadataURI = await this.uploader.upload(createProfileMetadata(existingProfile, request)); - - return { - profileId: request.profileId, - metadata: metadataURI, - }; - } - - private async retrieveProfileDetails(profileId: ProfileId): Promise { - const { data } = await this.apolloClient.query({ - fetchPolicy: 'cache-first', - query: GetProfileDocument, - variables: { - // 'sources' and 'observerId' is not need as profile metadata is independent from observer profile and sources - request: { profileId }, - ...mediaTransformConfigToQueryVariables(this.mediaTransforms), - }, - }); - - return data.result ?? never(`Cannot update profile "${profileId}: profile not found`); - } - - private createRequestFallback( - request: UpdateProfileDetailsRequest, - data: CreateSetProfileMetadataTypedDataData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensPeriphery(data.result.typedData.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('setProfileMetadataURI', [ - data.result.typedData.message.profileId, - data.result.typedData.message.metadata, - ]); - return { - ...request, - contractAddress: data.result.typedData.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/__tests__/ProfileMetadataCallGateway.spec.ts b/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/__tests__/ProfileMetadataCallGateway.spec.ts deleted file mode 100644 index 8b56908e96..0000000000 --- a/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/__tests__/ProfileMetadataCallGateway.spec.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { faker } from '@faker-js/faker'; -import { Profile, RelayErrorReasons } from '@lens-protocol/api-bindings'; -import { - mockCreateSetProfileMetadataTypedDataResponse, - mockCreateSetProfileMetadataViaDispatcherResponse, - mockLensApolloClient, - mockCreateSetProfileMetadataTypedDataData, - mockGetProfileResponse, - mockProfileFragment, - mockRelayerResultFragment, - mockRelayErrorFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { NativeTransaction } from '@lens-protocol/domain/entities'; -import { mockNonce, mockUpdateProfileDetailsRequest } from '@lens-protocol/domain/mocks'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, Url } from '@lens-protocol/shared-kernel'; - -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../../../mediaTransforms'; -import { UnsignedProtocolCall } from '../../../../wallet/adapters/ConcreteWallet'; -import { - assertBroadcastingErrorResultWithRequestFallback, - assertUnsignedProtocolCallCorrectness, - mockIMetadataUploader, - mockITransactionFactory, -} from '../../__helpers__/mocks'; -import { ProfileMetadataCallGateway } from '../ProfileMetadataCallGateway'; - -function setupTestScenario({ - existingProfile, - otherMockedResponses = [], - uploadUrl, -}: { - existingProfile: Profile; - otherMockedResponses?: MockedResponse[]; - uploadUrl: Url; -}) { - const mediaTransforms = defaultMediaTransformsConfig; - const getProfilesByIdQueryMockedResponse = mockGetProfileResponse({ - variables: { - request: { profileId: existingProfile.id }, - sources: [], - ...mediaTransformConfigToQueryVariables(mediaTransforms), - }, - profile: existingProfile, - }); - - const apolloClient = mockLensApolloClient([ - getProfilesByIdQueryMockedResponse, - ...otherMockedResponses, - ]); - - const transactionFactory = mockITransactionFactory(); - const uploader = mockIMetadataUploader(uploadUrl); - - const gateway = new ProfileMetadataCallGateway( - apolloClient, - transactionFactory, - uploader, - mediaTransforms, - ); - - return { gateway, uploader }; -} - -const existingProfile = mockProfileFragment(); -const uploadUrl = faker.internet.url(); -const request = mockUpdateProfileDetailsRequest({ profileId: existingProfile.id }); - -describe(`Given an instance of the ${ProfileMetadataCallGateway.name}`, () => { - const data = mockCreateSetProfileMetadataTypedDataData(); - - describe(`when creating an IUnsignedProtocolCall via the "${ProfileMetadataCallGateway.prototype.createUnsignedProtocolCall.name}" method`, () => { - it(`should: - - create a new Profile Metadata updating the profile details - - upload it via the IMetadataUploader - - create an instance of the ${UnsignedProtocolCall.name} w/ the expected typed data`, async () => { - const { gateway, uploader } = setupTestScenario({ - existingProfile, - uploadUrl, - otherMockedResponses: [ - mockCreateSetProfileMetadataTypedDataResponse({ - request: { - profileId: request.profileId, - metadata: uploadUrl, - }, - data, - }), - ], - }); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request); - - expect(uploader.upload).toHaveBeenCalledWith( - expect.objectContaining({ - version: '1.0.0', - metadata_id: expect.any(String), - name: request.name, - bio: request.bio, - }), - ); - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - - it(`should be possible to override the signature nonce`, async () => { - const nonce = mockNonce(); - const { gateway } = setupTestScenario({ - existingProfile, - uploadUrl, - otherMockedResponses: [ - mockCreateSetProfileMetadataTypedDataResponse({ - request: { - profileId: request.profileId, - metadata: uploadUrl, - }, - overrideSigNonce: nonce, - }), - ], - }); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request, nonce); - - expect(unsignedCall.nonce).toEqual(nonce); - }); - }); - - describe(`when creating a ${NativeTransaction.name} via the "${ProfileMetadataCallGateway.prototype.createDelegatedTransaction.name}" method`, () => { - const request = mockUpdateProfileDetailsRequest({ profileId: existingProfile.id }); - - it(`should: - - create a new Profile Metadata updating the profile details - - upload it via the IMetadataUploader - - create a ${NativeTransaction.name} instance`, async () => { - const { gateway, uploader } = setupTestScenario({ - existingProfile, - uploadUrl, - otherMockedResponses: [ - mockCreateSetProfileMetadataViaDispatcherResponse({ - variables: { - request: { - profileId: request.profileId, - metadata: uploadUrl, - }, - }, - data: { - result: mockRelayerResultFragment(), - }, - }), - ], - }); - - const result = await gateway.createDelegatedTransaction(request); - - expect(uploader.upload).toHaveBeenCalledWith( - expect.objectContaining({ - version: '1.0.0', - metadata_id: expect.any(String), - name: request.name, - bio: request.bio, - }), - ); - expect(result.unwrap()).toBeInstanceOf(NativeTransaction); - expect(result.unwrap()).toMatchObject({ - id: expect.any(String), - chainType: ChainType.POLYGON, - request, - }); - }); - - it.each([ - mockRelayErrorFragment(RelayErrorReasons.Rejected), - mockRelayErrorFragment(RelayErrorReasons.NotAllowed), - ])( - `should fail w/ a ${BroadcastingError.name} in case of RelayError response with "$reason" reason`, - async (relayError) => { - const request = mockUpdateProfileDetailsRequest({ profileId: existingProfile.id }); - - const { gateway } = setupTestScenario({ - existingProfile, - uploadUrl, - otherMockedResponses: [ - mockCreateSetProfileMetadataViaDispatcherResponse({ - variables: { - request: { - profileId: request.profileId, - metadata: uploadUrl, - }, - }, - data: { - result: relayError, - }, - }), - - mockCreateSetProfileMetadataTypedDataResponse({ - request: { - profileId: request.profileId, - metadata: uploadUrl, - }, - data, - }), - ], - }); - - const result = await gateway.createDelegatedTransaction(request); - - assertBroadcastingErrorResultWithRequestFallback(result, data.result.typedData); - }, - ); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/__tests__/createProfileMetadata.spec.ts b/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/__tests__/createProfileMetadata.spec.ts deleted file mode 100644 index 47a6fcdd88..0000000000 --- a/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/__tests__/createProfileMetadata.spec.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { mockAttributeFragment, mockProfileFragment } from '@lens-protocol/api-bindings/mocks'; -import { mockUpdateProfileDetailsRequest } from '@lens-protocol/domain/mocks'; -import { never, UnknownObject } from '@lens-protocol/shared-kernel'; - -import { createProfileMetadata } from '../createProfileMetadata'; - -function expectedMetadata(others: UnknownObject) { - return { - version: '1.0.0', - metadata_id: expect.any(String), - - ...others, - }; -} - -describe(`Given the ${createProfileMetadata.name} helper`, () => { - describe(`when called with a profile data and a UpdateProfileDetailsRequest`, () => { - it('should create profile metadata with the new details as specified in the request', () => { - const profile = mockProfileFragment({ - __attributes: [], - }); - const request = mockUpdateProfileDetailsRequest({ profileId: profile.id }); - - const metadata = createProfileMetadata(profile, request); - - expect(metadata).toMatchObject( - expectedMetadata({ - name: request.name, - bio: request.bio, - cover_picture: request.coverPicture, - attributes: [], - }), - ); - }); - - it('should be able to preserve "bio" and "cover_picture" if they are not specified in the request', () => { - const profile = mockProfileFragment({ - __attributes: [], - }); - const request = mockUpdateProfileDetailsRequest({ - profileId: profile.id, - bio: undefined, - coverPicture: undefined, - }); - - const metadata = createProfileMetadata(profile, request); - - expect(metadata).toMatchObject( - expectedMetadata({ - bio: profile.bio, - cover_picture: - profile.coverPicture?.__typename === 'MediaSet' - ? profile.coverPicture.original.url - : never(), - }), - ); - }); - - it('should be able to delete "bio" and "cover_picture" by passing "null" into the request', () => { - const profile = mockProfileFragment({ - __attributes: [], - }); - const request = mockUpdateProfileDetailsRequest({ - profileId: profile.id, - bio: null, - coverPicture: null, - }); - - const metadata = createProfileMetadata(profile, request); - - expect(metadata).toMatchObject( - expectedMetadata({ - bio: null, - cover_picture: null, - }), - ); - }); - - it('should create profile metadata adding attributes as specified in the request', () => { - const profile = mockProfileFragment({ - __attributes: [], - }); - const request = mockUpdateProfileDetailsRequest({ - profileId: profile.id, - attributes: { - value: 42, - dob: new Date(0), - text: 'something', - result: true, - }, - }); - - const metadata = createProfileMetadata(profile, request); - - expect(metadata).toMatchObject( - expectedMetadata({ - attributes: [ - { - displayType: 'number', - key: 'value', - value: '42', - }, - { - displayType: 'date', - key: 'dob', - value: new Date(0).toISOString(), - }, - { - displayType: 'string', - key: 'text', - value: 'something', - }, - { - displayType: 'boolean', - key: 'result', - value: 'true', - }, - ], - }), - ); - }); - - it('should omit attributes that are marked with "null" in the request', () => { - const profile = mockProfileFragment({ - __attributes: [ - mockAttributeFragment({ - key: 'foo', - }), - ], - }); - const request = mockUpdateProfileDetailsRequest({ - profileId: profile.id, - attributes: { - foo: null, - bar: null, - }, - }); - - const metadata = createProfileMetadata(profile, request); - - expect(metadata).toMatchObject( - expectedMetadata({ - attributes: [], - }), - ); - }); - - it('should create profile metadata preserving attributes that might already have been there', () => { - const existingAttribute = mockAttributeFragment(); - const profile = mockProfileFragment({ - __attributes: [existingAttribute], - }); - const request = mockUpdateProfileDetailsRequest({ profileId: profile.id }); - - const metadata = createProfileMetadata(profile, request); - - expect(metadata).toMatchObject({ - attributes: [ - { - key: existingAttribute.key, - value: existingAttribute.value, - displayType: existingAttribute.displayType, - }, - ], - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/createProfileMetadata.ts b/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/createProfileMetadata.ts deleted file mode 100644 index ce824c4b5e..0000000000 --- a/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/createProfileMetadata.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { - Attribute, - Profile, - ProfileMetadataAttribute, - ProfileMetadata, -} from '@lens-protocol/api-bindings'; -import { - PartialAttributesUpdate, - ProfileAttributeValue, - UpdateProfileDetailsRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { v4 } from 'uuid'; - -function newAttribute(key: string, value: ProfileAttributeValue): ProfileMetadataAttribute { - if (value instanceof Date) { - return { - key, - value: value.toISOString(), - displayType: 'date', - }; - } - - return { - key, - value: value.toString(), - displayType: typeof value, - }; -} - -function extractCoverImageUrl(existingProfile: Profile): string | null { - return existingProfile.coverPicture?.__typename === 'MediaSet' - ? existingProfile.coverPicture.original.url - : null; -} - -function coalesce(lhs: T | undefined, rhs: T): T { - return lhs !== undefined ? lhs : rhs; -} - -function isProfileAttributeValue( - value: ProfileAttributeValue | null, -): value is ProfileAttributeValue { - return value !== null; -} - -function resolveAttributes(attributes: Attribute[], update: PartialAttributesUpdate = {}) { - const remainder = { ...update }; - const updated = attributes.reduce((acc, attribute) => { - const value = update[attribute.key]; - - if (value === undefined) { - acc.push(attribute); - return acc; - } - delete remainder[attribute.key]; - - if (value !== null) { - acc.push(newAttribute(attribute.key, value)); - } - return acc; - }, [] as ProfileMetadataAttribute[]); - - return [ - ...updated, - ...Object.entries(remainder) - .filter( - (entry: [string, ProfileAttributeValue | null]): entry is [string, ProfileAttributeValue] => - isProfileAttributeValue(entry[1]), - ) - .map(([key, value]) => newAttribute(key, value)), - ]; -} - -export function createProfileMetadata( - existingProfile: Profile, - request: UpdateProfileDetailsRequest, -): ProfileMetadata { - return { - version: '1.0.0', - metadata_id: v4(), - - attributes: resolveAttributes(existingProfile.__attributes ?? [], request.attributes), - bio: coalesce(request.bio, existingProfile.bio), - cover_picture: coalesce(request.coverPicture, extractCoverImageUrl(existingProfile)), - name: request.name, - }; -} diff --git a/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/index.ts b/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/index.ts deleted file mode 100644 index ac97ef7b2d..0000000000 --- a/packages/react-v1/src/transactions/adapters/ProfileMetadataCallGateway/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ProfileMetadataCallGateway } from './ProfileMetadataCallGateway'; diff --git a/packages/react-v1/src/transactions/adapters/PromiseResultPresenter.tsx b/packages/react-v1/src/transactions/adapters/PromiseResultPresenter.tsx deleted file mode 100644 index 5fef2a5dbf..0000000000 --- a/packages/react-v1/src/transactions/adapters/PromiseResultPresenter.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { IGenericResultPresenter } from '@lens-protocol/domain/use-cases/transactions'; -import { Deferred, IEquatableError, Result } from '@lens-protocol/shared-kernel'; - -export class PromiseResultPresenter - implements IGenericResultPresenter -{ - private deferredResult = new Deferred>(); - - present(result: Result): void { - this.deferredResult.resolve(result); - } - - asResult(): Promise> { - return this.deferredResult.promise; - } -} diff --git a/packages/react-v1/src/transactions/adapters/ProxyReceipt.ts b/packages/react-v1/src/transactions/adapters/ProxyReceipt.ts deleted file mode 100644 index 016757ed8a..0000000000 --- a/packages/react-v1/src/transactions/adapters/ProxyReceipt.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type ProxyReceipt = { - proxyId: string; -}; diff --git a/packages/react-v1/src/transactions/adapters/PublicationCacheManager.ts b/packages/react-v1/src/transactions/adapters/PublicationCacheManager.ts deleted file mode 100644 index caf233b4e8..0000000000 --- a/packages/react-v1/src/transactions/adapters/PublicationCacheManager.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { FetchPolicy } from '@apollo/client'; -import { - AnyPublication, - FragmentPublication, - GetPublicationData, - GetPublicationDocument, - GetPublicationVariables, - getSession, - isPostPublication, - Post, - SafeApolloClient, - SessionType, - Sources, -} from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; -import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; -import { TransactionData } from '@lens-protocol/domain/use-cases/transactions'; -import { invariant, OneOf } from '@lens-protocol/shared-kernel'; - -import { mediaTransformConfigToQueryVariables, MediaTransformsConfig } from '../../mediaTransforms'; -import { INewPostCacheManager } from './CreatePostPresenter'; -import { IUpdatePublicationCacheManager } from './IUpdatePublicationCacheManager'; - -type RequestPublicationArgs = OneOf<{ - publicationId: PublicationId; - txHash: string; -}>; - -export class PublicationCacheManager - implements IUpdatePublicationCacheManager, INewPostCacheManager -{ - constructor( - private readonly client: SafeApolloClient, - private readonly sources: Sources, - private readonly mediaTransforms: MediaTransformsConfig, - ) {} - - async fetchNewPost({ id, txHash }: TransactionData): Promise { - const publication = await this.request( - txHash ? { txHash } : { publicationId: id as PublicationId }, - 'network-only', - ); - - invariant(publication, `Publication not found`); - invariant(isPostPublication(publication), `Unexpected publication type`); - - return publication; - } - - update( - publicationId: PublicationId, - updateFn: (current: TPublication) => TPublication, - ) { - const id = this.client.cache.identify({ - __typename: 'Publication', - id: publicationId, - }); - - this.client.cache.updateFragment( - { - id, - fragmentName: 'Publication', - fragment: FragmentPublication, - }, - (data) => { - if (data) { - return updateFn(data); - } - return null; - }, - ); - } - - private async request(request: RequestPublicationArgs, fetchPolicy: FetchPolicy) { - const session = getSession(); - - const { data } = await this.client.query({ - query: GetPublicationDocument, - variables: { - request, - observerId: session?.type === SessionType.WithProfile ? session.profile.id : null, - sources: this.sources, - ...mediaTransformConfigToQueryVariables(this.mediaTransforms), - }, - fetchPolicy, - }); - - return data.result; - } -} diff --git a/packages/react-v1/src/transactions/adapters/SelfFundedProtocolCallGateway.ts b/packages/react-v1/src/transactions/adapters/SelfFundedProtocolCallGateway.ts deleted file mode 100644 index 4d19bd7ed2..0000000000 --- a/packages/react-v1/src/transactions/adapters/SelfFundedProtocolCallGateway.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { TransactionRequest } from '@ethersproject/providers'; -import { bigNumber } from '@lens-protocol/blockchain-bindings'; -import { Wallet, UnsignedTransaction } from '@lens-protocol/domain/entities'; -import { - IPayTransactionGateway, - ProtocolTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { Amount, ChainType } from '@lens-protocol/shared-kernel'; -import { v4 } from 'uuid'; - -import { ITransactionRequest } from '../../wallet/adapters/ConcreteWallet'; -import { IProviderFactory } from '../../wallet/adapters/IProviderFactory'; -import { - Eip1559GasPriceEstimator, - TransactionExecutionSpeed, -} from '../infrastructure/Eip1559GasPriceEstimator'; -import { SelfFundedProtocolTransactionRequest } from './SelfFundedProtocolTransactionRequest'; - -export class UnsignedSelfFundedProtocolCallTransaction< - TRequest extends ProtocolTransactionRequest, - TSelfFundedRequest extends SelfFundedProtocolTransactionRequest = SelfFundedProtocolTransactionRequest, - > - extends UnsignedTransaction - implements ITransactionRequest -{ - constructor(request: TSelfFundedRequest, readonly transactionRequest: TransactionRequest) { - super(v4(), ChainType.POLYGON, request); - } -} - -export class SelfFundedProtocolCallGateway< - TRequest extends ProtocolTransactionRequest, - TSelfFundedRequest extends SelfFundedProtocolTransactionRequest = SelfFundedProtocolTransactionRequest, -> implements IPayTransactionGateway -{ - constructor(private readonly providerFactory: IProviderFactory) {} - - async prepareSelfFundedTransaction( - request: TSelfFundedRequest, - wallet: Wallet, - ): Promise> { - const provider = await this.providerFactory.createProvider({ - chainType: ChainType.POLYGON, - }); - - const gasLimit = await provider.estimateGas({ - to: request.contractAddress, - from: wallet.address, - data: request.encodedData, - }); - - const gasEstimator = new Eip1559GasPriceEstimator(provider, (value) => Amount.matic(value)); - - const gasPriceEstimate = await gasEstimator.estimate(TransactionExecutionSpeed.FAST); - - const transactionRequest = { - to: request.contractAddress, - from: wallet.address, - data: request.encodedData, - gasLimit, - maxFeePerGas: bigNumber(gasPriceEstimate.maxFeePerGas), - maxPriorityFeePerGas: bigNumber(gasPriceEstimate.maxPriorityFeePerGas), - type: 2, // EIP-1559 - }; - - return new UnsignedSelfFundedProtocolCallTransaction(request, transactionRequest); - } -} diff --git a/packages/react-v1/src/transactions/adapters/SelfFundedProtocolTransactionRequest.ts b/packages/react-v1/src/transactions/adapters/SelfFundedProtocolTransactionRequest.ts deleted file mode 100644 index 360f5d66be..0000000000 --- a/packages/react-v1/src/transactions/adapters/SelfFundedProtocolTransactionRequest.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ProtocolTransactionRequestModel } from '@lens-protocol/domain/entities'; -import { Brand, Distribute, EthereumAddress } from '@lens-protocol/shared-kernel'; - -export type Data = Brand; - -/** - * @internal - * @privateRemarks intentionally not exported - */ -type RawTransactionDetails = { - contractAddress: EthereumAddress; - encodedData: Data; -}; - -export type SelfFundedProtocolTransactionRequest = - Distribute; diff --git a/packages/react-v1/src/transactions/adapters/TransactionQueuePresenter.tsx b/packages/react-v1/src/transactions/adapters/TransactionQueuePresenter.tsx deleted file mode 100644 index c537e4e28c..0000000000 --- a/packages/react-v1/src/transactions/adapters/TransactionQueuePresenter.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { recentTransactionsVar, TxStatus, TransactionState } from '@lens-protocol/api-bindings'; -import { TransactionError } from '@lens-protocol/domain/entities'; -import { - ITransactionQueuePresenter, - AnyTransactionRequest, - TransactionData, -} from '@lens-protocol/domain/use-cases/transactions'; -import { CausedError } from '@lens-protocol/shared-kernel'; - -import { ErrorHandler } from '../../ErrorHandler'; - -/** - * Error thrown when a transaction fails - */ -export class FailedTransactionError extends CausedError { - readonly data?: TransactionData; - - constructor(cause: TransactionError, data: TransactionData) { - super(`Failed ${data.request.kind} transaction due to ${cause.reason}`, { cause }); - - this.data = data; - } -} - -type PartialTransactionStateUpdate = Partial>; - -export class TransactionQueuePresenter - implements ITransactionQueuePresenter -{ - constructor(private readonly errorHandler: ErrorHandler) {} - - clearRecent(): void { - const transactions = recentTransactionsVar(); - const filteredTransactions = transactions.filter( - (tx) => tx.status !== TxStatus.FAILED && tx.status !== TxStatus.SETTLED, - ); - - recentTransactionsVar(filteredTransactions); - } - - pending(data: TransactionData): void { - if (recentTransactionsVar().find(({ id }) => id === data.id)) { - this.updateById(data.id, { - ...data, - status: TxStatus.MINING, - }); - } else { - this.addTransaction({ - id: data.id, - status: TxStatus.MINING, - request: data.request, - txHash: data.txHash, - }); - } - } - - settled(data: TransactionData): void { - this.updateById(data.id, { status: TxStatus.SETTLED }); - } - - failed(error: TransactionError, data: TransactionData): void { - this.errorHandler(new FailedTransactionError(error, data)); - this.updateById(data.id, { status: TxStatus.FAILED }); - } - - private addTransaction(data: TransactionState) { - const transactions = recentTransactionsVar(); - recentTransactionsVar([data, ...transactions]); - } - - private updateById(id: string, update: PartialTransactionStateUpdate) { - const transactions = recentTransactionsVar(); - - recentTransactionsVar( - transactions.map((data) => { - if (id === data.id) { - return { - ...data, - ...update, - } as TransactionState; - } - return data; - }), - ); - } -} diff --git a/packages/react-v1/src/transactions/adapters/TransactionResultPresenter.ts b/packages/react-v1/src/transactions/adapters/TransactionResultPresenter.ts deleted file mode 100644 index c1f377cb0e..0000000000 --- a/packages/react-v1/src/transactions/adapters/TransactionResultPresenter.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { AnyTransactionRequestModel, TransactionError } from '@lens-protocol/domain/entities'; -import { - ITransactionResultPresenter, - TransactionData, -} from '@lens-protocol/domain/use-cases/transactions'; -import { - Deferred, - failure, - Failure, - IEquatableError, - Result, - success, -} from '@lens-protocol/shared-kernel'; - -import { AsyncTransactionResult } from './AsyncTransactionResult'; - -export class TransactionResultPresenter< - TRequest extends AnyTransactionRequestModel, - TError extends IEquatableError, -> implements ITransactionResultPresenter -{ - private earlyFailure: Failure | null = null; - - private deferredResult = new Deferred>(); - - present(result: Result, TError | TransactionError>): void { - if (result.isFailure()) { - if (result.error instanceof TransactionError) { - this.deferredResult.resolve(failure(result.error)); - return; - } - this.earlyFailure = failure(result.error); - return; - } - - this.deferredResult.resolve(success()); - } - - asResult(): Result, TError> { - if (this.earlyFailure) { - return this.earlyFailure; - } - - return success({ - waitForCompletion: async () => { - return this.deferredResult.promise; - }, - }); - } -} diff --git a/packages/react-v1/src/transactions/adapters/UnfollowProfileCallGateway.ts b/packages/react-v1/src/transactions/adapters/UnfollowProfileCallGateway.ts deleted file mode 100644 index f82d4ce693..0000000000 --- a/packages/react-v1/src/transactions/adapters/UnfollowProfileCallGateway.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { - CreateUnfollowTypedDataDocument, - CreateUnfollowTypedDataData, - CreateUnfollowTypedDataVariables, - SafeApolloClient, - omitTypename, -} from '@lens-protocol/api-bindings'; -import { lensFollowNFT } from '@lens-protocol/blockchain-bindings'; -import { UnfollowRequest } from '@lens-protocol/domain/use-cases/profile'; -import { IOnChainProtocolCallGateway } from '@lens-protocol/domain/use-cases/transactions'; - -import { UnsignedProtocolCall } from '../../wallet/adapters/ConcreteWallet'; -import { Data, SelfFundedProtocolTransactionRequest } from './SelfFundedProtocolTransactionRequest'; - -export class UnfollowProfileCallGateway implements IOnChainProtocolCallGateway { - constructor(private apolloClient: SafeApolloClient) {} - - async createUnsignedProtocolCall( - request: UnfollowRequest, - ): Promise> { - const { data } = await this.apolloClient.mutate< - CreateUnfollowTypedDataData, - CreateUnfollowTypedDataVariables - >({ - mutation: CreateUnfollowTypedDataDocument, - variables: { - request: { - profile: request.profileId, - }, - }, - }); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data), - }); - } - - private createRequestFallback( - request: UnfollowRequest, - data: CreateUnfollowTypedDataData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensFollowNFT(data.result.typedData.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('burn', [ - data.result.typedData.message.tokenId, - ]); - return { - ...request, - contractAddress: data.result.typedData.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/__helpers__/mocks.ts b/packages/react-v1/src/transactions/adapters/__helpers__/mocks.ts deleted file mode 100644 index d5d694da77..0000000000 --- a/packages/react-v1/src/transactions/adapters/__helpers__/mocks.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { omitTypename, Profile } from '@lens-protocol/api-bindings'; -import { TypedData } from '@lens-protocol/blockchain-bindings'; -import { - ProtocolTransactionRequestModel, - ProxyActionStatus, - AnyTransactionRequestModel, - ProfileId, -} from '@lens-protocol/domain/entities'; -import { - mockNonce, - mockTransactionHash, - mockAnyTransactionRequestModel, - mockProtocolTransactionRequestModel, -} from '@lens-protocol/domain/mocks'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { assertFailure, ChainType, never, Result, Url } from '@lens-protocol/shared-kernel'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; -import { mock } from 'jest-mock-extended'; -import { when } from 'jest-when'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { ITransactionObserver, TransactionFactory } from '../../infrastructure/TransactionFactory'; -import { IMetadataUploader } from '../IMetadataUploader'; -import { IProfileCacheManager } from '../IProfileCacheManager'; -import { - MetaTransactionData, - NativeTransactionData, - ProxyTransactionData, -} from '../ITransactionFactory'; -import { - Data, - SelfFundedProtocolTransactionRequest, -} from '../SelfFundedProtocolTransactionRequest'; -import { OnChainBroadcastReceipt } from '../relayer'; - -export function mockITransactionFactory( - transactionObserver: ITransactionObserver = mock(), -) { - // we create a TransactionFactory instance so to minimize the amount of mocking required, - // although consumers can still rely solely on the ITransactionFactory interface - return new TransactionFactory(transactionObserver); -} - -export function mockRelayReceipt(): OnChainBroadcastReceipt { - return { - indexingId: faker.datatype.uuid(), - txHash: mockTransactionHash(), - }; -} - -export function mockTypedData(): TypedData { - return { - types: { - CreateProfileWithSig: [{ name: 'foo', type: 'string' }], - }, - domain: { - name: 'none', - version: '1', - chainId: 1, - verifyingContract: mockEthereumAddress(), - }, - message: { - nonce: 0, - }, - }; -} - -export function mockMetaTransactionData({ - request = mockProtocolTransactionRequestModel() as T, - ...others -}: Partial> = {}): MetaTransactionData { - return { - chainType: ChainType.ETHEREUM, - id: faker.datatype.uuid(), - indexingId: faker.datatype.uuid(), - nonce: mockNonce(), - request, - txHash: mockTransactionHash(), - ...others, - }; -} - -export function mockNativeTransactionData({ - request = mockAnyTransactionRequestModel() as T, - ...others -}: Partial> = {}): NativeTransactionData { - return { - chainType: ChainType.ETHEREUM, - id: faker.datatype.uuid(), - request, - txHash: mockTransactionHash(), - ...others, - }; -} - -export function mockNativeTransactionDataWithIndexingId< - T extends AnyTransactionRequestModel, ->(): Required> { - return { - chainType: ChainType.ETHEREUM, - id: faker.datatype.uuid(), - indexingId: faker.datatype.uuid(), - request: mockAnyTransactionRequestModel() as T, - txHash: mockTransactionHash(), - }; -} - -export function mockProxyTransactionData({ - request = mockAnyTransactionRequestModel() as T, - ...others -}: Partial> = {}): ProxyTransactionData { - return { - status: ProxyActionStatus.MINTING, - chainType: ChainType.ETHEREUM, - proxyId: faker.datatype.uuid(), - id: faker.datatype.uuid(), - request, - txHash: mockTransactionHash(), - ...others, - }; -} - -export function mockIMetadataUploader(urlOrError: Url | Error): IMetadataUploader { - const uploader = mock>(); - - if (urlOrError instanceof Error) { - when(uploader.upload).mockRejectedValue(urlOrError); - } else { - when(uploader.upload).mockResolvedValue(urlOrError); - } - - return uploader; -} - -export function assertUnsignedProtocolCallCorrectness( - unsignedProtocolCall: UnsignedProtocolCall, - broadcastResult: { - id: string; - typedData: TypedData; - }, -) { - expect(unsignedProtocolCall.id).toEqual(broadcastResult.id); - expect(unsignedProtocolCall.typedData).toEqual(omitTypename(broadcastResult.typedData)); -} - -export function assertBroadcastingErrorResultWithRequestFallback( - result: Result, - typedData: TypedData, -) { - assertFailure(result); - expect(result.error).toBeInstanceOf(BroadcastingError); - expect(result.error.fallback).toMatchObject({ - contractAddress: typedData.domain.verifyingContract, - encodedData: expect.any(String), - }); -} - -export function mockSelfFundedProtocolTransactionRequest< - TRequest extends ProtocolTransactionRequestModel, ->(): SelfFundedProtocolTransactionRequest { - return { - contractAddress: mockEthereumAddress(), - encodedData: faker.datatype.hexadecimal({ length: 32 }) as Data, - ...mockAnyTransactionRequestModel(), - } as SelfFundedProtocolTransactionRequest; -} - -class MockedProfileCacheManager implements IProfileCacheManager { - constructor(profile: Profile) { - this.latestProfile = profile; - } - - latestProfile: Profile; - - fetchProfile = jest.fn().mockImplementation(async () => this.latestProfile); - - fetchNewProfile = jest.fn().mockImplementation(async () => this.latestProfile); - - refreshProfile = jest.fn().mockImplementation(async () => this.latestProfile); - - updateProfile = jest.fn((_: ProfileId, updateFn: (current: Profile) => Profile) => { - this.latestProfile = updateFn(this.latestProfile ?? never()); - }); -} - -export function mockIProfileCacheManager(profile: Profile) { - return new MockedProfileCacheManager(profile); -} diff --git a/packages/react-v1/src/transactions/adapters/__tests__/ApproveTransactionGateway.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/ApproveTransactionGateway.spec.ts deleted file mode 100644 index ea9f0c8415..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/ApproveTransactionGateway.spec.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* - * @jest-environment node - */ -import { erc20 } from '@lens-protocol/blockchain-bindings'; -import { mockTokenAllowanceRequest, mockWallet } from '@lens-protocol/domain/mocks'; -import { - TokenAllowanceLimit, - TokenAllowanceRequest, -} from '@lens-protocol/domain/use-cases/wallets'; -import { MockProvider } from 'ethereum-waffle'; -import { BigNumber, constants, providers, utils } from 'ethers'; - -import { mockIProviderFactory } from '../../../wallet/adapters/__helpers__/mocks'; -import { - ApproveTransactionGateway, - UnsignedApproveTransaction, -} from '../ApproveTransactionGateway'; - -function setupApproveTransactionGateway({ - request, - provider, -}: { - request: TokenAllowanceRequest; - provider: providers.JsonRpcProvider; -}) { - const providerFactory = mockIProviderFactory({ - chainType: request.amount.asset.chainType, - provider, - }); - - return new ApproveTransactionGateway(providerFactory); -} - -async function mineNBlocks(provider: MockProvider, blocks: number) { - return provider.send('evm_mine', [{ blocks }]); -} - -describe(`Given an instance of the ${ApproveTransactionGateway.name}`, () => { - const wallet = mockWallet(); - - describe(`when creating an approve transaction for an exact amount`, () => { - it(`should succeed with the expected ${UnsignedApproveTransaction.name}`, async () => { - const request = mockTokenAllowanceRequest({ - limit: TokenAllowanceLimit.EXACT, - }); - const provider = new MockProvider({ - ganacheOptions: { - chain: { - hardfork: 'london', - }, - }, - }); - await mineNBlocks(provider, 20); - const approveTransactionGateway = setupApproveTransactionGateway({ - request, - provider, - }); - - const unsignedTransaction = await approveTransactionGateway.createApproveTransaction( - request, - wallet, - ); - - expect(unsignedTransaction).toBeInstanceOf(UnsignedApproveTransaction); - expect(unsignedTransaction).toEqual({ - chainType: request.amount.asset.chainType, - id: expect.any(String), - request, - transactionRequest: expect.objectContaining({ - data: erc20(request.amount.asset.address, provider).interface.encodeFunctionData( - 'approve', - [request.spender, utils.parseEther(request.amount.toSignificantDigits())], - ), - gasLimit: expect.any(BigNumber), - maxFeePerGas: expect.any(BigNumber), - maxPriorityFeePerGas: expect.any(BigNumber), - from: wallet.address, - type: 2, // EIP-1559 - }), - }); - }); - }); - - describe(`when creating an infinite approve transaction`, () => { - it(`should succeed with the expected ${UnsignedApproveTransaction.name}`, async () => { - const request = mockTokenAllowanceRequest({ - limit: TokenAllowanceLimit.INFINITE, - }); - const provider = new MockProvider({ - ganacheOptions: { - chain: { - hardfork: 'london', - }, - }, - }); - await mineNBlocks(provider, 20); - const approveTransactionGateway = setupApproveTransactionGateway({ - request, - provider, - }); - - const unsignedTransaction = await approveTransactionGateway.createApproveTransaction( - request, - wallet, - ); - - expect(unsignedTransaction).toBeInstanceOf(UnsignedApproveTransaction); - expect(unsignedTransaction).toEqual({ - chainType: request.amount.asset.chainType, - id: expect.any(String), - request, - transactionRequest: expect.objectContaining({ - data: erc20(request.amount.asset.address, provider).interface.encodeFunctionData( - 'approve', - [request.spender, constants.MaxUint256], - ), - gasLimit: expect.any(BigNumber), - maxFeePerGas: expect.any(BigNumber), - maxPriorityFeePerGas: expect.any(BigNumber), - from: wallet.address, - type: 2, // EIP-1559 - }), - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/CollectPublicationGateway.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/CollectPublicationGateway.spec.ts deleted file mode 100644 index 9af96fae8d..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/CollectPublicationGateway.spec.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { - CreateCollectTypedDataData, - CreateCollectTypedDataDocument, - CreateCollectTypedDataVariables, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; -import { - createBroadcastProxyActionCallMockedError, - mockBroadcastProxyActionCallResponse, - mockLensApolloClient, - mockCreateCollectTypedDataData, -} from '@lens-protocol/api-bindings/mocks'; -import { ProxyActionStatus, ProxyTransaction } from '@lens-protocol/domain/entities'; -import { mockFreeCollectRequest, mockNonce } from '@lens-protocol/domain/mocks'; -import { FreeCollectRequest } from '@lens-protocol/domain/use-cases/publications'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, ILogger, success } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { ITransactionObserver } from '../../infrastructure/TransactionFactory'; -import { CollectPublicationGateway } from '../CollectPublicationGateway'; -import { ITransactionFactory } from '../ITransactionFactory'; -import { - assertUnsignedProtocolCallCorrectness, - mockITransactionFactory, -} from '../__helpers__/mocks'; - -jest.mock('@lens-protocol/shared-kernel', () => { - // eslint-disable-next-line - const actual = jest.requireActual('@lens-protocol/shared-kernel'); - - // eslint-disable-next-line - return { - ...actual, - getID: jest.fn(() => 'id'), - }; -}); - -function mockITransactionObserver() { - const observer = mock(); - observer.waitForProxyTransactionStatus.mockResolvedValue( - success({ txHash: 'tx-hash', status: ProxyActionStatus.MINTING, txId: 'tx-id' }), - ); - return observer; -} - -function mockCollectPublicationGateway({ - apollo, - factory, -}: { - apollo: SafeApolloClient; - factory: ITransactionFactory; -}) { - return new CollectPublicationGateway(apollo, factory, mock()); -} - -function mockmockCollectTypedDatMutationResponse({ - variables, - data, -}: { - variables: CreateCollectTypedDataVariables; - data: CreateCollectTypedDataData; -}): MockedResponse { - return { - request: { - query: CreateCollectTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -describe(`Given an instance of the ${CollectPublicationGateway.name}`, () => { - const request = mockFreeCollectRequest(); - - describe(`when calling the "${CollectPublicationGateway.prototype.createUnsignedProtocolCall.name}"`, () => { - it(`should create an "${UnsignedProtocolCall.name}" w/ the expected typed data`, async () => { - const data = mockCreateCollectTypedDataData(); - - const apollo = mockLensApolloClient([ - mockmockCollectTypedDatMutationResponse({ - variables: { - request: { - publicationId: request.publicationId, - }, - }, - data, - }), - ]); - - const mockTransactionObserver = mockITransactionObserver(); - const factory = mockITransactionFactory(mockTransactionObserver); - const collectPublicationGateway = mockCollectPublicationGateway({ - apollo, - factory, - }); - const unsignedCall = await collectPublicationGateway.createUnsignedProtocolCall(request); - - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - - it(`should be possible to override the signature nonce`, async () => { - const nonce = mockNonce(); - const apollo = mockLensApolloClient([ - mockmockCollectTypedDatMutationResponse({ - variables: { - request: { - publicationId: request.publicationId, - }, - options: { - overrideSigNonce: nonce, - }, - }, - data: mockCreateCollectTypedDataData({ nonce }), - }), - ]); - - const mockTransactionObserver = mockITransactionObserver(); - const factory = mockITransactionFactory(mockTransactionObserver); - const collectPublicationGateway = mockCollectPublicationGateway({ - apollo, - factory, - }); - const unsignedCall = await collectPublicationGateway.createUnsignedProtocolCall( - request, - nonce, - ); - - expect(unsignedCall.nonce).toEqual(nonce); - }); - }); - - describe(`when relaying a FreeCollectRequest via the "${CollectPublicationGateway.prototype.createProxyTransaction.name}" method`, () => { - const request = mockFreeCollectRequest(); - it(`should succeed with ${ProxyTransaction.name} on Polygon`, async () => { - const indexingId = 'indexing-id'; - const apollo = mockLensApolloClient([ - mockBroadcastProxyActionCallResponse({ - result: indexingId, - variables: { - request: { - collect: { - freeCollect: { - publicationId: request.publicationId, - }, - }, - }, - }, - }), - ]); - - const mockTransactionObserver = mockITransactionObserver(); - const factory = mockITransactionFactory(mockTransactionObserver); - const collectPublicationGateway = mockCollectPublicationGateway({ - apollo, - factory, - }); - - const transactionResult = await collectPublicationGateway.createProxyTransaction(request); - - if (transactionResult.isFailure()) throw transactionResult.error; - - const transaction = transactionResult.value; - - await transaction.waitNextEvent(); - - expect(transaction).toEqual( - expect.objectContaining({ - chainType: ChainType.POLYGON, - id: 'id', - request, - status: ProxyActionStatus.MINTING, - }), - ); - - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - expect((transaction as any).state.proxyId).toEqual(indexingId); - }); - it(`should fail with ${BroadcastingError.name} in the case of a broadcast failure`, async () => { - const apollo = mockLensApolloClient([ - createBroadcastProxyActionCallMockedError({ - errorMessage: 'Failed to broadcast proxy action call', - variables: { - request: { - collect: { - freeCollect: { - publicationId: request.publicationId, - }, - }, - }, - }, - }), - mockmockCollectTypedDatMutationResponse({ - variables: { - request: { - publicationId: request.publicationId, - }, - }, - data: mockCreateCollectTypedDataData(), - }), - ]); - - const mockTransactionObserver = mockITransactionObserver(); - const factory = mockITransactionFactory(mockTransactionObserver); - const collectPublicationGateway = mockCollectPublicationGateway({ - apollo, - factory, - }); - - const transactionResult = await collectPublicationGateway.createProxyTransaction(request); - - if (transactionResult.isSuccess()) throw new Error('Expected transaction to fail'); - - expect(transactionResult.error).toEqual( - new BroadcastingError('Failed to broadcast proxy action call'), - ); - expect(transactionResult.error.fallback).toEqual( - expect.objectContaining({ - ...request, - }), - ); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/CreatePostPresenter.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/CreatePostPresenter.spec.ts deleted file mode 100644 index 24e6a0c9a2..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/CreatePostPresenter.spec.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { mockPostFragment } from '@lens-protocol/api-bindings/mocks'; -import { TransactionError, TransactionErrorReason } from '@lens-protocol/domain/entities'; -import { mockCreatePostRequest, mockTransactionData } from '@lens-protocol/domain/mocks'; -import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; -import { BroadcastingError, TransactionData } from '@lens-protocol/domain/use-cases/transactions'; -import { failure, Result, success } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; - -import { CreatePostPresenter, INewPostCacheManager } from '../CreatePostPresenter'; - -function setupTestScenario() { - const cacheManager = mock(); - - const presenter = new CreatePostPresenter(cacheManager); - - return { - cacheManager, - presenter, - }; -} - -describe(`Given an instance of the ${CreatePostPresenter.name}`, () => { - describe.each([new BroadcastingError('error')])( - `and the "${CreatePostPresenter.prototype.present.name}" method is called with failure($name)`, - (error) => { - const result: Result = failure(error); - - describe(`when the "${CreatePostPresenter.prototype.asResult.name}" is called`, () => { - it(`should eagerly return the failure`, async () => { - const { presenter } = setupTestScenario(); - - await presenter.present(result); - - expect(presenter.asResult()).toEqual(result); - }); - }); - }, - ); - - describe(`and the "${CreatePostPresenter.prototype.asResult.name}" method is called`, () => { - describe(`when the "${CreatePostPresenter.prototype.present.name}" method is subsequently called`, () => { - describe(`with failure(${TransactionError.name})`, () => { - const result: Result = failure( - new TransactionError(TransactionErrorReason.REVERTED), - ); - - it('should yield the failure as result of the "waitForCompletion" callback', async () => { - const { presenter } = setupTestScenario(); - - const broadcasted = presenter.asResult(); - - const [completion] = await Promise.all([ - broadcasted.unwrap().waitForCompletion(), - presenter.present(result), - ]); - - expect(completion).toEqual(result); - }); - }); - - describe(`with success(TransactionData)`, () => { - const request = mockCreatePostRequest(); - const result: Result, never> = success( - mockTransactionData({ request }), - ); - const post = mockPostFragment(); - - it('should fetch and return the newly create Profile as result of the "waitForCompletion" callback', async () => { - const { cacheManager, presenter } = setupTestScenario(); - cacheManager.fetchNewPost.mockResolvedValue(post); - - const broadcasted = presenter.asResult(); - - const [completion] = await Promise.all([ - broadcasted.unwrap().waitForCompletion(), - presenter.present(result), - ]); - - expect(completion).toEqual(success(post)); - }); - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/DispatcherConfigCallGateway.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/DispatcherConfigCallGateway.spec.ts deleted file mode 100644 index 76a50b8068..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/DispatcherConfigCallGateway.spec.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { - CreateSetDispatcherTypedDataDocument, - CreateSetDispatcherTypedDataData, - CreateSetDispatcherTypedDataVariables, -} from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockCreateSetDispatcherTypedDataData, -} from '@lens-protocol/api-bindings/mocks'; -import { mockNonce, mockUpdateDispatcherConfigRequest } from '@lens-protocol/domain/mocks'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { DispatcherConfigCallGateway } from '../DispatcherConfigCallGateway'; -import { assertUnsignedProtocolCallCorrectness } from '../__helpers__/mocks'; - -function mockmockSetDispatcherTypedDataMutationResponse({ - variables, - data, -}: { - variables: CreateSetDispatcherTypedDataVariables; - data: CreateSetDispatcherTypedDataData; -}): MockedResponse { - return { - request: { - query: CreateSetDispatcherTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -describe(`Given an instance of the ${DispatcherConfigCallGateway.name}`, () => { - describe(`when calling the "${DispatcherConfigCallGateway.prototype.createUnsignedProtocolCall.name}" method`, () => { - it(`should create an "${UnsignedProtocolCall.name}" w/ the expected typed data`, async () => { - const request = mockUpdateDispatcherConfigRequest(); - - const data = mockCreateSetDispatcherTypedDataData(); - - const apollo = mockLensApolloClient([ - mockmockSetDispatcherTypedDataMutationResponse({ - variables: { - request: { - profileId: request.profileId, - enable: request.enabled, - }, - }, - data, - }), - ]); - - const dispatcherConfigCallGateway = new DispatcherConfigCallGateway(apollo); - - const unsignedCall = await dispatcherConfigCallGateway.createUnsignedProtocolCall(request); - - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - - it('should be possible to override the signature nonce', async () => { - const request = mockUpdateDispatcherConfigRequest(); - - const nonce = mockNonce(); - - const apollo = mockLensApolloClient([ - mockmockSetDispatcherTypedDataMutationResponse({ - variables: { - request: { - profileId: request.profileId, - enable: request.enabled, - }, - options: { - overrideSigNonce: nonce, - }, - }, - data: mockCreateSetDispatcherTypedDataData({ nonce }), - }), - ]); - const dispatcherConfigCallGateway = new DispatcherConfigCallGateway(apollo); - - const unsignedCall = await dispatcherConfigCallGateway.createUnsignedProtocolCall( - request, - nonce, - ); - - expect(unsignedCall.nonce).toEqual(nonce); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/FollowPolicyCallGateway.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/FollowPolicyCallGateway.spec.ts deleted file mode 100644 index 3289e95ebe..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/FollowPolicyCallGateway.spec.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { - CreateSetFollowModuleTypedDataDocument, - CreateSetFollowModuleTypedDataData, - CreateSetFollowModuleTypedDataVariables, - FollowModuleParams, -} from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockCreateSetFollowModuleTypedDataData, -} from '@lens-protocol/api-bindings/mocks'; -import { - mockChargeFollowConfig, - mockNoFeeFollowConfig, - mockNonce, - mockUpdateFollowPolicyRequest, -} from '@lens-protocol/domain/mocks'; -import { - FollowPolicyType, - UpdateFollowPolicyRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { never } from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { FollowPolicyCallGateway } from '../FollowPolicyCallGateway'; -import { assertUnsignedProtocolCallCorrectness } from '../__helpers__/mocks'; - -function mockCreateSetFollowModuleTypedDataResponse({ - variables, - data, -}: { - variables: CreateSetFollowModuleTypedDataVariables; - data: CreateSetFollowModuleTypedDataData; -}): MockedResponse { - return { - request: { - query: CreateSetFollowModuleTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -describe(`Given an instance of the ${FollowPolicyCallGateway.name}`, () => { - describe.each<{ - description: string; - policy: UpdateFollowPolicyRequest['policy']; - expectedFollowModule: (policy: UpdateFollowPolicyRequest['policy']) => FollowModuleParams; - }>([ - { - description: 'to enable follow fees', - policy: mockChargeFollowConfig(), - expectedFollowModule: (policy) => ({ - feeFollowModule: - policy.type === FollowPolicyType.CHARGE - ? { - amount: { - currency: policy.amount.asset.address, - value: policy.amount.toSignificantDigits(), - }, - recipient: policy.recipient, - } - : never(), - }), - }, - { - description: 'to disable follow fees', - policy: mockNoFeeFollowConfig(), - expectedFollowModule: () => ({ - freeFollowModule: true, - }), - }, - ])( - `when calling the "${FollowPolicyCallGateway.prototype.createUnsignedProtocolCall.name}" method $description`, - ({ policy, expectedFollowModule }) => { - const request = mockUpdateFollowPolicyRequest({ policy }); - - it(`should create an "${UnsignedProtocolCall.name}" w/ the expected typed data`, async () => { - const data = mockCreateSetFollowModuleTypedDataData(); - - const apollo = mockLensApolloClient([ - mockCreateSetFollowModuleTypedDataResponse({ - variables: { - request: { - profileId: request.profileId, - followModule: expectedFollowModule(request.policy), - }, - }, - data, - }), - ]); - const followFeeTransactionGateway = new FollowPolicyCallGateway(apollo); - - const unsignedCall = await followFeeTransactionGateway.createUnsignedProtocolCall(request); - - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - - it(`should be possible to override the signature nonce`, async () => { - const nonce = mockNonce(); - const apollo = mockLensApolloClient([ - mockCreateSetFollowModuleTypedDataResponse({ - variables: { - request: { - profileId: request.profileId, - followModule: expectedFollowModule(request.policy), - }, - options: { - overrideSigNonce: nonce, - }, - }, - data: mockCreateSetFollowModuleTypedDataData({ nonce }), - }), - ]); - const followFeeTransactionGateway = new FollowPolicyCallGateway(apollo); - - const unsignedCall = await followFeeTransactionGateway.createUnsignedProtocolCall( - request, - nonce, - ); - - expect(unsignedCall.nonce).toEqual(nonce); - }); - }, - ); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/FollowProfilesGateway.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/FollowProfilesGateway.spec.ts deleted file mode 100644 index 84d2d79d90..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/FollowProfilesGateway.spec.ts +++ /dev/null @@ -1,305 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { - CreateFollowTypedDataDocument, - CreateFollowTypedDataData, - CreateFollowTypedDataVariables, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; -import { - mockCreateFollowTypedDataData, - mockLensApolloClient, - mockBroadcastProxyActionCallResponse, - createBroadcastProxyActionCallMockedError, -} from '@lens-protocol/api-bindings/mocks'; -import { ProxyActionStatus, ProxyTransaction } from '@lens-protocol/domain/entities'; -import { - mockNonce, - mockPaidFollowRequest, - mockProfileOwnerFollowRequest, - mockUnconstrainedFollowRequest, -} from '@lens-protocol/domain/mocks'; -import { UnconstrainedFollowRequest } from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, ILogger, success } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { ITransactionObserver } from '../../infrastructure/TransactionFactory'; -import { FollowProfilesGateway } from '../FollowProfilesGateway'; -import { ITransactionFactory } from '../ITransactionFactory'; -import { - assertUnsignedProtocolCallCorrectness, - mockITransactionFactory, -} from '../__helpers__/mocks'; - -jest.mock('@lens-protocol/shared-kernel', () => { - // eslint-disable-next-line - const actual = jest.requireActual('@lens-protocol/shared-kernel'); - - // eslint-disable-next-line - return { - ...actual, - getID: jest.fn(() => 'id'), - }; -}); - -function mockCreateFollowTypedDataMutationResponse({ - variables, - data, -}: { - variables: CreateFollowTypedDataVariables; - data: CreateFollowTypedDataData; -}): MockedResponse { - return { - request: { - query: CreateFollowTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -function mockITransactionObserver() { - const observer = mock(); - observer.waitForProxyTransactionStatus.mockResolvedValue( - success({ txHash: 'tx-hash', status: ProxyActionStatus.MINTING, txId: 'tx-id' }), - ); - return observer; -} - -function mockFollowProfilesGateway({ - apollo, - factory, -}: { - apollo: SafeApolloClient; - factory: ITransactionFactory; -}) { - return new FollowProfilesGateway(apollo, factory, mock()); -} - -describe(`Given an instance of the ${FollowProfilesGateway.name}`, () => { - describe(`when calling the "${FollowProfilesGateway.prototype.createUnsignedProtocolCall.name}" method`, () => { - describe('with an UnconstrainedFollowRequest', () => { - it(`should create an "${UnsignedProtocolCall.name}" w/ the expected typed data`, async () => { - const request = mockUnconstrainedFollowRequest(); - const data = mockCreateFollowTypedDataData(); - - const apollo = mockLensApolloClient([ - mockCreateFollowTypedDataMutationResponse({ - variables: { - request: { - follow: [ - { - profile: request.profileId, - }, - ], - }, - }, - data, - }), - ]); - const mockTransactionObserver = mockITransactionObserver(); - const factory = mockITransactionFactory(mockTransactionObserver); - const followProfilesGateway = mockFollowProfilesGateway({ apollo, factory }); - - const unsignedCall = await followProfilesGateway.createUnsignedProtocolCall(request); - - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - }); - - describe('with a ProfileOwnerFollowRequest', () => { - it(`should create an "${UnsignedProtocolCall.name}" w/ the expected typed data`, async () => { - const request = mockProfileOwnerFollowRequest(); - const data = mockCreateFollowTypedDataData(); - - const apollo = mockLensApolloClient([ - mockCreateFollowTypedDataMutationResponse({ - variables: { - request: { - follow: [ - { - profile: request.profileId, - followModule: { - profileFollowModule: { - profileId: request.followerProfileId, - }, - }, - }, - ], - }, - }, - data, - }), - ]); - const mockTransactionObserver = mockITransactionObserver(); - const factory = mockITransactionFactory(mockTransactionObserver); - const followProfilesGateway = mockFollowProfilesGateway({ apollo, factory }); - - const unsignedCall = await followProfilesGateway.createUnsignedProtocolCall(request); - - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - }); - - describe(`with a PaidFollowRequest`, () => { - it(`should create an "${UnsignedProtocolCall.name}" w/ the expected typed data`, async () => { - const request = mockPaidFollowRequest(); - const data = mockCreateFollowTypedDataData(); - - const apollo = mockLensApolloClient([ - mockCreateFollowTypedDataMutationResponse({ - variables: { - request: { - follow: [ - { - profile: request.profileId, - followModule: { - feeFollowModule: { - amount: { - currency: request.fee.amount.asset.address, - value: request.fee.amount.toFixed(), - }, - }, - }, - }, - ], - }, - }, - data, - }), - ]); - const mockTransactionObserver = mockITransactionObserver(); - const factory = mockITransactionFactory(mockTransactionObserver); - const followProfilesGateway = mockFollowProfilesGateway({ apollo, factory }); - - const unsignedCall = await followProfilesGateway.createUnsignedProtocolCall(request); - - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - }); - - it(`should be possible to override the signature nonce`, async () => { - const request = mockUnconstrainedFollowRequest(); - const nonce = mockNonce(); - const apollo = mockLensApolloClient([ - mockCreateFollowTypedDataMutationResponse({ - variables: { - request: { - follow: [ - { - profile: request.profileId, - }, - ], - }, - options: { - overrideSigNonce: nonce, - }, - }, - data: mockCreateFollowTypedDataData({ nonce }), - }), - ]); - const mockTransactionObserver = mockITransactionObserver(); - const factory = mockITransactionFactory(mockTransactionObserver); - const followProfilesGateway = mockFollowProfilesGateway({ apollo, factory }); - - const unsignedCall = await followProfilesGateway.createUnsignedProtocolCall(request, nonce); - - expect(unsignedCall.nonce).toEqual(nonce); - }); - }); - - describe(`when relaying an UnconstrainedFollowRequest via the "${FollowProfilesGateway.prototype.createProxyTransaction.name}" method`, () => { - const request = mockUnconstrainedFollowRequest(); - it(`should succeed with ${ProxyTransaction.name} on Polygon`, async () => { - const indexingId = 'indexing-id'; - const apollo = mockLensApolloClient([ - mockBroadcastProxyActionCallResponse({ - result: indexingId, - variables: { - request: { - follow: { - freeFollow: { - profileId: request.profileId, - }, - }, - }, - }, - }), - ]); - const mockTransactionObserver = mockITransactionObserver(); - const factory = mockITransactionFactory(mockTransactionObserver); - const followProfilesGateway = mockFollowProfilesGateway({ - apollo, - factory, - }); - - const transactionResult = await followProfilesGateway.createProxyTransaction(request); - - if (transactionResult.isFailure()) throw transactionResult.error; - - const transaction = transactionResult.value; - - await transaction.waitNextEvent(); - - expect(transaction).toEqual( - expect.objectContaining({ - chainType: ChainType.POLYGON, - id: 'id', - request, - status: ProxyActionStatus.MINTING, - }), - ); - - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - expect((transaction as any).state.proxyId).toEqual(indexingId); - }); - - it(`should fail with ${BroadcastingError.name} in the case of a broadcast failure`, async () => { - const apollo = mockLensApolloClient([ - createBroadcastProxyActionCallMockedError({ - errorMessage: 'Failed to broadcast proxy action call', - variables: { - request: { - follow: { - freeFollow: { - profileId: request.profileId, - }, - }, - }, - }, - }), - mockCreateFollowTypedDataMutationResponse({ - variables: { - request: { - follow: [ - { - profile: request.profileId, - }, - ], - }, - }, - data: mockCreateFollowTypedDataData(), - }), - ]); - const mockTransactionObserver = mockITransactionObserver(); - const factory = mockITransactionFactory(mockTransactionObserver); - const followProfilesGateway = mockFollowProfilesGateway({ apollo, factory }); - - const transactionResult = await followProfilesGateway.createProxyTransaction(request); - - if (transactionResult.isSuccess()) throw new Error('Expected transaction to fail'); - - expect(transactionResult.error).toEqual( - new BroadcastingError('Failed to broadcast proxy action call'), - ); - expect(transactionResult.error.fallback).toEqual( - expect.objectContaining({ - ...request, - }), - ); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/OffChainRelayer.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/OffChainRelayer.spec.ts deleted file mode 100644 index f3f6756e79..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/OffChainRelayer.spec.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { RelayErrorReasons, BroadcastOffChainResult } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockRelayErrorFragment, - mockBroadcastOffChainResponse, - mockDataAvailabilityPublicationResult, -} from '@lens-protocol/api-bindings/mocks'; -import { DataTransaction, ISignedProtocolCall } from '@lens-protocol/domain/entities'; -import { - BroadcastingError, - ProtocolTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { assertFailure, assertSuccess, ILogger } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; - -import { SignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { mockSignedProtocolCall } from '../../../wallet/adapters/__helpers__/mocks'; -import { OffChainRelayer } from '../OffChainRelayer'; -import { mockITransactionFactory } from '../__helpers__/mocks'; - -function setupRelayer({ - broadcastResult, - signedCall, -}: { - broadcastResult: BroadcastOffChainResult; - signedCall: ISignedProtocolCall; -}) { - const factory = mockITransactionFactory(); - const apollo = mockLensApolloClient([ - mockBroadcastOffChainResponse({ - result: broadcastResult, - variables: { - request: { - id: signedCall.id, - signature: signedCall.signature, - }, - }, - }), - ]); - return new OffChainRelayer(apollo, factory, mock()); -} - -describe(`Given an instance of the ${OffChainRelayer.name}`, () => { - const signedCall = mockSignedProtocolCall(); - - describe(`when relaying an ISignedProtocolCall succeeds`, () => { - it(`should resolve with a success(${DataTransaction.name})`, async () => { - const broadcastResult = mockDataAvailabilityPublicationResult(); - - const relayer = setupRelayer({ broadcastResult, signedCall }); - const result = await relayer.relayProtocolCall(signedCall); - - assertSuccess(result); - expect(result.value).toBeInstanceOf(DataTransaction); - expect(result.value).toMatchObject( - expect.objectContaining({ - id: broadcastResult.id, - request: signedCall.request, - }), - ); - }); - }); - - describe(`when relaying an ISignedProtocolCall fails`, () => { - it(`should resolve with a failure(${BroadcastingError.name}) carrying the RequestFallback from the ${SignedProtocolCall.name}`, async () => { - const broadcastResult = mockRelayErrorFragment(RelayErrorReasons.Rejected); - - const relayer = setupRelayer({ broadcastResult, signedCall }); - const result = await relayer.relayProtocolCall(signedCall); - - assertFailure(result); - expect(result.error).toBeInstanceOf(BroadcastingError); - expect(result.error.fallback).toMatchObject(signedCall.fallback); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/OnChainRelayer.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/OnChainRelayer.spec.ts deleted file mode 100644 index 76dd65b83e..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/OnChainRelayer.spec.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { RelayErrorReasons, BroadcastOnChainResult } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockBroadcastOnChainResponse, - mockRelayerResultFragment, - mockRelayErrorFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { ISignedProtocolCall, MetaTransaction } from '@lens-protocol/domain/entities'; -import { - BroadcastingError, - ProtocolTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { assertFailure, ChainType, ILogger } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; - -import { SignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { mockSignedProtocolCall } from '../../../wallet/adapters/__helpers__/mocks'; -import { OnChainRelayer } from '../OnChainRelayer'; -import { mockITransactionFactory } from '../__helpers__/mocks'; - -function setupRelayer({ - broadcastResult, - signedCall, -}: { - broadcastResult: BroadcastOnChainResult; - signedCall: ISignedProtocolCall; -}) { - const factory = mockITransactionFactory(); - const apollo = mockLensApolloClient([ - mockBroadcastOnChainResponse({ - result: broadcastResult, - variables: { - request: { - id: signedCall.id, - signature: signedCall.signature, - }, - }, - }), - ]); - return new OnChainRelayer(apollo, factory, mock()); -} - -describe(`Given an instance of the ${OnChainRelayer.name}`, () => { - const signedCall = mockSignedProtocolCall(); - - describe(`when relaying an ISignedProtocolCall succeeds`, () => { - it(`should resolve with a success(${MetaTransaction.name}) on Polygon`, async () => { - const broadcastResult = mockRelayerResultFragment(); - - const relayer = setupRelayer({ broadcastResult, signedCall }); - const result = await relayer.relayProtocolCall(signedCall); - - expect(result.unwrap()).toMatchObject( - expect.objectContaining({ - chainType: ChainType.POLYGON, - id: signedCall.id, - nonce: signedCall.nonce, - request: signedCall.request, - }), - ); - }); - }); - - describe(`when relaying an ISignedProtocolCall fails`, () => { - it(`should resolve with a failure(${BroadcastingError.name}) carrying the RequestFallback from the ${SignedProtocolCall.name}`, async () => { - const broadcastResult = mockRelayErrorFragment(RelayErrorReasons.Rejected); - - const relayer = setupRelayer({ broadcastResult, signedCall }); - const result = await relayer.relayProtocolCall(signedCall); - - assertFailure(result); - expect(result.error).toBeInstanceOf(BroadcastingError); - expect(result.error.fallback).toMatchObject(signedCall.fallback); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/ProfileImageCallGateway.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/ProfileImageCallGateway.spec.ts deleted file mode 100644 index 57dcc9e1ae..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/ProfileImageCallGateway.spec.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { RelayErrorReasons } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockCreateSetProfileImageUriTypedDataData, - mockCreateSetProfileImageUriTypedDataResponse, - mockSetProfileImageURIViaDispatcherResponse, - mockRelayerResultFragment, - mockRelayErrorFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { NativeTransaction } from '@lens-protocol/domain/entities'; -import { - mockNonce, - mockUpdateNftProfileImageRequest, - mockUpdateOffChainProfileImageRequest, -} from '@lens-protocol/domain/mocks'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType } from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { ProfileImageCallGateway } from '../ProfileImageCallGateway'; -import { - assertBroadcastingErrorResultWithRequestFallback, - assertUnsignedProtocolCallCorrectness, - mockITransactionFactory, -} from '../__helpers__/mocks'; - -describe(`Given an instance of the ${ProfileImageCallGateway.name}`, () => { - describe.each([ - { - requestName: 'UpdateNftProfileImageRequest', - createExerciseData: () => { - const request = mockUpdateNftProfileImageRequest(); - return { - request, - expectedRequestVars: { - profileId: request.profileId, - nftData: { - id: request.signature.id, - signature: request.signature.signature, - }, - }, - }; - }, - }, - { - requestName: 'UpdateOffChainProfileImageRequest', - createExerciseData: () => { - const request = mockUpdateOffChainProfileImageRequest(); - - return { - request, - expectedRequestVars: { - profileId: request.profileId, - url: request.url, - }, - }; - }, - }, - ])('with $requestName', ({ createExerciseData }) => { - const { request, expectedRequestVars } = createExerciseData(); - const data = mockCreateSetProfileImageUriTypedDataData(); - - describe(`when calling the "${ProfileImageCallGateway.prototype.createUnsignedProtocolCall.name}"`, () => { - it(`should create an "${UnsignedProtocolCall.name}" w/ the expected typed data`, async () => { - const apollo = mockLensApolloClient([ - mockCreateSetProfileImageUriTypedDataResponse({ - variables: { - request: expectedRequestVars, - }, - data, - }), - ]); - const transactionFactory = mockITransactionFactory(); - - const gateway = new ProfileImageCallGateway(apollo, transactionFactory); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request); - - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - - it(`should be possible to override the signature nonce`, async () => { - const nonce = mockNonce(); - const apollo = mockLensApolloClient([ - mockCreateSetProfileImageUriTypedDataResponse({ - variables: { - request: expectedRequestVars, - options: { - overrideSigNonce: nonce, - }, - }, - data: mockCreateSetProfileImageUriTypedDataData({ nonce }), - }), - ]); - - const transactionFactory = mockITransactionFactory(); - - const gateway = new ProfileImageCallGateway(apollo, transactionFactory); - const unsignedCall = await gateway.createUnsignedProtocolCall(request, nonce); - - expect(unsignedCall.nonce).toEqual(nonce); - }); - }); - - describe(`when calling the "${ProfileImageCallGateway.prototype.createDelegatedTransaction.name}"`, () => { - it(`should create an instance of the ${NativeTransaction.name}`, async () => { - const apollo = mockLensApolloClient([ - mockSetProfileImageURIViaDispatcherResponse({ - variables: { - request: expectedRequestVars, - }, - data: { - result: mockRelayerResultFragment(), - }, - }), - ]); - const transactionFactory = mockITransactionFactory(); - - const gateway = new ProfileImageCallGateway(apollo, transactionFactory); - const result = await gateway.createDelegatedTransaction(request); - - expect(result.unwrap()).toBeInstanceOf(NativeTransaction); - expect(result.unwrap()).toEqual( - expect.objectContaining({ - chainType: ChainType.POLYGON, - id: expect.any(String), - request, - }), - ); - }); - - it.each([ - mockRelayErrorFragment(RelayErrorReasons.Rejected), - mockRelayErrorFragment(RelayErrorReasons.NotAllowed), - ])( - `should fail w/ a ${BroadcastingError.name} in case of RelayError response with "$reason" reason`, - async (relayError) => { - const apollo = mockLensApolloClient([ - mockSetProfileImageURIViaDispatcherResponse({ - variables: { - request: expectedRequestVars, - }, - data: { - result: relayError, - }, - }), - mockCreateSetProfileImageUriTypedDataResponse({ - variables: { - request: expectedRequestVars, - }, - data, - }), - ]); - const transactionFactory = mockITransactionFactory(); - - const gateway = new ProfileImageCallGateway(apollo, transactionFactory); - const result = await gateway.createDelegatedTransaction(request); - - assertBroadcastingErrorResultWithRequestFallback(result, data.result.typedData); - }, - ); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/PromiseResultPresenter.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/PromiseResultPresenter.spec.ts deleted file mode 100644 index 0ed1ce68e7..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/PromiseResultPresenter.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { WalletConnectionError, WalletConnectionErrorReason } from '@lens-protocol/domain/entities'; -import { failure, success } from '@lens-protocol/shared-kernel'; - -import { PromiseResultPresenter } from '../PromiseResultPresenter'; - -describe(`Given an instance of the ${PromiseResultPresenter.name}`, () => { - describe(`when converting the instance into a Result`, () => { - it(`should be able to resolve with a success`, async () => { - const presenter = new PromiseResultPresenter(); - - const promise = presenter.asResult(); - presenter.present(success()); - const result = await promise; - - expect(result.isSuccess()).toBe(true); - }); - - it(`should be able to resolve with a failure`, async () => { - const presenter = new PromiseResultPresenter(); - - const promise = presenter.asResult(); - const err = new WalletConnectionError(WalletConnectionErrorReason.INCORRECT_CHAIN); - presenter.present(failure(err)); - const result = await promise; - - expect(() => result.unwrap()).toThrow(WalletConnectionError); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/PublicationCacheManager.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/PublicationCacheManager.spec.ts deleted file mode 100644 index 7eb468faf8..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/PublicationCacheManager.spec.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { AnyPublication, FragmentPublication } from '@lens-protocol/api-bindings'; -import { - mockPostFragment, - mockCommentFragment, - mockMirrorFragment, - mockGetPublicationResponse, - mockSources, - mockLensApolloClient, - simulateAuthenticatedWallet, -} from '@lens-protocol/api-bindings/mocks'; -import { - mockCreatePostRequest, - mockPublicationId, - mockTransactionData, - mockTransactionHash, -} from '@lens-protocol/domain/mocks'; - -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../../mediaTransforms'; -import { PublicationCacheManager } from '../PublicationCacheManager'; - -function setupTestScenario({ - txHash, - publication, -}: { - txHash?: string; - publication: AnyPublication; -}) { - const sources = mockSources(); - const mediaTransforms = defaultMediaTransformsConfig; - const client = mockLensApolloClient([ - mockGetPublicationResponse({ - variables: { - request: txHash - ? { - txHash, - } - : { - publicationId: publication.id, - }, - observerId: null, - sources, - ...mediaTransformConfigToQueryVariables(mediaTransforms), - }, - publication, - }), - ]); - - client.cache.writeFragment({ - id: client.cache.identify({ - __typename: publication.__typename, - id: publication.id, - }), - fragment: FragmentPublication, - fragmentName: 'Publication', - data: publication, - }); - - return { - cacheManager: new PublicationCacheManager(client, sources, mediaTransforms), - - get publicationFromCache() { - return client.cache.readFragment({ - id: client.cache.identify({ - __typename: publication.__typename, - id: publication.id, - }), - fragment: FragmentPublication, - fragmentName: 'Publication', - }); - }, - }; -} - -describe(`Given the ${PublicationCacheManager.name}`, () => { - beforeAll(() => { - simulateAuthenticatedWallet(); - }); - - describe(`when "${PublicationCacheManager.prototype.fetchNewPost.name}" method is invoked`, () => { - const post = mockPostFragment(); - - it('should fetch new publication by "txHash" if available', async () => { - const txHash = mockTransactionHash(); - const scenario = setupTestScenario({ - txHash, - publication: post, - }); - - const transactionData = mockTransactionData({ - txHash, - request: mockCreatePostRequest(), - }); - const publication = await scenario.cacheManager.fetchNewPost(transactionData); - - expect(publication).toMatchObject({ - id: post.id, - }); - }); - - it('should fetch new publication by "id" if "txHash" is not available', async () => { - const request = mockCreatePostRequest(); - const scenario = setupTestScenario({ - publication: post, - }); - - const transactionData = mockTransactionData({ id: post.id, request }); - const publication = await scenario.cacheManager.fetchNewPost(transactionData); - - expect(publication).toMatchObject({ - id: post.id, - }); - }); - }); - - describe(`when "${PublicationCacheManager.prototype.update.name}" method is invoked`, () => { - it.each([ - mockPostFragment({ - hidden: false, - }), - mockCommentFragment({ - hidden: false, - }), - mockMirrorFragment({ - hidden: false, - }), - ])(`should be able to update $__typename cache fragments`, async (publication) => { - const scenario = setupTestScenario({ publication }); - - scenario.cacheManager.update(publication.id, (data) => ({ - ...data, - hidden: true, - })); - - expect(scenario.publicationFromCache).toMatchObject({ - hidden: true, - }); - }); - - it(`should not call the update callback if the cache item is not present`, async () => { - const scenario = setupTestScenario({ - publication: mockPostFragment(), - }); - const updateSpy = jest.fn(); - - scenario.cacheManager.update(mockPublicationId(), updateSpy); - - expect(updateSpy).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/SelfFundedProtocolCallGateway.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/SelfFundedProtocolCallGateway.spec.ts deleted file mode 100644 index bf886e6318..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/SelfFundedProtocolCallGateway.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * @jest-environment node - */ -import { mockWallet } from '@lens-protocol/domain/mocks'; -import { ProtocolTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType } from '@lens-protocol/shared-kernel'; -import { MockProvider } from 'ethereum-waffle'; -import { providers } from 'ethers'; - -import { mockIProviderFactory } from '../../../wallet/adapters/__helpers__/mocks'; -import { - SelfFundedProtocolCallGateway, - UnsignedSelfFundedProtocolCallTransaction, -} from '../SelfFundedProtocolCallGateway'; -import { mockSelfFundedProtocolTransactionRequest } from '../__helpers__/mocks'; - -function setupSelfFundedProtocolCallGateway({ provider }: { provider: providers.JsonRpcProvider }) { - const providerFactory = mockIProviderFactory({ - chainType: ChainType.POLYGON, - provider, - }); - - return new SelfFundedProtocolCallGateway(providerFactory); -} - -async function mineNBlocks(provider: MockProvider, blocks: number) { - return provider.send('evm_mine', [{ blocks }]); -} - -describe(`Given an instance of the ${SelfFundedProtocolCallGateway.name}`, () => { - const request = mockSelfFundedProtocolTransactionRequest(); - const wallet = mockWallet(); - - describe(`when invoking ${SelfFundedProtocolCallGateway.prototype.prepareSelfFundedTransaction.name}`, () => { - it(`should succeed with the expected ${UnsignedSelfFundedProtocolCallTransaction.name}`, async () => { - const provider = new MockProvider({ - ganacheOptions: { - chain: { - hardfork: 'london', - }, - }, - }); - await mineNBlocks(provider, 20); - const gateway = setupSelfFundedProtocolCallGateway({ provider }); - - const unsignedTransaction = await gateway.prepareSelfFundedTransaction(request, wallet); - - expect(unsignedTransaction).toBeInstanceOf(UnsignedSelfFundedProtocolCallTransaction); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/TransactionQueuePresenter.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/TransactionQueuePresenter.spec.ts deleted file mode 100644 index bfe7a48d55..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/TransactionQueuePresenter.spec.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { recentTransactionsVar, TxStatus } from '@lens-protocol/api-bindings'; -import { TransactionError, TransactionErrorReason } from '@lens-protocol/domain/entities'; -import { mockTransactionError, mockTransactionData } from '@lens-protocol/domain/mocks'; -import { - AnyTransactionRequest, - TransactionData, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { FailedTransactionError, TransactionQueuePresenter } from '../TransactionQueuePresenter'; - -function setupTransactionQueuePresenter() { - const errorHandler = jest.fn(); - - const presenter = new TransactionQueuePresenter(errorHandler); - - return { presenter, errorHandler }; -} - -describe(`Given the ${TransactionQueuePresenter.name}`, () => { - afterEach(() => { - recentTransactionsVar([]); - }); - - describe(`when invoking "${TransactionQueuePresenter.prototype.pending.name}" method`, () => { - it('should add it to the list of recent transactions', () => { - const { presenter } = setupTransactionQueuePresenter(); - - const transaction = mockTransactionData(); - presenter.pending(transaction); - - expect(recentTransactionsVar()).toEqual([{ status: TxStatus.PENDING, ...transaction }]); - }); - - it('should update the status of an existing transaction', () => { - const { presenter } = setupTransactionQueuePresenter(); - const transaction = mockTransactionData(); - presenter.pending(transaction); - - const updated = mockTransactionData({ id: transaction.id, request: transaction.request }); - presenter.pending(updated); - - expect(recentTransactionsVar()).toEqual([{ status: TxStatus.PENDING, ...updated }]); - }); - }); - - describe(`when invoking "${TransactionQueuePresenter.prototype.settled.name}" method`, () => { - const transaction = mockTransactionData(); - - it('should update the corresponding transaction', () => { - const { presenter } = setupTransactionQueuePresenter(); - presenter.pending(transaction); - - presenter.settled(transaction); - - expect(recentTransactionsVar()).toEqual([{ status: TxStatus.SETTLED, ...transaction }]); - }); - }); - - describe(`when invoking "${TransactionQueuePresenter.prototype.failed.name}" method`, () => { - const transaction = mockTransactionData(); - - it('should update the corresponding transaction', () => { - const { presenter } = setupTransactionQueuePresenter(); - presenter.pending(transaction); - - presenter.failed(mockTransactionError(), transaction); - - expect(recentTransactionsVar()).toEqual([{ status: TxStatus.FAILED, ...transaction }]); - }); - - it(`should use the provided errorHandler to propagate the error to the user`, () => { - const { presenter, errorHandler } = setupTransactionQueuePresenter(); - presenter.pending(transaction); - - const error = new TransactionError(TransactionErrorReason.UNKNOWN); - presenter.failed(error, transaction); - - const expectedError = new FailedTransactionError(error, transaction); - expect(errorHandler).toHaveBeenCalledWith(expectedError); - }); - }); - - describe(`when invoking "${TransactionQueuePresenter.prototype.clearRecent.name}" method`, () => { - it(`should remove ${TxStatus.SETTLED} and ${TxStatus.FAILED} tx`, () => { - const { presenter } = setupTransactionQueuePresenter(); - const toKeep = [mockTransactionData(), mockTransactionData()]; - const toRemove = [mockTransactionData(), mockTransactionData()]; - - toKeep.concat(toRemove).forEach((transaction) => presenter.pending(transaction)); - presenter.failed( - mockTransactionError(), - toRemove[0] as TransactionData, - ); - presenter.settled(toRemove[1] as TransactionData); - - presenter.clearRecent(); - - expect(recentTransactionsVar()).toEqual( - toKeep.reverse().map((data) => ({ - ...data, - status: TxStatus.PENDING, - })), - ); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/__tests__/UnfollowProfileCallGateway.spec.ts b/packages/react-v1/src/transactions/adapters/__tests__/UnfollowProfileCallGateway.spec.ts deleted file mode 100644 index c24820a0d4..0000000000 --- a/packages/react-v1/src/transactions/adapters/__tests__/UnfollowProfileCallGateway.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { MockedResponse } from '@apollo/client/testing'; -import { - CreateUnfollowTypedDataDocument, - CreateUnfollowTypedDataData, - CreateUnfollowTypedDataVariables, -} from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockCreateUnfollowTypedDataData, -} from '@lens-protocol/api-bindings/mocks'; -import { mockUnfollowRequest } from '@lens-protocol/domain/mocks'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { UnfollowProfileCallGateway } from '../UnfollowProfileCallGateway'; -import { assertUnsignedProtocolCallCorrectness } from '../__helpers__/mocks'; - -function mockmockUnfollowTypedDataMutationResponse({ - variables, - data, -}: { - variables: CreateUnfollowTypedDataVariables; - data: CreateUnfollowTypedDataData; -}): MockedResponse { - return { - request: { - query: CreateUnfollowTypedDataDocument, - variables, - }, - result: { - data, - }, - }; -} - -describe(`Given an instance of the ${UnfollowProfileCallGateway.name}`, () => { - const request = mockUnfollowRequest(); - - describe(`when calling the "${UnfollowProfileCallGateway.prototype.createUnsignedProtocolCall.name}"`, () => { - it(`should create an "${UnsignedProtocolCall.name}" w/ the expected typed data`, async () => { - const data = mockCreateUnfollowTypedDataData(); - const apollo = mockLensApolloClient([ - mockmockUnfollowTypedDataMutationResponse({ - variables: { - request: { - profile: request.profileId, - }, - }, - data, - }), - ]); - const gateway = new UnfollowProfileCallGateway(apollo); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request); - - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainCommentGateway.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainCommentGateway.ts deleted file mode 100644 index 1bfa02aad5..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainCommentGateway.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { - CreateCommentEip712TypedData, - CreateDataAvailabilityCommentRequest, - CreateDataAvailabilityCommentTypedDataData, - CreateDataAvailabilityCommentTypedDataDocument, - CreateDataAvailabilityCommentTypedDataVariables, - CreateDataAvailabilityCommentViaDispatcherData, - CreateDataAvailabilityCommentViaDispatcherDocument, - CreateDataAvailabilityCommentViaDispatcherVariables, - SafeApolloClient, - omitTypename, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { DataTransaction } from '@lens-protocol/domain/entities'; -import { CreateCommentRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - IDelegatedTransactionGateway, - IOffChainProtocolCallGateway, -} from '@lens-protocol/domain/use-cases/transactions'; -import { failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { IMetadataUploader } from '../IMetadataUploader'; -import { ITransactionFactory } from '../ITransactionFactory'; -import { - Data, - SelfFundedProtocolTransactionRequest, -} from '../SelfFundedProtocolTransactionRequest'; -import { handleRelayError, OffChainBroadcastReceipt } from '../relayer'; - -export class CreateOffChainCommentGateway - implements - IDelegatedTransactionGateway, - IOffChainProtocolCallGateway -{ - constructor( - private readonly apolloClient: SafeApolloClient, - private readonly transactionFactory: ITransactionFactory, - private readonly metadataUploader: IMetadataUploader, - ) {} - - async createDelegatedTransaction( - request: CreateCommentRequest, - ): PromiseResult, BroadcastingError> { - const result = await this.broadcast(request); - - if (result.isFailure()) return failure(result.error); - - const receipt = result.value; - const transaction = this.transactionFactory.createDataTransaction({ - id: receipt.id, - request, - }); - - return success(transaction); - } - - async createUnsignedProtocolCall( - request: CreateCommentRequest, - ): Promise> { - const data = await this.createTypedData(request); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data.result.typedData), - }); - } - - private async broadcast( - request: CreateCommentRequest, - ): PromiseResult { - const requestArg = await this.resolveCreateDataAvailabilityPostRequest(request); - - const { data } = await this.apolloClient.mutate< - CreateDataAvailabilityCommentViaDispatcherData, - CreateDataAvailabilityCommentViaDispatcherVariables - >({ - mutation: CreateDataAvailabilityCommentViaDispatcherDocument, - variables: { - request: requestArg, - }, - }); - - if (data.result.__typename === 'RelayError') { - const typedData = await this.createTypedData(request); - const fallback = this.createRequestFallback(request, typedData.result.typedData); - - return handleRelayError(data.result, fallback); - } - - return success({ - id: data.result.id, - }); - } - - private async createTypedData( - request: CreateCommentRequest, - ): Promise { - const { data } = await this.apolloClient.mutate< - CreateDataAvailabilityCommentTypedDataData, - CreateDataAvailabilityCommentTypedDataVariables - >({ - mutation: CreateDataAvailabilityCommentTypedDataDocument, - variables: { - request: { - commentOn: request.publicationId, - contentURI: await this.metadataUploader.upload(request), - from: request.profileId, - }, - }, - }); - return data; - } - - private async resolveCreateDataAvailabilityPostRequest( - request: CreateCommentRequest, - ): Promise { - return { - commentOn: request.publicationId, - contentURI: await this.metadataUploader.upload(request), - from: request.profileId, - }; - } - - private createRequestFallback( - request: CreateCommentRequest, - data: CreateCommentEip712TypedData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('comment', [ - { - profileId: data.message.profileId, - contentURI: data.message.contentURI, - profileIdPointed: data.message.profileIdPointed, - pubIdPointed: data.message.pubIdPointed, - referenceModuleData: data.message.referenceModuleData, - collectModule: data.message.collectModule, - collectModuleInitData: data.message.collectModuleInitData, - referenceModule: data.message.referenceModule, - referenceModuleInitData: data.message.referenceModuleInitData, - }, - ]); - return { - ...request, - contractAddress: data.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainMirrorGateway.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainMirrorGateway.ts deleted file mode 100644 index 49dbc401c0..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainMirrorGateway.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { - omitTypename, - SafeApolloClient, - CreateDataAvailabilityMirrorViaDispatcherData, - CreateDataAvailabilityMirrorViaDispatcherVariables, - CreateDataAvailabilityMirrorViaDispatcherDocument, - CreateMirrorEip712TypedData, - CreateDataAvailabilityMirrorTypedDataData, - CreateDataAvailabilityMirrorTypedDataVariables, - CreateDataAvailabilityMirrorTypedDataDocument, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { DataTransaction } from '@lens-protocol/domain/entities'; -import { CreateMirrorRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - IDelegatedTransactionGateway, - IOffChainProtocolCallGateway, -} from '@lens-protocol/domain/use-cases/transactions'; -import { failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { ITransactionFactory } from '../ITransactionFactory'; -import { - Data, - SelfFundedProtocolTransactionRequest, -} from '../SelfFundedProtocolTransactionRequest'; -import { handleRelayError, OffChainBroadcastReceipt } from '../relayer'; - -export class CreateOffChainMirrorGateway - implements - IDelegatedTransactionGateway, - IOffChainProtocolCallGateway -{ - constructor( - private readonly apolloClient: SafeApolloClient, - private readonly transactionFactory: ITransactionFactory, - ) {} - - async createDelegatedTransaction( - request: CreateMirrorRequest, - ): PromiseResult, BroadcastingError> { - const result = await this.broadcast(request); - - if (result.isFailure()) return failure(result.error); - - const receipt = result.value; - const transaction = this.transactionFactory.createDataTransaction({ - id: receipt.id, - request, - }); - - return success(transaction); - } - - async createUnsignedProtocolCall( - request: CreateMirrorRequest, - ): Promise> { - const data = await this.createTypedData(request); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data.result.typedData), - }); - } - - private async broadcast( - request: CreateMirrorRequest, - ): PromiseResult { - const { data } = await this.apolloClient.mutate< - CreateDataAvailabilityMirrorViaDispatcherData, - CreateDataAvailabilityMirrorViaDispatcherVariables - >({ - mutation: CreateDataAvailabilityMirrorViaDispatcherDocument, - variables: { - request: { - from: request.profileId, - mirror: request.publicationId, - }, - }, - }); - - if (data.result.__typename === 'RelayError') { - const typedData = await this.createTypedData(request); - const fallback = this.createRequestFallback(request, typedData.result.typedData); - - return handleRelayError(data.result, fallback); - } - - return success({ - id: data.result.id, - }); - } - - private async createTypedData( - request: CreateMirrorRequest, - ): Promise { - const { data } = await this.apolloClient.mutate< - CreateDataAvailabilityMirrorTypedDataData, - CreateDataAvailabilityMirrorTypedDataVariables - >({ - mutation: CreateDataAvailabilityMirrorTypedDataDocument, - variables: { - request: { - from: request.profileId, - mirror: request.publicationId, - }, - }, - }); - return data; - } - - private createRequestFallback( - request: CreateMirrorRequest, - data: CreateMirrorEip712TypedData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('mirror', [ - { - profileId: data.message.profileId, - profileIdPointed: data.message.profileIdPointed, - pubIdPointed: data.message.pubIdPointed, - referenceModuleData: data.message.referenceModuleData, - referenceModule: data.message.referenceModule, - referenceModuleInitData: data.message.referenceModuleInitData, - }, - ]); - return { - ...request, - contractAddress: data.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainPostGateway.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainPostGateway.ts deleted file mode 100644 index 75aadcda99..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOffChainPostGateway.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { - SafeApolloClient, - omitTypename, - CreateDataAvailabilityPostTypedDataDocument, - CreateDataAvailabilityPostTypedDataData, - CreateDataAvailabilityPostTypedDataVariables, - CreatePostEip712TypedData, - CreateDataAvailabilityPostViaDispatcherDocument, - CreateDataAvailabilityPostViaDispatcherData, - CreateDataAvailabilityPostViaDispatcherVariables, - CreateDataAvailabilityPostRequest, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { DataTransaction } from '@lens-protocol/domain/entities'; -import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - IDelegatedTransactionGateway, - IOffChainProtocolCallGateway, -} from '@lens-protocol/domain/use-cases/transactions'; -import { failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { IMetadataUploader } from '../IMetadataUploader'; -import { ITransactionFactory } from '../ITransactionFactory'; -import { - Data, - SelfFundedProtocolTransactionRequest, -} from '../SelfFundedProtocolTransactionRequest'; -import { handleRelayError, OffChainBroadcastReceipt } from '../relayer'; - -export class CreateOffChainPostGateway - implements - IDelegatedTransactionGateway, - IOffChainProtocolCallGateway -{ - constructor( - private readonly apolloClient: SafeApolloClient, - private readonly transactionFactory: ITransactionFactory, - private readonly metadataUploader: IMetadataUploader, - ) {} - - async createDelegatedTransaction( - request: CreatePostRequest, - ): PromiseResult, BroadcastingError> { - const result = await this.broadcast(request); - - if (result.isFailure()) return failure(result.error); - - const receipt = result.value; - const transaction = this.transactionFactory.createDataTransaction({ - id: receipt.id, - request, - }); - - return success(transaction); - } - - async createUnsignedProtocolCall( - request: CreatePostRequest, - ): Promise> { - const data = await this.createTypedData(request); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data.result.typedData), - }); - } - - private async broadcast( - request: CreatePostRequest, - ): PromiseResult { - const requestArg = await this.resolveCreateDataAvailabilityPostRequest(request); - - const { data } = await this.apolloClient.mutate< - CreateDataAvailabilityPostViaDispatcherData, - CreateDataAvailabilityPostViaDispatcherVariables - >({ - mutation: CreateDataAvailabilityPostViaDispatcherDocument, - variables: { - request: requestArg, - }, - }); - - if (data.result.__typename === 'RelayError') { - const typedData = await this.createTypedData(request); - const fallback = this.createRequestFallback(request, typedData.result.typedData); - - return handleRelayError(data.result, fallback); - } - - return success({ - id: data.result.id, - }); - } - - private async createTypedData( - request: CreatePostRequest, - ): Promise { - const { data } = await this.apolloClient.mutate< - CreateDataAvailabilityPostTypedDataData, - CreateDataAvailabilityPostTypedDataVariables - >({ - mutation: CreateDataAvailabilityPostTypedDataDocument, - variables: { - request: { - contentURI: await this.metadataUploader.upload(request), - from: request.profileId, - }, - }, - }); - return data; - } - - private async resolveCreateDataAvailabilityPostRequest( - request: CreatePostRequest, - ): Promise { - return { - contentURI: await this.metadataUploader.upload(request), - from: request.profileId, - }; - } - - private createRequestFallback( - request: CreatePostRequest, - data: CreatePostEip712TypedData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('post', [ - { - profileId: data.message.profileId, - contentURI: data.message.contentURI, - collectModule: data.message.collectModule, - collectModuleInitData: data.message.collectModuleInitData, - referenceModule: data.message.referenceModule, - referenceModuleInitData: data.message.referenceModuleInitData, - }, - ]); - return { - ...request, - contractAddress: data.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainCommentGateway.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainCommentGateway.ts deleted file mode 100644 index 3cb25e6d1e..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainCommentGateway.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { - CreateCommentTypedDataDocument, - CreateCommentTypedDataData, - CreateCommentTypedDataVariables, - CreateCommentViaDispatcherDocument, - CreateCommentViaDispatcherData, - CreateCommentViaDispatcherVariables, - CreatePublicCommentRequest as CreatePublicCommentRequestArg, - SafeApolloClient, - omitTypename, - CreateCommentEip712TypedData, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { NativeTransaction, Nonce } from '@lens-protocol/domain/entities'; -import { CreateCommentRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - IDelegatedTransactionGateway, - IOnChainProtocolCallGateway, -} from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; -import { v4 } from 'uuid'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { IMetadataUploader } from '../IMetadataUploader'; -import { ITransactionFactory } from '../ITransactionFactory'; -import { - Data, - SelfFundedProtocolTransactionRequest, -} from '../SelfFundedProtocolTransactionRequest'; -import { handleRelayError, OnChainBroadcastReceipt } from '../relayer'; -import { resolveCollectModuleParams } from './resolveCollectModuleParams'; -import { resolveReferenceModuleParams } from './resolveReferenceModuleParams'; - -export class CreateOnChainCommentGateway - implements - IDelegatedTransactionGateway, - IOnChainProtocolCallGateway -{ - constructor( - private readonly apolloClient: SafeApolloClient, - private readonly transactionFactory: ITransactionFactory, - private readonly uploader: IMetadataUploader, - ) {} - - async createDelegatedTransaction( - request: CreateCommentRequest, - ): PromiseResult, BroadcastingError> { - const result = await this.broadcast(request); - - if (result.isFailure()) return failure(result.error); - - const receipt = result.value; - const transaction = this.transactionFactory.createNativeTransaction({ - chainType: ChainType.POLYGON, - id: v4(), - request, - indexingId: receipt.indexingId, - txHash: receipt.txHash, - }); - return success(transaction); - } - - async createUnsignedProtocolCall( - request: CreateCommentRequest, - nonce?: Nonce, - ): Promise> { - const requestArg = await this.resolveCreateCommentRequestArg(request); - - const typedData = await this.createTypedData(requestArg, nonce); - - return UnsignedProtocolCall.create({ - id: typedData.result.id, - request, - typedData: omitTypename(typedData.result.typedData), - fallback: this.createRequestFallback(request, typedData.result.typedData), - }); - } - - private async broadcast( - request: CreateCommentRequest, - ): PromiseResult { - const requestArg = await this.resolveCreateCommentRequestArg(request); - - const { data } = await this.apolloClient.mutate< - CreateCommentViaDispatcherData, - CreateCommentViaDispatcherVariables - >({ - mutation: CreateCommentViaDispatcherDocument, - variables: { - request: requestArg, - }, - }); - - if (data.result.__typename === 'RelayError') { - const typedData = await this.createTypedData(requestArg); - const fallback = this.createRequestFallback(request, typedData.result.typedData); - - return handleRelayError(data.result, fallback); - } - - return success({ - indexingId: data.result.txId, - txHash: data.result.txHash, - }); - } - - private async createTypedData( - requestArg: CreatePublicCommentRequestArg, - nonce?: Nonce, - ): Promise { - const { data } = await this.apolloClient.mutate< - CreateCommentTypedDataData, - CreateCommentTypedDataVariables - >({ - mutation: CreateCommentTypedDataDocument, - variables: { - request: requestArg, - options: nonce ? { overrideSigNonce: nonce } : undefined, - }, - }); - return data; - } - private async resolveCreateCommentRequestArg( - request: CreateCommentRequest, - ): Promise { - const contentURI = await this.uploader.upload(request); - - return { - contentURI, - profileId: request.profileId, - publicationId: request.publicationId, - collectModule: resolveCollectModuleParams(request), - referenceModule: resolveReferenceModuleParams(request), - }; - } - - private createRequestFallback( - request: CreateCommentRequest, - data: CreateCommentEip712TypedData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('comment', [ - { - profileId: data.message.profileId, - contentURI: data.message.contentURI, - profileIdPointed: data.message.profileIdPointed, - pubIdPointed: data.message.pubIdPointed, - referenceModuleData: data.message.referenceModuleData, - collectModule: data.message.collectModule, - collectModuleInitData: data.message.collectModuleInitData, - referenceModule: data.message.referenceModule, - referenceModuleInitData: data.message.referenceModuleInitData, - }, - ]); - return { - ...request, - contractAddress: data.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainMirrorGateway.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainMirrorGateway.ts deleted file mode 100644 index de4ce1c051..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainMirrorGateway.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { - CreateMirrorTypedDataDocument, - CreateMirrorViaDispatcherDocument, - CreateMirrorViaDispatcherData, - CreateMirrorViaDispatcherVariables, - CreateMirrorRequest as CreateMirrorRequestArg, - omitTypename, - CreateMirrorTypedDataData, - CreateMirrorTypedDataVariables, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { NativeTransaction, Nonce } from '@lens-protocol/domain/entities'; -import { CreateMirrorRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - IDelegatedTransactionGateway, - IOnChainProtocolCallGateway, -} from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; -import { v4 } from 'uuid'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { ITransactionFactory } from '../ITransactionFactory'; -import { - Data, - SelfFundedProtocolTransactionRequest, -} from '../SelfFundedProtocolTransactionRequest'; -import { handleRelayError, OnChainBroadcastReceipt } from '../relayer'; - -export class CreateOnChainMirrorGateway - implements - IDelegatedTransactionGateway, - IOnChainProtocolCallGateway -{ - constructor( - private readonly apolloClient: SafeApolloClient, - private readonly transactionFactory: ITransactionFactory, - ) {} - - async createDelegatedTransaction( - request: CreateMirrorRequest, - ): PromiseResult, BroadcastingError> { - const result = await this.broadcast(request); - - if (result.isFailure()) return failure(result.error); - - const receipt = result.value; - - const transaction = this.transactionFactory.createNativeTransaction({ - chainType: ChainType.POLYGON, - id: v4(), - request, - indexingId: receipt.indexingId, - txHash: receipt.txHash, - }); - - return success(transaction); - } - - async createUnsignedProtocolCall( - request: CreateMirrorRequest, - nonce?: Nonce, - ): Promise> { - const requestArg = await this.resolveCreateMirrorRequestArg(request); - - const data = await this.createTypedData(requestArg, nonce); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data), - }); - } - - private async broadcast( - request: CreateMirrorRequest, - ): PromiseResult { - const requestArg = await this.resolveCreateMirrorRequestArg(request); - - const { data } = await this.apolloClient.mutate< - CreateMirrorViaDispatcherData, - CreateMirrorViaDispatcherVariables - >({ - mutation: CreateMirrorViaDispatcherDocument, - variables: { - request: requestArg, - }, - }); - - if (data.result.__typename === 'RelayError') { - const typedData = await this.createTypedData(requestArg); - const fallback = this.createRequestFallback(request, typedData); - - return handleRelayError(data.result, fallback); - } - - return success({ - indexingId: data.result.txId, - txHash: data.result.txHash, - }); - } - - private async createTypedData( - requestArg: CreateMirrorRequestArg, - nonce?: Nonce, - ): Promise { - const { data } = await this.apolloClient.mutate< - CreateMirrorTypedDataData, - CreateMirrorTypedDataVariables - >({ - mutation: CreateMirrorTypedDataDocument, - variables: { - request: requestArg, - options: nonce ? { overrideSigNonce: nonce } : undefined, - }, - }); - return data; - } - - private async resolveCreateMirrorRequestArg( - request: CreateMirrorRequest, - ): Promise { - return { - profileId: request.profileId, - publicationId: request.publicationId, - }; - } - - private createRequestFallback( - request: CreateMirrorRequest, - data: CreateMirrorTypedDataData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.result.typedData.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('mirror', [ - { - profileId: data.result.typedData.message.profileId, - profileIdPointed: data.result.typedData.message.profileIdPointed, - pubIdPointed: data.result.typedData.message.pubIdPointed, - referenceModuleData: data.result.typedData.message.referenceModuleData, - referenceModule: data.result.typedData.message.referenceModule, - referenceModuleInitData: data.result.typedData.message.referenceModuleInitData, - }, - ]); - return { - ...request, - contractAddress: data.result.typedData.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainPostGateway.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainPostGateway.ts deleted file mode 100644 index ad704481df..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/CreateOnChainPostGateway.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { - CreatePostTypedDataDocument, - CreatePostTypedDataData, - CreatePostTypedDataVariables, - CreatePostViaDispatcherDocument, - CreatePostViaDispatcherData, - CreatePostViaDispatcherVariables, - CreatePublicPostRequest as CreatePublicPostRequestArg, - SafeApolloClient, - omitTypename, - CreatePostEip712TypedData, -} from '@lens-protocol/api-bindings'; -import { lensHub } from '@lens-protocol/blockchain-bindings'; -import { NativeTransaction, Nonce } from '@lens-protocol/domain/entities'; -import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - IDelegatedTransactionGateway, - IOnChainProtocolCallGateway, -} from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; -import { v4 } from 'uuid'; - -import { UnsignedProtocolCall } from '../../../wallet/adapters/ConcreteWallet'; -import { IMetadataUploader } from '../IMetadataUploader'; -import { ITransactionFactory } from '../ITransactionFactory'; -import { - Data, - SelfFundedProtocolTransactionRequest, -} from '../SelfFundedProtocolTransactionRequest'; -import { handleRelayError, OnChainBroadcastReceipt } from '../relayer'; -import { resolveCollectModuleParams } from './resolveCollectModuleParams'; -import { resolveReferenceModuleParams } from './resolveReferenceModuleParams'; - -export class CreateOnChainPostGateway - implements - IDelegatedTransactionGateway, - IOnChainProtocolCallGateway -{ - constructor( - private readonly apolloClient: SafeApolloClient, - private readonly transactionFactory: ITransactionFactory, - private readonly metadataUploader: IMetadataUploader, - ) {} - - async createDelegatedTransaction( - request: CreatePostRequest, - ): PromiseResult, BroadcastingError> { - const result = await this.broadcast(request); - - if (result.isFailure()) return failure(result.error); - - const receipt = result.value; - const transaction = this.transactionFactory.createNativeTransaction({ - chainType: ChainType.POLYGON, - id: v4(), - request, - indexingId: receipt.indexingId, - txHash: receipt.txHash, - }); - - return success(transaction); - } - - async createUnsignedProtocolCall( - request: CreatePostRequest, - nonce?: Nonce, - ): Promise> { - const requestArg = await this.resolveCreatePostRequestArg(request); - const data = await this.createTypedData(requestArg, nonce); - - return UnsignedProtocolCall.create({ - id: data.result.id, - request, - typedData: omitTypename(data.result.typedData), - fallback: this.createRequestFallback(request, data.result.typedData), - }); - } - - private async broadcast( - request: CreatePostRequest, - ): PromiseResult { - const requestArg = await this.resolveCreatePostRequestArg(request); - - const { data } = await this.apolloClient.mutate< - CreatePostViaDispatcherData, - CreatePostViaDispatcherVariables - >({ - mutation: CreatePostViaDispatcherDocument, - variables: { - request: requestArg, - }, - }); - - if (data.result.__typename === 'RelayError') { - const typedData = await this.createTypedData(requestArg); - const fallback = this.createRequestFallback(request, typedData.result.typedData); - - return handleRelayError(data.result, fallback); - } - - return success({ - indexingId: data.result.txId, - txHash: data.result.txHash, - }); - } - - private async createTypedData( - requestArg: CreatePublicPostRequestArg, - nonce?: Nonce, - ): Promise { - const { data } = await this.apolloClient.mutate< - CreatePostTypedDataData, - CreatePostTypedDataVariables - >({ - mutation: CreatePostTypedDataDocument, - variables: { - request: requestArg, - options: nonce ? { overrideSigNonce: nonce } : undefined, - }, - }); - return data; - } - - private async resolveCreatePostRequestArg( - request: CreatePostRequest, - ): Promise { - return { - contentURI: await this.metadataUploader.upload(request), - profileId: request.profileId, - collectModule: resolveCollectModuleParams(request), - referenceModule: resolveReferenceModuleParams(request), - }; - } - - private createRequestFallback( - request: CreatePostRequest, - data: CreatePostEip712TypedData, - ): SelfFundedProtocolTransactionRequest { - const contract = lensHub(data.domain.verifyingContract); - const encodedData = contract.interface.encodeFunctionData('post', [ - { - profileId: data.message.profileId, - contentURI: data.message.contentURI, - collectModule: data.message.collectModule, - collectModuleInitData: data.message.collectModuleInitData, - referenceModule: data.message.referenceModule, - referenceModuleInitData: data.message.referenceModuleInitData, - }, - ]); - return { - ...request, - contractAddress: data.domain.verifyingContract, - encodedData: encodedData as Data, - }; - } -} diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainCommentGateway.spec.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainCommentGateway.spec.ts deleted file mode 100644 index 6277889007..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainCommentGateway.spec.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { SafeApolloClient, RelayErrorReasons } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockDataAvailabilityPublicationResult, - mockRelayErrorFragment, - mockCreateDataAvailabilityCommentTypedDataResponse, - mockCreateCommentTypedDataData, - mockCreateDataAvailabilityCommentViaDispatcherDataResponse, -} from '@lens-protocol/api-bindings/mocks'; -import { DataTransaction } from '@lens-protocol/domain/entities'; -import { mockCreateCommentRequest } from '@lens-protocol/domain/mocks'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { Url } from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../../../wallet/adapters/ConcreteWallet'; -import { - mockITransactionFactory, - mockIMetadataUploader, - assertUnsignedProtocolCallCorrectness, - assertBroadcastingErrorResultWithRequestFallback, -} from '../../__helpers__/mocks'; -import { CreateOffChainCommentGateway } from '../CreateOffChainCommentGateway'; - -function setupTestScenario({ - apolloClient, - uploadUrl, -}: { - apolloClient: SafeApolloClient; - uploadUrl: Url; -}) { - const transactionFactory = mockITransactionFactory(); - const uploader = mockIMetadataUploader(uploadUrl); - - const gateway = new CreateOffChainCommentGateway(apolloClient, transactionFactory, uploader); - - return { gateway, uploader }; -} - -describe(`Given an instance of ${CreateOffChainCommentGateway.name}`, () => { - const data = mockCreateCommentTypedDataData(); - const uploadUrl = faker.internet.url(); - - describe(`when creating an IUnsignedProtocolCall`, () => { - const request = mockCreateCommentRequest(); - - it(`should: - - use the IMetadataUploader to upload the publication metadata - - create an instance of the ${UnsignedProtocolCall.name} with the expected typed data`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreateDataAvailabilityCommentTypedDataResponse({ - variables: { - request: { - commentOn: request.publicationId, - from: request.profileId, - contentURI: uploadUrl, - }, - }, - data, - }), - ]); - - const { gateway, uploader } = setupTestScenario({ apolloClient, uploadUrl }); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request); - - expect(uploader.upload).toHaveBeenCalledWith(request); - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - }); - - describe(`when creating a ${DataTransaction.name}`, () => { - const request = mockCreateCommentRequest(); - - it(`should: - - use the IMetadataUploader to upload the publication metadata - - create an instance of the ${DataTransaction.name}`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreateDataAvailabilityCommentViaDispatcherDataResponse({ - variables: { - request: { - commentOn: request.publicationId, - from: request.profileId, - contentURI: uploadUrl, - }, - }, - data: { - result: mockDataAvailabilityPublicationResult(), - }, - }), - ]); - const { gateway, uploader } = setupTestScenario({ apolloClient, uploadUrl }); - - const result = await gateway.createDelegatedTransaction(request); - - expect(uploader.upload).toHaveBeenCalledWith(request); - expect(result.unwrap()).toBeInstanceOf(DataTransaction); - expect(result.unwrap()).toEqual( - expect.objectContaining({ - id: expect.any(String), - request, - }), - ); - }); - - it.each([ - mockRelayErrorFragment(RelayErrorReasons.Rejected), - mockRelayErrorFragment(RelayErrorReasons.NotAllowed), - ])( - `should fail w/ a ${BroadcastingError.name} in case of RelayError response with "$reason" reason`, - async (relayError) => { - const apolloClient = mockLensApolloClient([ - mockCreateDataAvailabilityCommentViaDispatcherDataResponse({ - variables: { - request: { - commentOn: request.publicationId, - from: request.profileId, - contentURI: uploadUrl, - }, - }, - data: { - result: relayError, - }, - }), - mockCreateDataAvailabilityCommentTypedDataResponse({ - variables: { - request: { - commentOn: request.publicationId, - from: request.profileId, - contentURI: uploadUrl, - }, - }, - data, - }), - ]); - - const { gateway } = setupTestScenario({ apolloClient, uploadUrl }); - const result = await gateway.createDelegatedTransaction(request); - - assertBroadcastingErrorResultWithRequestFallback(result, data.result.typedData); - }, - ); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainMirrorGateway.spec.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainMirrorGateway.spec.ts deleted file mode 100644 index e19148e075..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainMirrorGateway.spec.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { SafeApolloClient, RelayErrorReasons } from '@lens-protocol/api-bindings'; -import { - mockCreateDataAvailabilityMirrorTypedDataResponse, - mockCreateDataAvailabilityMirrorViaDispatcherDataResponse, - mockLensApolloClient, - mockCreateMirrorTypedDataData, - mockDataAvailabilityPublicationResult, - mockRelayErrorFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { DataTransaction } from '@lens-protocol/domain/entities'; -import { mockCreateMirrorRequest } from '@lens-protocol/domain/mocks'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; - -import { UnsignedProtocolCall } from '../../../../wallet/adapters/ConcreteWallet'; -import { - mockITransactionFactory, - assertUnsignedProtocolCallCorrectness, - assertBroadcastingErrorResultWithRequestFallback, -} from '../../__helpers__/mocks'; -import { CreateOffChainMirrorGateway } from '../CreateOffChainMirrorGateway'; - -function setupTestScenario({ apolloClient }: { apolloClient: SafeApolloClient }) { - const transactionFactory = mockITransactionFactory(); - - const gateway = new CreateOffChainMirrorGateway(apolloClient, transactionFactory); - - return { gateway }; -} - -describe(`Given an instance of ${CreateOffChainMirrorGateway.name}`, () => { - const data = mockCreateMirrorTypedDataData(); - - describe(`when creating an IUnsignedProtocolCall`, () => { - const request = mockCreateMirrorRequest(); - - it(`should create an instance of the ${UnsignedProtocolCall.name} with the expected typed data`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreateDataAvailabilityMirrorTypedDataResponse({ - variables: { - request: { - from: request.profileId, - mirror: request.publicationId, - }, - }, - data, - }), - ]); - - const { gateway } = setupTestScenario({ apolloClient }); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request); - - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - }); - - describe(`when creating a ${DataTransaction.name}`, () => { - const request = mockCreateMirrorRequest(); - - it(`should create an instance of the ${DataTransaction.name}`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreateDataAvailabilityMirrorViaDispatcherDataResponse({ - variables: { - request: { - from: request.profileId, - mirror: request.publicationId, - }, - }, - data: { - result: mockDataAvailabilityPublicationResult(), - }, - }), - ]); - const { gateway } = setupTestScenario({ apolloClient }); - - const result = await gateway.createDelegatedTransaction(request); - - expect(result.unwrap()).toBeInstanceOf(DataTransaction); - expect(result.unwrap()).toEqual( - expect.objectContaining({ - id: expect.any(String), - request, - }), - ); - }); - - it.each([ - mockRelayErrorFragment(RelayErrorReasons.Rejected), - mockRelayErrorFragment(RelayErrorReasons.NotAllowed), - ])( - `should fail w/ a ${BroadcastingError.name} in case of RelayError response with "$reason" reason`, - async (relayError) => { - const apolloClient = mockLensApolloClient([ - mockCreateDataAvailabilityMirrorViaDispatcherDataResponse({ - variables: { - request: { - from: request.profileId, - mirror: request.publicationId, - }, - }, - data: { - result: relayError, - }, - }), - mockCreateDataAvailabilityMirrorTypedDataResponse({ - variables: { - request: { - from: request.profileId, - mirror: request.publicationId, - }, - }, - data, - }), - ]); - - const { gateway } = setupTestScenario({ apolloClient }); - const result = await gateway.createDelegatedTransaction(request); - - assertBroadcastingErrorResultWithRequestFallback(result, data.result.typedData); - }, - ); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainPostGateway.spec.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainPostGateway.spec.ts deleted file mode 100644 index 81eb44226e..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOffChainPostGateway.spec.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { SafeApolloClient, RelayErrorReasons } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockCreatePostTypedDataData, - mockCreateDataAvailabilityPostTypedDataResponse, - mockCreateDataAvailabilityPostViaDispatcherDataResponse, - mockDataAvailabilityPublicationResult, - mockRelayErrorFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { DataTransaction } from '@lens-protocol/domain/entities'; -import { mockCreatePostRequest } from '@lens-protocol/domain/mocks'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { Url } from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../../../wallet/adapters/ConcreteWallet'; -import { - mockITransactionFactory, - mockIMetadataUploader, - assertUnsignedProtocolCallCorrectness, - assertBroadcastingErrorResultWithRequestFallback, -} from '../../__helpers__/mocks'; -import { CreateOffChainPostGateway } from '../CreateOffChainPostGateway'; - -function setupTestScenario({ - apolloClient, - uploadUrl, -}: { - apolloClient: SafeApolloClient; - uploadUrl: Url; -}) { - const transactionFactory = mockITransactionFactory(); - const uploader = mockIMetadataUploader(uploadUrl); - - const gateway = new CreateOffChainPostGateway(apolloClient, transactionFactory, uploader); - - return { gateway, uploader }; -} - -describe(`Given an instance of ${CreateOffChainPostGateway.name}`, () => { - const data = mockCreatePostTypedDataData(); - const uploadUrl = faker.internet.url(); - - describe(`when creating an IUnsignedProtocolCall`, () => { - const request = mockCreatePostRequest(); - - it(`should: - - use the IMetadataUploader to upload the publication metadata - - create an instance of the ${UnsignedProtocolCall.name} with the expected typed data`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreateDataAvailabilityPostTypedDataResponse({ - variables: { - request: { - from: request.profileId, - contentURI: uploadUrl, - }, - }, - data, - }), - ]); - - const { gateway, uploader } = setupTestScenario({ apolloClient, uploadUrl }); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request); - - expect(uploader.upload).toHaveBeenCalledWith(request); - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - }); - - describe(`when creating a ${DataTransaction.name}`, () => { - const request = mockCreatePostRequest(); - - it(`should: - - use the IMetadataUploader to upload the publication metadata - - create an instance of the ${DataTransaction.name}`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreateDataAvailabilityPostViaDispatcherDataResponse({ - variables: { - request: { - from: request.profileId, - contentURI: uploadUrl, - }, - }, - data: { - result: mockDataAvailabilityPublicationResult(), - }, - }), - ]); - const { gateway, uploader } = setupTestScenario({ apolloClient, uploadUrl }); - - const result = await gateway.createDelegatedTransaction(request); - - expect(uploader.upload).toHaveBeenCalledWith(request); - expect(result.unwrap()).toBeInstanceOf(DataTransaction); - expect(result.unwrap()).toEqual( - expect.objectContaining({ - id: expect.any(String), - request, - }), - ); - }); - - it.each([ - mockRelayErrorFragment(RelayErrorReasons.Rejected), - mockRelayErrorFragment(RelayErrorReasons.NotAllowed), - ])( - `should fail w/ a ${BroadcastingError.name} in case of RelayError response with "$reason" reason`, - async (relayError) => { - const apolloClient = mockLensApolloClient([ - mockCreateDataAvailabilityPostViaDispatcherDataResponse({ - variables: { - request: { - from: request.profileId, - contentURI: uploadUrl, - }, - }, - data: { - result: relayError, - }, - }), - mockCreateDataAvailabilityPostTypedDataResponse({ - variables: { - request: { - from: request.profileId, - contentURI: uploadUrl, - }, - }, - data, - }), - ]); - - const { gateway } = setupTestScenario({ apolloClient, uploadUrl }); - const result = await gateway.createDelegatedTransaction(request); - - assertBroadcastingErrorResultWithRequestFallback(result, data.result.typedData); - }, - ); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainCommentGateway.spec.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainCommentGateway.spec.ts deleted file mode 100644 index b8e440c911..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainCommentGateway.spec.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { SafeApolloClient, RelayErrorReasons } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockRelayerResultFragment, - mockCreateCommentTypedDataData, - mockCreateCommentTypedDataResponse, - mockCreateCommentViaDispatcherResponse, - mockRelayErrorFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { NativeTransaction } from '@lens-protocol/domain/entities'; -import { mockNonce, mockCreateCommentRequest } from '@lens-protocol/domain/mocks'; -import { - CollectPolicyType, - ReferencePolicyType, -} from '@lens-protocol/domain/use-cases/publications'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, Url } from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../../../wallet/adapters/ConcreteWallet'; -import { - assertBroadcastingErrorResultWithRequestFallback, - assertUnsignedProtocolCallCorrectness, - mockIMetadataUploader, - mockITransactionFactory, -} from '../../__helpers__/mocks'; -import { CreateOnChainCommentGateway } from '../CreateOnChainCommentGateway'; - -function setupTestScenario({ - apolloClient, - uploadUrl, -}: { - apolloClient: SafeApolloClient; - uploadUrl: Url; -}) { - const transactionFactory = mockITransactionFactory(); - const uploader = mockIMetadataUploader(uploadUrl); - - const gateway = new CreateOnChainCommentGateway(apolloClient, transactionFactory, uploader); - - return { gateway, uploader }; -} - -describe(`Given an instance of ${CreateOnChainCommentGateway.name}`, () => { - const request = mockCreateCommentRequest({ - collect: { - type: CollectPolicyType.NO_COLLECT, - }, - reference: { - type: ReferencePolicyType.ANYONE, - }, - }); - const expectedMutationRequestDetails = { - collectModule: { - revertCollectModule: true, - }, - }; - const uploadUrl = faker.internet.url(); - const data = mockCreateCommentTypedDataData(); - - describe(`when creating an IUnsignedProtocolCall`, () => { - it(`should: - - use the IMetadataUploader to upload the publication metadata - - create an instance of the ${UnsignedProtocolCall.name} with the expected typed data`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreateCommentTypedDataResponse({ - variables: { - request: { - contentURI: uploadUrl, - profileId: request.profileId, - publicationId: request.publicationId, - ...expectedMutationRequestDetails, - }, - }, - data, - }), - ]); - const { gateway, uploader } = setupTestScenario({ apolloClient, uploadUrl }); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request); - - expect(uploader.upload).toHaveBeenCalledWith(request); - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - - it(`should be possible to override the signature nonce`, async () => { - const nonce = mockNonce(); - const apolloClient = mockLensApolloClient([ - mockCreateCommentTypedDataResponse({ - variables: { - request: { - contentURI: uploadUrl, - profileId: request.profileId, - publicationId: request.publicationId, - ...expectedMutationRequestDetails, - }, - options: { - overrideSigNonce: nonce, - }, - }, - data: mockCreateCommentTypedDataData({ nonce }), - }), - ]); - const { gateway } = setupTestScenario({ apolloClient, uploadUrl }); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request, nonce); - - expect(unsignedCall.nonce).toEqual(nonce); - }); - }); - - describe(`when creating a ${NativeTransaction.name}}"`, () => { - it(`should: - - use the IMetadataUploader to upload the publication metadata - - create an instance of the ${NativeTransaction.name}`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreateCommentViaDispatcherResponse({ - variables: { - request: { - contentURI: uploadUrl, - profileId: request.profileId, - publicationId: request.publicationId, - - ...expectedMutationRequestDetails, - }, - }, - data: { - result: mockRelayerResultFragment(), - }, - }), - ]); - - const { gateway, uploader } = setupTestScenario({ apolloClient, uploadUrl }); - - const result = await gateway.createDelegatedTransaction(request); - - expect(uploader.upload).toHaveBeenCalledWith(request); - expect(result.unwrap()).toBeInstanceOf(NativeTransaction); - expect(result.unwrap()).toEqual( - expect.objectContaining({ - chainType: ChainType.POLYGON, - id: expect.any(String), - request, - }), - ); - }); - - it.each([ - mockRelayErrorFragment(RelayErrorReasons.Rejected), - mockRelayErrorFragment(RelayErrorReasons.NotAllowed), - ])( - `should fail w/ a ${BroadcastingError.name} in case of RelayError response with "$reason" reason`, - async (relayError) => { - const apolloClient = mockLensApolloClient([ - mockCreateCommentViaDispatcherResponse({ - variables: { - request: { - contentURI: uploadUrl, - profileId: request.profileId, - publicationId: request.publicationId, - - ...expectedMutationRequestDetails, - }, - }, - data: { - result: relayError, - }, - }), - mockCreateCommentTypedDataResponse({ - variables: { - request: { - contentURI: uploadUrl, - profileId: request.profileId, - publicationId: request.publicationId, - ...expectedMutationRequestDetails, - }, - }, - data, - }), - ]); - - const { gateway } = setupTestScenario({ apolloClient, uploadUrl }); - - const result = await gateway.createDelegatedTransaction(request); - - assertBroadcastingErrorResultWithRequestFallback(result, data.result.typedData); - }, - ); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainMirrorGateway.spec.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainMirrorGateway.spec.ts deleted file mode 100644 index feeb8df2eb..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainMirrorGateway.spec.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { SafeApolloClient, RelayErrorReasons } from '@lens-protocol/api-bindings'; -import { - mockCreateMirrorTypedDataResponse, - mockCreateMirrorViaDispatcherResponse, - mockLensApolloClient, - mockCreateMirrorTypedDataData, - mockRelayerResultFragment, - mockRelayErrorFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { NativeTransaction } from '@lens-protocol/domain/entities'; -import { mockCreateMirrorRequest } from '@lens-protocol/domain/mocks'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; - -import { UnsignedProtocolCall } from '../../../../wallet/adapters/ConcreteWallet'; -import { - mockITransactionFactory, - assertUnsignedProtocolCallCorrectness, - assertBroadcastingErrorResultWithRequestFallback, -} from '../../__helpers__/mocks'; -import { CreateOnChainMirrorGateway } from '../CreateOnChainMirrorGateway'; - -function setupTestScenario({ apolloClient }: { apolloClient: SafeApolloClient }) { - const transactionFactory = mockITransactionFactory(); - - const gateway = new CreateOnChainMirrorGateway(apolloClient, transactionFactory); - - return { gateway }; -} - -describe(`Given an instance of ${CreateOnChainMirrorGateway.name}`, () => { - const data = mockCreateMirrorTypedDataData(); - - describe(`when creating an IUnsignedProtocolCall`, () => { - const request = mockCreateMirrorRequest(); - - it(`should create an instance of the ${UnsignedProtocolCall.name} with the expected typed data`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreateMirrorTypedDataResponse({ - variables: { - request: { - profileId: request.profileId, - publicationId: request.publicationId, - }, - }, - data, - }), - ]); - - const { gateway } = setupTestScenario({ apolloClient }); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request); - - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - }); - - describe(`when creating a ${NativeTransaction.name}`, () => { - const request = mockCreateMirrorRequest(); - - it(`should create an instance of the ${NativeTransaction.name}`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreateMirrorViaDispatcherResponse({ - variables: { - request: { - profileId: request.profileId, - publicationId: request.publicationId, - }, - }, - data: { - result: mockRelayerResultFragment(), - }, - }), - ]); - const { gateway } = setupTestScenario({ apolloClient }); - - const result = await gateway.createDelegatedTransaction(request); - - expect(result.unwrap()).toBeInstanceOf(NativeTransaction); - expect(result.unwrap()).toEqual( - expect.objectContaining({ - id: expect.any(String), - request, - }), - ); - }); - - it.each([ - mockRelayErrorFragment(RelayErrorReasons.Rejected), - mockRelayErrorFragment(RelayErrorReasons.NotAllowed), - ])( - `should fail w/ a ${BroadcastingError.name} in case of RelayError response with "$reason" reason`, - async (relayError) => { - const apolloClient = mockLensApolloClient([ - mockCreateMirrorViaDispatcherResponse({ - variables: { - request: { - profileId: request.profileId, - publicationId: request.publicationId, - }, - }, - data: { - result: relayError, - }, - }), - mockCreateMirrorTypedDataResponse({ - variables: { - request: { - profileId: request.profileId, - publicationId: request.publicationId, - }, - }, - data, - }), - ]); - - const { gateway } = setupTestScenario({ apolloClient }); - const result = await gateway.createDelegatedTransaction(request); - - assertBroadcastingErrorResultWithRequestFallback(result, data.result.typedData); - }, - ); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainPostGateway.spec.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainPostGateway.spec.ts deleted file mode 100644 index a8fdb73848..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/CreateOnChainPostGateway.spec.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { SafeApolloClient, RelayErrorReasons } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockCreatePostTypedDataData, - mockRelayerResultFragment, - mockCreatePostTypedDataResponse, - mockCreatePostViaDispatcherResponse, - mockRelayErrorFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { NativeTransaction } from '@lens-protocol/domain/entities'; -import { mockNonce, mockCreatePostRequest } from '@lens-protocol/domain/mocks'; -import { - CollectPolicyType, - ReferencePolicyType, -} from '@lens-protocol/domain/use-cases/publications'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, Url } from '@lens-protocol/shared-kernel'; - -import { UnsignedProtocolCall } from '../../../../wallet/adapters/ConcreteWallet'; -import { - mockITransactionFactory, - mockIMetadataUploader, - assertUnsignedProtocolCallCorrectness, - assertBroadcastingErrorResultWithRequestFallback, -} from '../../__helpers__/mocks'; -import { CreateOnChainPostGateway } from '../CreateOnChainPostGateway'; - -function setupTestScenario({ - apolloClient, - uploadUrl, -}: { - apolloClient: SafeApolloClient; - uploadUrl: Url; -}) { - const transactionFactory = mockITransactionFactory(); - const uploader = mockIMetadataUploader(uploadUrl); - - const gateway = new CreateOnChainPostGateway(apolloClient, transactionFactory, uploader); - - return { gateway, uploader }; -} - -describe(`Given an instance of ${CreateOnChainPostGateway.name}`, () => { - const request = mockCreatePostRequest({ - collect: { - type: CollectPolicyType.NO_COLLECT, - }, - reference: { - type: ReferencePolicyType.ANYONE, - }, - }); - const expectedMutationRequestDetails = { - collectModule: { - revertCollectModule: true, - }, - }; - const data = mockCreatePostTypedDataData(); - const uploadUrl = faker.internet.url(); - - describe(`when creating an IUnsignedProtocolCall`, () => { - it(`should: - - use the IMetadataUploader to upload the publication metadata - - create an instance of the ${UnsignedProtocolCall.name} with the expected typed data`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreatePostTypedDataResponse({ - variables: { - request: { - profileId: request.profileId, - contentURI: uploadUrl, - ...expectedMutationRequestDetails, - }, - }, - data, - }), - ]); - const { gateway, uploader } = setupTestScenario({ apolloClient, uploadUrl }); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request); - - expect(uploader.upload).toHaveBeenCalledWith(request); - assertUnsignedProtocolCallCorrectness(unsignedCall, data.result); - }); - - it(`should allow to override the signature nonce`, async () => { - const nonce = mockNonce(); - const apolloClient = mockLensApolloClient([ - mockCreatePostTypedDataResponse({ - variables: { - request: { - profileId: request.profileId, - contentURI: uploadUrl, - ...expectedMutationRequestDetails, - }, - options: { - overrideSigNonce: nonce, - }, - }, - data: mockCreatePostTypedDataData({ nonce }), - }), - ]); - const { gateway } = setupTestScenario({ apolloClient, uploadUrl }); - - const unsignedCall = await gateway.createUnsignedProtocolCall(request, nonce); - - expect(unsignedCall.nonce).toEqual(nonce); - }); - }); - - describe(`when creating a ${NativeTransaction.name}`, () => { - it(`should: - - use the IMetadataUploader to upload the publication metadata - - create an instance of the ${NativeTransaction.name}`, async () => { - const apolloClient = mockLensApolloClient([ - mockCreatePostViaDispatcherResponse({ - variables: { - request: { - profileId: request.profileId, - contentURI: uploadUrl, - ...expectedMutationRequestDetails, - }, - }, - data: { - result: mockRelayerResultFragment(), - }, - }), - ]); - const { gateway, uploader } = setupTestScenario({ apolloClient, uploadUrl }); - - const result = await gateway.createDelegatedTransaction(request); - - expect(uploader.upload).toHaveBeenCalledWith(request); - expect(result.unwrap()).toBeInstanceOf(NativeTransaction); - expect(result.unwrap()).toEqual( - expect.objectContaining({ - chainType: ChainType.POLYGON, - id: expect.any(String), - request, - }), - ); - }); - - it.each([ - mockRelayErrorFragment(RelayErrorReasons.Rejected), - mockRelayErrorFragment(RelayErrorReasons.NotAllowed), - ])( - `should fail w/ a ${BroadcastingError.name} in case of RelayError response with "$reason" reason`, - async (relayError) => { - const apolloClient = mockLensApolloClient([ - mockCreatePostViaDispatcherResponse({ - variables: { - request: { - profileId: request.profileId, - contentURI: uploadUrl, - ...expectedMutationRequestDetails, - }, - }, - data: { - result: relayError, - }, - }), - mockCreatePostTypedDataResponse({ - variables: { - request: { - profileId: request.profileId, - contentURI: uploadUrl, - ...expectedMutationRequestDetails, - }, - }, - data, - }), - ]); - - const { gateway } = setupTestScenario({ apolloClient, uploadUrl }); - const result = await gateway.createDelegatedTransaction(request); - - assertBroadcastingErrorResultWithRequestFallback(result, data.result.typedData); - }, - ); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/resolveCollectModuleParams.spec.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/resolveCollectModuleParams.spec.ts deleted file mode 100644 index 2e2fe07963..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/resolveCollectModuleParams.spec.ts +++ /dev/null @@ -1,407 +0,0 @@ -import { - mockChargeCollectPolicyConfig, - mockCreateCommentRequest, - mockCreatePostRequest, - mockFreeCollectPolicyConfig, -} from '@lens-protocol/domain/mocks'; -import { CollectPolicyType } from '@lens-protocol/domain/use-cases/publications'; -import { never } from '@lens-protocol/shared-kernel'; -import { mockDaiAmount } from '@lens-protocol/shared-kernel/mocks'; - -import { resolveCollectModuleParams } from '../resolveCollectModuleParams'; - -jest.useFakeTimers(); - -const KNOWN_END_TIMESTAMP = new Date(1991, 6, 3).getTime(); -const TIMESTAMP_24_HOURS = 1000 * 60 * 60 * 24; - -describe(`Given the ${resolveCollectModuleParams.name} function`, () => { - describe.each([ - { - type: 'CreatePostRequest', - mockRequest: mockCreatePostRequest, - }, - { - type: 'CreateCommentRequest', - mockRequest: mockCreateCommentRequest, - }, - ])('when called with a "$type"', ({ mockRequest }) => { - describe(`that has ${CollectPolicyType.NO_COLLECT} collect policy`, () => { - it(`should resolve with the "revertCollectModule" with the expected parameters`, async () => { - const request = mockRequest({ - collect: { type: CollectPolicyType.NO_COLLECT }, - }); - - const collectModule = resolveCollectModuleParams(request); - - expect(collectModule).toEqual({ - revertCollectModule: true, - }); - }); - }); - - describe(`that has ${CollectPolicyType.FREE} collect policy`, () => { - describe.each([ - { - description: 'with just "followersOnly" specified', - request: mockRequest({ - collect: mockFreeCollectPolicyConfig({ - followersOnly: true, - }), - }), - expected: { - simpleCollectModule: { - followerOnly: true, - }, - }, - }, - - { - description: 'with a "collectLimit" specified', - request: mockRequest({ - collect: mockFreeCollectPolicyConfig({ - followersOnly: true, - collectLimit: 10, - }), - }), - expected: { - simpleCollectModule: { - followerOnly: true, - collectLimit: '10', - }, - }, - }, - - { - description: 'with an "endTimestamp" specified', - request: mockRequest({ - collect: mockFreeCollectPolicyConfig({ - followersOnly: true, - endTimestamp: KNOWN_END_TIMESTAMP, - }), - }), - expected: { - simpleCollectModule: { - followerOnly: true, - endTimestamp: KNOWN_END_TIMESTAMP.toString(), - }, - }, - }, - ])(`$description`, ({ request, expected }) => { - const collectModuleParamsKey = Object.keys(expected)[0] ?? never(); - - it(`should resolve with the "${collectModuleParamsKey}" with the expected parameters`, async () => { - const collectModule = resolveCollectModuleParams(request); - - expect(collectModule).toEqual(expected); - }); - }); - }); - - describe(`that has ${CollectPolicyType.CHARGE} collect policy`, () => { - const fee = mockDaiAmount(5); - const recipients = [ - { - recipient: '0xEEA0C1f5ab0159dba749Dc0BAee462E5e293daaF', - split: 50, - }, - { - recipient: '0xEEA0C1f5ab0159dba749Dc0BAee462E5e293daaB', - split: 50, - }, - ]; - - describe.each([ - { - description: 'with just a "fee" and "followersOnly" specified', - request: mockRequest({ - collect: mockChargeCollectPolicyConfig({ - recipient: '0x', - followersOnly: true, - mirrorReward: 0, - fee, - }), - }), - expected: { - simpleCollectModule: { - fee: { - amount: { - currency: '0x6b175474e89094c44da98b954eedeac495271d0f', - value: '5', - }, - recipient: '0x', - referralFee: 0, - }, - followerOnly: true, - }, - }, - }, - - { - description: 'with also a "collectLimit" specified', - request: mockRequest({ - collect: mockChargeCollectPolicyConfig({ - recipient: '0x', - followersOnly: true, - mirrorReward: 0, - fee, - collectLimit: 10, - }), - }), - expected: { - simpleCollectModule: { - fee: { - amount: { - currency: '0x6b175474e89094c44da98b954eedeac495271d0f', - value: '5', - }, - recipient: '0x', - referralFee: 0, - }, - followerOnly: true, - collectLimit: '10', - }, - }, - }, - - { - description: 'with also "endTimestamp" specified', - request: mockRequest({ - collect: mockChargeCollectPolicyConfig({ - recipient: '0x', - followersOnly: true, - mirrorReward: 0, - fee, - endTimestamp: KNOWN_END_TIMESTAMP, - }), - }), - expected: { - simpleCollectModule: { - fee: { - amount: { - currency: '0x6b175474e89094c44da98b954eedeac495271d0f', - value: '5', - }, - recipient: '0x', - referralFee: 0, - }, - followerOnly: true, - endTimestamp: KNOWN_END_TIMESTAMP.toString(), - }, - }, - }, - - { - description: 'with also a deprecated "timeLimited" specified', - request: mockRequest({ - collect: mockChargeCollectPolicyConfig({ - recipient: '0x', - followersOnly: true, - mirrorReward: 0, - fee, - timeLimited: true, - }), - }), - expected: { - simpleCollectModule: { - fee: { - amount: { - currency: '0x6b175474e89094c44da98b954eedeac495271d0f', - value: '5', - }, - recipient: '0x', - referralFee: 0, - }, - endTimestamp: (Date.now() + TIMESTAMP_24_HOURS).toString(), - followerOnly: true, - }, - }, - }, - - { - description: - 'with "fee" and "depositToAave" but without "collectLimit" or "endTimestamp"', - request: mockRequest({ - collect: mockChargeCollectPolicyConfig({ - recipient: '0x', - followersOnly: true, - mirrorReward: 0, - fee, - depositToAave: true, - }), - }), - expected: { - aaveFeeCollectModule: { - amount: { - currency: '0x6b175474e89094c44da98b954eedeac495271d0f', - value: '5', - }, - followerOnly: true, - recipient: '0x', - referralFee: 0, - }, - }, - }, - - { - description: 'with "fee", "depositToAave", "collectLimit" and "endTimestamp"', - request: mockRequest({ - collect: mockChargeCollectPolicyConfig({ - recipient: '0x', - followersOnly: true, - mirrorReward: 0, - fee, - depositToAave: true, - collectLimit: 10, - endTimestamp: 1679501207007, - }), - }), - expected: { - aaveFeeCollectModule: { - amount: { - currency: '0x6b175474e89094c44da98b954eedeac495271d0f', - value: '5', - }, - followerOnly: true, - recipient: '0x', - referralFee: 0, - collectLimit: '10', - endTimestamp: '1679501207007', - }, - }, - }, - - { - description: 'with "fee" and "vault" but without "collectLimit" and "endTimestamp"', - request: mockRequest({ - collect: mockChargeCollectPolicyConfig({ - recipient: '0x', - followersOnly: true, - mirrorReward: 0, - fee, - vault: '0x', - }), - }), - expected: { - erc4626FeeCollectModule: { - amount: { - currency: '0x6b175474e89094c44da98b954eedeac495271d0f', - value: '5', - }, - followerOnly: true, - recipient: '0x', - referralFee: 0, - vault: '0x', - }, - }, - }, - - { - description: 'with "fee", "vault", "collectLimit" and "endTimestamp"', - request: mockRequest({ - collect: mockChargeCollectPolicyConfig({ - recipient: '0x', - followersOnly: true, - mirrorReward: 0, - fee, - vault: '0x', - collectLimit: 10, - endTimestamp: 1679501207007, - }), - }), - expected: { - erc4626FeeCollectModule: { - amount: { - currency: '0x6b175474e89094c44da98b954eedeac495271d0f', - value: '5', - }, - followerOnly: true, - recipient: '0x', - referralFee: 0, - vault: '0x', - collectLimit: '10', - endTimestamp: '1679501207007', - }, - }, - }, - - { - description: - 'with "fee", multiple "recipients" but without "collectLimit" and "endTimestamp"', - request: mockRequest({ - collect: mockChargeCollectPolicyConfig({ - followersOnly: true, - mirrorReward: 0, - fee, - recipients: [ - { - recipient: '0xEEA0C1f5ab0159dba749Dc0BAee462E5e293daaF', - split: 50, - }, - { - recipient: '0xEEA0C1f5ab0159dba749Dc0BAee462E5e293daaB', - split: 50, - }, - ], - }), - }), - expected: { - multirecipientFeeCollectModule: { - amount: { - currency: '0x6b175474e89094c44da98b954eedeac495271d0f', - value: '5', - }, - followerOnly: true, - referralFee: 0, - recipients: [ - { - recipient: '0xEEA0C1f5ab0159dba749Dc0BAee462E5e293daaF', - split: 50, - }, - { - recipient: '0xEEA0C1f5ab0159dba749Dc0BAee462E5e293daaB', - split: 50, - }, - ], - }, - }, - }, - - { - description: 'with "fee", multiple "recipients", "collectLimit" and "endTimestamp"', - request: mockRequest({ - collect: mockChargeCollectPolicyConfig({ - followersOnly: true, - mirrorReward: 0, - fee, - recipients, - collectLimit: 10, - endTimestamp: 1679501207007, - }), - }), - expected: { - multirecipientFeeCollectModule: { - amount: { - currency: '0x6b175474e89094c44da98b954eedeac495271d0f', - value: '5', - }, - followerOnly: true, - referralFee: 0, - recipients, - collectLimit: '10', - endTimestamp: '1679501207007', - }, - }, - }, - ])(`$description`, ({ request, expected }) => { - const collectModuleParamsKey = Object.keys(expected)[0] ?? never(); - - it(`should resolve with the "${collectModuleParamsKey}" with the expected parameters`, async () => { - const collectModule = resolveCollectModuleParams(request); - - expect(collectModule).toEqual(expected); - }); - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/resolveReferenceModuleParams.spec.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/resolveReferenceModuleParams.spec.ts deleted file mode 100644 index cc76141008..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/__tests__/resolveReferenceModuleParams.spec.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { mockCreateCommentRequest, mockCreatePostRequest } from '@lens-protocol/domain/mocks'; -import { ReferencePolicyType } from '@lens-protocol/domain/use-cases/publications'; - -import { resolveReferenceModuleParams } from '../resolveReferenceModuleParams'; - -describe(`Given the ${resolveReferenceModuleParams.name} function`, () => { - describe.each([ - { - type: 'CreatePostRequest', - mockRequest: mockCreatePostRequest, - }, - { - type: 'CreateCommentRequest', - mockRequest: mockCreateCommentRequest, - }, - ])('when called with a "$type"', ({ mockRequest }) => { - describe(`that has ${ReferencePolicyType.ANYONE} reference policy`, () => { - it(`should resolve with no reference module config`, async () => { - const request = mockRequest({ - reference: { type: ReferencePolicyType.ANYONE }, - }); - - const referenceModule = resolveReferenceModuleParams(request); - - expect(referenceModule).toBe(undefined); - }); - }); - - describe(`that has ${ReferencePolicyType.FOLLOWERS_ONLY} reference policy`, () => { - it(`should resolve with the "followerOnlyReferenceModule"`, async () => { - const request = mockRequest({ - reference: { type: ReferencePolicyType.FOLLOWERS_ONLY }, - }); - - const referenceModule = resolveReferenceModuleParams(request); - - expect(referenceModule).toEqual({ - followerOnlyReferenceModule: true, - }); - }); - }); - - describe(`that has ${ReferencePolicyType.DEGREES_OF_SEPARATION} reference policy`, () => { - it(`should resolve with the "followerOnlyReferenceModule"`, async () => { - const params = { - commentsRestricted: true, - mirrorsRestricted: true, - degreesOfSeparation: 6, - }; - const request = mockRequest({ - reference: { - type: ReferencePolicyType.DEGREES_OF_SEPARATION, - params, - }, - }); - - const referenceModule = resolveReferenceModuleParams(request); - - expect(referenceModule).toEqual({ - degreesOfSeparationReferenceModule: params, - }); - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/resolveCollectModuleParams.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/resolveCollectModuleParams.ts deleted file mode 100644 index 9389bcaf25..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/resolveCollectModuleParams.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { CollectModuleParams, ModuleFeeParams } from '@lens-protocol/api-bindings'; -import { - CollectPolicyType, - CreatePostRequest, - CreateCommentRequest, - AaveChargeCollectPolicyConfig, - VaultChargeCollectPolicyConfig, - MultirecipientChargeCollectPolicyConfig, - ChargeCollectPolicyConfig, - CollectPolicyConfig, - SimpleChargeCollectPolicyConfig, -} from '@lens-protocol/domain/use-cases/publications'; - -function isAaveChargeCollectPolicy( - collect: ChargeCollectPolicyConfig, -): collect is AaveChargeCollectPolicyConfig { - return 'depositToAave' in collect && collect.depositToAave; -} - -function isVaultChargeCollectPolicy( - collect: ChargeCollectPolicyConfig, -): collect is VaultChargeCollectPolicyConfig { - return 'vault' in collect; -} - -function isMultirecipientChargeCollectPolicy( - collect: ChargeCollectPolicyConfig, -): collect is MultirecipientChargeCollectPolicyConfig { - return 'recipients' in collect; -} - -function resolveChargeCollectModuleSharedParams(collect: ChargeCollectPolicyConfig) { - return { - amount: { - currency: collect.fee.asset.address, - value: collect.fee.toSignificantDigits(), - }, - followerOnly: collect.followersOnly, - referralFee: collect.mirrorReward, - }; -} - -function resolveModuleFeeParams(collect: SimpleChargeCollectPolicyConfig): ModuleFeeParams { - return { - amount: { - currency: collect.fee.asset.address, - value: collect.fee.toSignificantDigits(), - }, - referralFee: collect.mirrorReward, - recipient: collect.recipient, - }; -} - -function resolveOptionalCollectLimit(collect: CollectPolicyConfig) { - return { - ...('collectLimit' in collect && - collect.collectLimit && { collectLimit: collect.collectLimit.toString() }), - }; -} - -function resolveOptionalEndTimestamp(collect: CollectPolicyConfig) { - return { - ...('endTimestamp' in collect && - collect.endTimestamp && { endTimestamp: collect.endTimestamp.toString() }), - }; -} - -function oneDayFromNowTimestamp() { - return Date.now() + 24 * 60 * 60 * 1000; -} - -function resolveEndTimestampFromOptionalTimeLimited(collect: CollectPolicyConfig) { - return { - ...('timeLimited' in collect && - collect.timeLimited && { endTimestamp: oneDayFromNowTimestamp().toString() }), - }; -} - -function resolveChargeCollectModule(collect: ChargeCollectPolicyConfig): CollectModuleParams { - if (isAaveChargeCollectPolicy(collect)) { - return { - aaveFeeCollectModule: { - ...resolveChargeCollectModuleSharedParams(collect), - recipient: collect.recipient, - ...resolveOptionalCollectLimit(collect), - ...resolveOptionalEndTimestamp(collect), - }, - }; - } - - if (isVaultChargeCollectPolicy(collect)) { - return { - erc4626FeeCollectModule: { - ...resolveChargeCollectModuleSharedParams(collect), - recipient: collect.recipient, - vault: collect.vault, - ...resolveOptionalCollectLimit(collect), - ...resolveOptionalEndTimestamp(collect), - }, - }; - } - - if (isMultirecipientChargeCollectPolicy(collect)) { - return { - multirecipientFeeCollectModule: { - ...resolveChargeCollectModuleSharedParams(collect), - recipients: collect.recipients, - ...resolveOptionalCollectLimit(collect), - ...resolveOptionalEndTimestamp(collect), - }, - }; - } - - return { - simpleCollectModule: { - fee: resolveModuleFeeParams(collect), - followerOnly: collect.followersOnly, - ...resolveOptionalCollectLimit(collect), - ...resolveOptionalEndTimestamp(collect), - ...resolveEndTimestampFromOptionalTimeLimited(collect), - }, - }; -} - -export function resolveCollectModuleParams( - request: CreatePostRequest | CreateCommentRequest, -): CollectModuleParams { - switch (request.collect.type) { - case CollectPolicyType.FREE: - return { - simpleCollectModule: { - followerOnly: request.collect.followersOnly, - ...resolveOptionalCollectLimit(request.collect), - ...resolveOptionalEndTimestamp(request.collect), - }, - }; - - case CollectPolicyType.NO_COLLECT: - return { - revertCollectModule: true, - }; - - case CollectPolicyType.CHARGE: - return resolveChargeCollectModule(request.collect); - } -} diff --git a/packages/react-v1/src/transactions/adapters/publication-call-gateways/resolveReferenceModuleParams.ts b/packages/react-v1/src/transactions/adapters/publication-call-gateways/resolveReferenceModuleParams.ts deleted file mode 100644 index fad8ecb749..0000000000 --- a/packages/react-v1/src/transactions/adapters/publication-call-gateways/resolveReferenceModuleParams.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ReferenceModuleParams } from '@lens-protocol/api-bindings'; -import { - ReferencePolicyType, - CreatePostRequest, - CreateCommentRequest, -} from '@lens-protocol/domain/use-cases/publications'; - -export function resolveReferenceModuleParams( - request: CreatePostRequest | CreateCommentRequest, -): ReferenceModuleParams | undefined { - if (request.reference.type === ReferencePolicyType.FOLLOWERS_ONLY) { - return { - followerOnlyReferenceModule: true, - }; - } - - if (request.reference.type === ReferencePolicyType.DEGREES_OF_SEPARATION) { - return { - degreesOfSeparationReferenceModule: request.reference.params, - }; - } - - return undefined; -} diff --git a/packages/react-v1/src/transactions/adapters/relayer.ts b/packages/react-v1/src/transactions/adapters/relayer.ts deleted file mode 100644 index 3e049c8b38..0000000000 --- a/packages/react-v1/src/transactions/adapters/relayer.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { RelayError, RelayErrorReasons } from '@lens-protocol/api-bindings'; -import { - BroadcastingError, - ProtocolTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { failure, Failure, InvariantError } from '@lens-protocol/shared-kernel'; - -import { SelfFundedProtocolTransactionRequest } from './SelfFundedProtocolTransactionRequest'; - -export type OnChainBroadcastReceipt = { - indexingId: string; - txHash: string; -}; - -export type OffChainBroadcastReceipt = { - id: string; -}; - -export function handleRelayError( - error: RelayError, - fallback?: SelfFundedProtocolTransactionRequest, -): Failure { - switch (error.reason) { - case RelayErrorReasons.NotAllowed: - case RelayErrorReasons.Rejected: - return failure(new BroadcastingError(error.reason, fallback)); - default: - throw new InvariantError(`Unexpected relay error reason: ${error.reason}`); - } -} diff --git a/packages/react-v1/src/transactions/adapters/responders/CollectPublicationResponder.tsx b/packages/react-v1/src/transactions/adapters/responders/CollectPublicationResponder.tsx deleted file mode 100644 index 5c19bffb4c..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/CollectPublicationResponder.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { - GetPublicationData, - GetPublicationDocument, - GetPublicationVariables, - getSession, - PublicationStats, - SafeApolloClient, - SessionType, - Sources, -} from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; -import { CollectRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - ITransactionResponder, - TransactionData, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { - mediaTransformConfigToQueryVariables, - MediaTransformsConfig, -} from '../../../mediaTransforms'; - -export class CollectPublicationResponder implements ITransactionResponder { - constructor( - private readonly client: SafeApolloClient, - private readonly sources: Sources, - private readonly mediaTransforms: MediaTransformsConfig, - ) {} - - async prepare({ request }: TransactionData) { - const identifier = this.client.cache.identify({ - __typename: 'Post', - id: request.publicationId, - }); - this.client.cache.modify({ - id: identifier, - fields: { - stats(existing: PublicationStats) { - return { - ...existing, - totalAmountOfCollects: existing.totalAmountOfCollects + 1, - }; - }, - }, - }); - } - - async commit({ request }: TransactionData) { - await this.refetchPublicationFromNetwork(request.publicationId); - } - - async rollback({ request }: TransactionData) { - await this.refetchPublicationFromNetwork(request.publicationId); - } - - private async refetchPublicationFromNetwork(publicationId: PublicationId) { - const session = getSession(); - - await this.client.query({ - query: GetPublicationDocument, - variables: { - request: { - publicationId: publicationId, - }, - observerId: session?.type === SessionType.WithProfile ? session.profile.id : null, - sources: this.sources, - ...mediaTransformConfigToQueryVariables(this.mediaTransforms), - }, - fetchPolicy: 'network-only', - }); - } -} diff --git a/packages/react-v1/src/transactions/adapters/responders/CreateMirrorResponder.ts b/packages/react-v1/src/transactions/adapters/responders/CreateMirrorResponder.ts deleted file mode 100644 index bfe5b9db23..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/CreateMirrorResponder.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { - GetPublicationData, - GetPublicationDocument, - GetPublicationVariables, - getSession, - PublicationStats, - SafeApolloClient, - SessionType, - Sources, -} from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; -import { CreateMirrorRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - ITransactionResponder, - TransactionData, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { - mediaTransformConfigToQueryVariables, - MediaTransformsConfig, -} from '../../../mediaTransforms'; - -export class CreateMirrorResponder implements ITransactionResponder { - constructor( - private readonly client: SafeApolloClient, - private readonly sources: Sources, - private readonly mediaTransforms: MediaTransformsConfig, - ) {} - - async prepare({ request }: TransactionData) { - const identifier = this.client.cache.identify({ - __typename: 'Post', - id: request.publicationId, - }); - this.client.cache.modify({ - id: identifier, - fields: { - stats(existing: PublicationStats) { - return { - ...existing, - totalAmountOfMirrors: existing.totalAmountOfMirrors + 1, - }; - }, - }, - }); - } - - async commit({ request }: TransactionData) { - await this.refetchPublicationFromNetwork(request.publicationId); - } - - async rollback({ request }: TransactionData) { - await this.refetchPublicationFromNetwork(request.publicationId); - } - - private async refetchPublicationFromNetwork(publicationId: PublicationId) { - const session = getSession(); - - await this.client.query({ - query: GetPublicationDocument, - variables: { - request: { - publicationId, - }, - observerId: session?.type === SessionType.WithProfile ? session.profile.id : null, - sources: this.sources, - ...mediaTransformConfigToQueryVariables(this.mediaTransforms), - }, - fetchPolicy: 'network-only', - }); - } -} diff --git a/packages/react-v1/src/transactions/adapters/responders/CreatePostResponder.ts b/packages/react-v1/src/transactions/adapters/responders/CreatePostResponder.ts deleted file mode 100644 index b75c9940a5..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/CreatePostResponder.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { makeVar } from '@apollo/client'; -import { - PendingPost, - PublicationMainFocus, - Profile, - Post, - isPostPublication, - SafeApolloClient, - Sources, - GetPublicationData, - GetPublicationVariables, - GetPublicationDocument, -} from '@lens-protocol/api-bindings'; -import { PublicationId } from '@lens-protocol/domain/entities'; -import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - ITransactionResponder, - TransactionData, -} from '@lens-protocol/domain/use-cases/transactions'; -import { invariant } from '@lens-protocol/shared-kernel'; - -import { - MediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../../mediaTransforms'; -import { IProfileCacheManager } from '../IProfileCacheManager'; - -function pendingPost({ - id, - author, - request, -}: { - id: string; - author: Profile; - request: CreatePostRequest; -}): PendingPost { - return { - __typename: 'PendingPost', - id, - profile: author, - content: request.content ?? null, - mainContentFocus: PublicationMainFocus[request.contentFocus], - media: - request.media?.map((media) => ({ - __typename: 'Media', - altTag: media.altTag ?? null, - cover: media.cover ?? null, - mimeType: media.mimeType, - url: media.url, - })) ?? null, - locale: request.locale, - }; -} - -export const recentPosts = makeVar>([]); - -export class CreatePostResponder implements ITransactionResponder { - constructor( - private readonly profileCacheManager: IProfileCacheManager, - private readonly client: SafeApolloClient, - private readonly sources: Sources, - private readonly mediaTransforms: MediaTransformsConfig, - ) {} - - async prepare({ id, request }: TransactionData) { - const author = await this.profileCacheManager.fetchProfile(request.profileId); - - invariant(author, 'Cannot find author profile'); - - const post = pendingPost({ id, author, request }); - - recentPosts([post, ...recentPosts()]); - } - - async commit({ id, txHash, request }: TransactionData) { - const publicationResult = await this.client.query({ - query: GetPublicationDocument, - variables: { - request: txHash ? { txHash } : { publicationId: id as PublicationId }, - observerId: request.profileId, - sources: this.sources, - ...mediaTransformConfigToQueryVariables(this.mediaTransforms), - }, - fetchPolicy: 'network-only', - }); - - const publication = publicationResult.data.result; - invariant(publication, 'Publication by hash query should return data'); - invariant(isPostPublication(publication), 'Publication should be a post'); - - recentPosts( - recentPosts().map((post) => { - if (post.id === id) { - return publication; - } - return post; - }), - ); - } - - async rollback({ id }: TransactionData) { - recentPosts(recentPosts().filter((post) => post.id !== id)); - } -} diff --git a/packages/react-v1/src/transactions/adapters/responders/CreateProfileResponder.ts b/packages/react-v1/src/transactions/adapters/responders/CreateProfileResponder.ts deleted file mode 100644 index dda3eaa7f4..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/CreateProfileResponder.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { makeVar, useReactiveVar } from '@apollo/client'; -import { Profile } from '@lens-protocol/api-bindings'; -import { CreateProfileRequest } from '@lens-protocol/domain/use-cases/profile'; -import { - TransactionData, - ITransactionResponder, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { IProfileCacheManager } from '../IProfileCacheManager'; - -const recentProfilesVar = makeVar([]); - -export class CreateProfileResponder implements ITransactionResponder { - constructor(private readonly profileCacheManager: IProfileCacheManager) {} - - async commit({ request }: TransactionData) { - const profile = await this.profileCacheManager.fetchNewProfile(request.handle); - - recentProfilesVar([...recentProfilesVar(), profile]); - } -} - -export function useRecentProfiles() { - return useReactiveVar(recentProfilesVar); -} diff --git a/packages/react-v1/src/transactions/adapters/responders/FollowProfilesResponder.tsx b/packages/react-v1/src/transactions/adapters/responders/FollowProfilesResponder.tsx deleted file mode 100644 index fa8229ca1f..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/FollowProfilesResponder.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { ApolloCache, NormalizedCacheObject } from '@apollo/client'; -import { Profile, FragmentProfile } from '@lens-protocol/api-bindings'; -import { FollowRequest } from '@lens-protocol/domain/use-cases/profile'; -import { - ITransactionResponder, - TransactionData, -} from '@lens-protocol/domain/use-cases/transactions'; - -export class FollowProfilesResponder implements ITransactionResponder { - constructor(private apolloCache: ApolloCache) {} - - async prepare({ request }: TransactionData) { - const profileIdentifier = this.apolloCache.identify({ - __typename: 'Profile', - id: request.profileId, - }); - - const snapshot = this.apolloCache.readFragment({ - id: profileIdentifier, - fragmentName: 'Profile', - fragment: FragmentProfile, - }); - - if (snapshot) { - this.apolloCache.writeFragment({ - id: profileIdentifier, - fragmentName: 'Profile', - fragment: FragmentProfile, - data: { - ...snapshot, - stats: { - ...snapshot.stats, - totalFollowers: snapshot.stats.totalFollowers + 1, - }, - }, - }); - } - } - - async commit({ request }: TransactionData) { - const profileIdentifier = this.apolloCache.identify({ - __typename: 'Profile', - id: request.profileId, - }); - - const snapshot = this.apolloCache.readFragment({ - id: profileIdentifier, - fragmentName: 'Profile', - fragment: FragmentProfile, - }); - - if (snapshot) { - this.apolloCache.writeFragment({ - id: profileIdentifier, - fragmentName: 'Profile', - fragment: FragmentProfile, - data: { - ...snapshot, - isFollowedByMe: true, - stats: { - ...snapshot.stats, - totalFollowers: snapshot.stats.totalFollowers + 1, - }, - }, - }); - } - } - - async rollback({ request }: TransactionData) { - const profileIdentifier = this.apolloCache.identify({ - __typename: 'Profile', - id: request.profileId, - }); - - const snapshot = this.apolloCache.readFragment({ - id: profileIdentifier, - fragmentName: 'Profile', - fragment: FragmentProfile, - }); - - if (snapshot) { - this.apolloCache.writeFragment({ - id: profileIdentifier, - fragmentName: 'Profile', - fragment: FragmentProfile, - data: { - ...snapshot, - stats: { - ...snapshot.stats, - totalFollowers: snapshot.stats.totalFollowers - 1, - }, - }, - }); - } - } -} diff --git a/packages/react-v1/src/transactions/adapters/responders/NoopResponder.ts b/packages/react-v1/src/transactions/adapters/responders/NoopResponder.ts deleted file mode 100644 index 81c1887a20..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/NoopResponder.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { AnyTransactionRequestModel } from '@lens-protocol/domain/entities'; -import { - TransactionData, - ITransactionResponder, -} from '@lens-protocol/domain/use-cases/transactions'; - -export class NoopResponder - implements ITransactionResponder -{ - // eslint-disable-next-line @typescript-eslint/no-empty-function - async commit(_: TransactionData) {} -} diff --git a/packages/react-v1/src/transactions/adapters/responders/UnfollowProfileResponder.ts b/packages/react-v1/src/transactions/adapters/responders/UnfollowProfileResponder.ts deleted file mode 100644 index 2fcded8067..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/UnfollowProfileResponder.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { ApolloCache, NormalizedCacheObject } from '@apollo/client'; -import { Profile } from '@lens-protocol/api-bindings'; -import { UnfollowRequest } from '@lens-protocol/domain/use-cases/profile'; -import { - TransactionData, - ITransactionResponder, -} from '@lens-protocol/domain/use-cases/transactions'; - -export class UnfollowProfileResponder implements ITransactionResponder { - constructor(private apolloCache: ApolloCache) {} - - async commit({ request }: TransactionData) { - const profileIdentifier = this.apolloCache.identify({ - __typename: 'Profile', - id: request.profileId, - }); - this.apolloCache.modify({ - id: profileIdentifier, - fields: { - isFollowedByMe: () => false, - stats(oldStats: Profile['stats']) { - return { - ...oldStats, - totalFollowers: oldStats.totalFollowers - 1, - }; - }, - }, - }); - } -} diff --git a/packages/react-v1/src/transactions/adapters/responders/UpdateDispatcherConfigResponder.ts b/packages/react-v1/src/transactions/adapters/responders/UpdateDispatcherConfigResponder.ts deleted file mode 100644 index 75fe1d5aed..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/UpdateDispatcherConfigResponder.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { UpdateDispatcherConfigRequest } from '@lens-protocol/domain/use-cases/profile'; -import { - TransactionData, - ITransactionResponder, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { IProfileCacheManager } from '../IProfileCacheManager'; - -export class UpdateDispatcherConfigResponder - implements ITransactionResponder -{ - constructor(private readonly profileCacheManager: IProfileCacheManager) {} - - async commit({ request }: TransactionData) { - await this.profileCacheManager.refreshProfile(request.profileId); - } -} diff --git a/packages/react-v1/src/transactions/adapters/responders/UpdateFollowPolicyResponder.ts b/packages/react-v1/src/transactions/adapters/responders/UpdateFollowPolicyResponder.ts deleted file mode 100644 index d9be146068..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/UpdateFollowPolicyResponder.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { FollowPolicy } from '@lens-protocol/api-bindings'; -import { UpdateFollowPolicyRequest } from '@lens-protocol/domain/use-cases/profile'; -import { - ITransactionResponder, - TransactionData, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { IProfileCacheManager } from '../IProfileCacheManager'; - -export class UpdateFollowPolicyResponder - implements ITransactionResponder -{ - constructor(private readonly profileCacheManager: IProfileCacheManager) {} - - async prepare({ request }: TransactionData) { - this.profileCacheManager.updateProfile(request.profileId, (current) => ({ - ...current, - followPolicy: request.policy as FollowPolicy, // TODO sort discrepancy with contractAddress missing from request model - })); - } - - async commit({ request }: TransactionData) { - await this.profileCacheManager.refreshProfile(request.profileId); - } - - async rollback({ request }: TransactionData) { - await this.profileCacheManager.refreshProfile(request.profileId); - } -} diff --git a/packages/react-v1/src/transactions/adapters/responders/UpdateProfileImageResponder.ts b/packages/react-v1/src/transactions/adapters/responders/UpdateProfileImageResponder.ts deleted file mode 100644 index b72e528e40..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/UpdateProfileImageResponder.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { - UpdateOffChainProfileImageRequest, - UpdateProfileImageRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { - TransactionData, - ITransactionResponder, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { IProfileCacheManager } from '../IProfileCacheManager'; - -function isUpdateOffChainProfileImageRequest( - request: UpdateProfileImageRequest, -): request is UpdateOffChainProfileImageRequest { - return 'url' in request; -} - -export class UpdateProfileImageResponder - implements ITransactionResponder -{ - constructor(private readonly profileCacheManager: IProfileCacheManager) {} - - async prepare({ request }: TransactionData) { - if (isUpdateOffChainProfileImageRequest(request)) { - this.profileCacheManager.updateProfile(request.profileId, (current) => { - return { - ...current, - picture: { - __typename: 'MediaSet', - original: { - __typename: 'Media', - url: request.url, - // we don't know the following (yet), not important for now - altTag: null, - cover: null, - mimeType: null, - }, - optimized: { - __typename: 'Media', - url: request.url, - // we don't know the following (yet), not important for now - altTag: null, - cover: null, - mimeType: null, - }, - thumbnail: { - __typename: 'Media', - url: request.url, - // we don't know the following (yet), not important for now - altTag: null, - cover: null, - mimeType: null, - }, - }, - }; - }); - } - } - - async commit({ request }: TransactionData) { - await this.profileCacheManager.refreshProfile(request.profileId); - } - - async rollback({ request }: TransactionData) { - await this.profileCacheManager.refreshProfile(request.profileId); - } -} diff --git a/packages/react-v1/src/transactions/adapters/responders/UpdateProfileMetadataResponder.ts b/packages/react-v1/src/transactions/adapters/responders/UpdateProfileMetadataResponder.ts deleted file mode 100644 index 7e76978975..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/UpdateProfileMetadataResponder.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Attribute, Maybe, Profile } from '@lens-protocol/api-bindings'; -import { - ProfileAttributeValue, - UpdateProfileDetailsRequest, - PartialAttributesUpdate, -} from '@lens-protocol/domain/use-cases/profile'; -import { - ITransactionResponder, - TransactionData, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { IProfileCacheManager } from '../IProfileCacheManager'; - -function attribute(key: string, value: ProfileAttributeValue): Attribute { - if (value instanceof Date) { - return { - __typename: 'Attribute', - key, - value: value.toISOString(), - displayType: 'date', - }; - } - - return { - __typename: 'Attribute', - key, - value: value.toString(), - displayType: typeof value, - }; -} - -function mergeAttributes( - existing: Maybe, - update: PartialAttributesUpdate, -): Attribute[] { - const acc = new Map(); - - (existing ?? []).forEach((attr) => { - acc.set(attr.key, attr); - }); - - for (const [key, value] of Object.entries(update)) { - if (value === null) { - acc.delete(key); - } else { - acc.set(key, attribute(key, value)); - } - } - return Array.from(acc.values()); -} - -export class UpdateProfileMetadataResponder - implements ITransactionResponder -{ - private snapshots = new Map(); - - constructor(private readonly profileCacheManager: IProfileCacheManager) {} - - async prepare({ request }: TransactionData) { - this.profileCacheManager.updateProfile(request.profileId, (current) => { - this.snapshots.set(request, current); - - return { - ...current, - name: request.name, - bio: request.bio ?? current.bio, - coverPicture: request.coverPicture - ? { - __typename: 'MediaSet', - original: { - __typename: 'Media', - url: request.coverPicture, - // we don't know the following (yet), not important for now - altTag: null, - cover: null, - mimeType: null, - }, - optimized: { - __typename: 'Media', - url: request.coverPicture, - // we don't know the following (yet), not important for now - altTag: null, - cover: null, - mimeType: null, - }, - } - : current.coverPicture, - __attributes: request.attributes - ? mergeAttributes(current.__attributes, request.attributes) - : current.__attributes, - }; - }); - } - - async rollback({ request }: TransactionData) { - const snapshot = this.snapshots.get(request); - - if (snapshot) { - this.profileCacheManager.updateProfile(request.profileId, () => snapshot); - } - } - - async commit({ request }: TransactionData) { - await this.profileCacheManager.refreshProfile(request.profileId); - this.snapshots.delete(request); - } -} diff --git a/packages/react-v1/src/transactions/adapters/responders/__tests__/CollectPublicationResponder.spec.ts b/packages/react-v1/src/transactions/adapters/responders/__tests__/CollectPublicationResponder.spec.ts deleted file mode 100644 index 844eca62af..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/__tests__/CollectPublicationResponder.spec.ts +++ /dev/null @@ -1,243 +0,0 @@ -import { DocumentNode } from '@apollo/client'; -import { - FragmentComment, - FragmentMirror, - FragmentPost, - AnyPublication, - ContentPublication, -} from '@lens-protocol/api-bindings'; -import { - mockGetPublicationResponse, - mockLensApolloClient, - mockCommentFragment, - mockMirrorFragment, - mockPostFragment, - mockProfileFragment, - mockPublicationStatsFragment, - mockSources, - simulateAuthenticatedProfile, -} from '@lens-protocol/api-bindings/mocks'; -import { mockTransactionData, mockPaidCollectRequest } from '@lens-protocol/domain/mocks'; -import { nonNullable } from '@lens-protocol/shared-kernel'; - -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../../../mediaTransforms'; -import { CollectPublicationResponder } from '../CollectPublicationResponder'; - -type AnyPublicationTypename = AnyPublication['__typename']; - -const typeToFragmentMap: Record = { - Post: FragmentPost, - Comment: FragmentComment, - Mirror: FragmentMirror, -}; - -function setupTestScenario({ - publication, - expected, -}: { - publication: AnyPublication; - expected: AnyPublication | null; -}) { - const activeProfile = mockProfileFragment(); - simulateAuthenticatedProfile(activeProfile); - - const sources = mockSources(); - const mediaTransforms = defaultMediaTransformsConfig; - const apolloClient = mockLensApolloClient( - expected - ? [ - mockGetPublicationResponse({ - variables: { - request: { publicationId: publication.id }, - observerId: activeProfile.id, - sources, - ...mediaTransformConfigToQueryVariables(mediaTransforms), - }, - publication: expected, - }), - ] - : [], - ); - - apolloClient.cache.writeFragment({ - id: apolloClient.cache.identify(publication), - fragment: typeToFragmentMap[publication.__typename], - fragmentName: publication.__typename, - data: publication, - }); - - const responder = new CollectPublicationResponder(apolloClient, sources, mediaTransforms); - - return { - responder, - - get updatedPublicationFragment() { - return nonNullable( - apolloClient.cache.readFragment({ - id: apolloClient.cache.identify(publication), - fragment: typeToFragmentMap[publication.__typename], - fragmentName: publication.__typename, - }), - "Can't find post in cache", - ); - }, - }; -} - -const knownInitialPublicationStats = mockPublicationStatsFragment({ totalAmountOfCollects: 1 }); - -describe(`Given the ${CollectPublicationResponder.name}`, () => { - describe.each([ - mockPostFragment({ - hasCollectedByMe: false, - stats: knownInitialPublicationStats, - }), - - mockCommentFragment({ - hasCollectedByMe: false, - stats: knownInitialPublicationStats, - }), - ])('and a $__typename', (publication) => { - describe(`when "${CollectPublicationResponder.prototype.prepare.name}" method is invoked`, () => { - it('should optimistically update the total amount of collects in the publication stats ', async () => { - const request = mockPaidCollectRequest({ - publicationId: publication.id, - }); - const transactionData = mockTransactionData({ request }); - - const scenario = setupTestScenario({ - publication: publication, - expected: null, - }); - - await scenario.responder.prepare(transactionData); - - expect(scenario.updatedPublicationFragment).toMatchObject({ - stats: { - totalAmountOfCollects: knownInitialPublicationStats.totalAmountOfCollects + 1, - }, - }); - }); - }); - }); - - describe.each([ - mockPostFragment({ - hasCollectedByMe: false, - stats: knownInitialPublicationStats, - }), - - mockCommentFragment({ - hasCollectedByMe: false, - stats: knownInitialPublicationStats, - }), - ])('and a $__typename', (publication) => { - describe(`when "${CollectPublicationResponder.prototype.commit.name}" method is invoked`, () => { - it(`should update the publication from API`, async () => { - const request = mockPaidCollectRequest({ - publicationId: publication.id, - }); - const transactionData = mockTransactionData({ request }); - const scenario = setupTestScenario({ - publication, - expected: { - ...publication, - hasCollectedByMe: true, - stats: { - ...publication.stats, - totalAmountOfCollects: 2, - }, - }, - }); - - await scenario.responder.commit(transactionData); - - expect(scenario.updatedPublicationFragment).toMatchObject({ - hasCollectedByMe: true, - stats: { - totalAmountOfCollects: 2, - }, - }); - }); - - it('should update the publication from API if collected via a mirror', async () => { - const mirror = mockMirrorFragment({ - mirrorOf: publication, - }); - const request = mockPaidCollectRequest({ - publicationId: mirror.id, - }); - const transactionData = mockTransactionData({ request }); - const scenario = setupTestScenario({ - publication: mirror, - expected: { - ...mirror, - mirrorOf: { - ...publication, - hasCollectedByMe: true, - stats: { - ...publication.stats, - totalAmountOfCollects: 2, - }, - }, - }, - }); - - await scenario.responder.commit(transactionData); - - expect(scenario.updatedPublicationFragment).toMatchObject({ - mirrorOf: { - hasCollectedByMe: true, - stats: { - totalAmountOfCollects: 2, - }, - }, - }); - }); - }); - }); - - describe.each([ - mockPostFragment({ - hasCollectedByMe: false, - stats: knownInitialPublicationStats, - }), - - mockCommentFragment({ - hasCollectedByMe: false, - stats: knownInitialPublicationStats, - }), - ])('and a $__typename', (publication) => { - describe(`when "${CollectPublicationResponder.prototype.rollback.name}" method is invoked`, () => { - it('should update the publication from API', async () => { - const request = mockPaidCollectRequest({ - publicationId: publication.id, - }); - const transactionData = mockTransactionData({ request }); - const scenario = setupTestScenario({ - publication: publication, - expected: { - ...publication, - hasCollectedByMe: false, - stats: { - ...publication.stats, - totalAmountOfCollects: 0, - }, - }, - }); - - await scenario.responder.rollback(transactionData); - - expect(scenario.updatedPublicationFragment).toMatchObject({ - hasCollectedByMe: false, - stats: { - totalAmountOfCollects: 0, - }, - }); - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/responders/__tests__/CreateMirrorResponder.spec.ts b/packages/react-v1/src/transactions/adapters/responders/__tests__/CreateMirrorResponder.spec.ts deleted file mode 100644 index 2e29999806..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/__tests__/CreateMirrorResponder.spec.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { Post, FragmentPost } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockPostFragment, - mockProfileFragment, - mockSources, - mockGetPublicationResponse, - simulateAuthenticatedProfile, -} from '@lens-protocol/api-bindings/mocks'; -import { - mockTransactionData, - mockCreateMirrorRequest, - mockPublicationId, -} from '@lens-protocol/domain/mocks'; -import { CreateMirrorRequest } from '@lens-protocol/domain/use-cases/publications'; -import { TransactionData } from '@lens-protocol/domain/use-cases/transactions'; -import { nonNullable } from '@lens-protocol/shared-kernel'; - -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../../../mediaTransforms'; -import { CreateMirrorResponder } from '../CreateMirrorResponder'; - -function setupTestScenario({ - post, - expected, - transactionData, -}: { - post: Post; - expected: Post | null; - transactionData: TransactionData; -}) { - const activeProfile = mockProfileFragment(); - simulateAuthenticatedProfile(activeProfile); - - const sources = mockSources(); - const mediaTransforms = defaultMediaTransformsConfig; - const apolloClient = mockLensApolloClient( - expected - ? [ - mockGetPublicationResponse({ - variables: { - request: { - publicationId: transactionData.request.publicationId, - }, - observerId: activeProfile.id, - sources, - ...mediaTransformConfigToQueryVariables(mediaTransforms), - }, - publication: expected, - }), - ] - : [], - ); - - apolloClient.cache.writeFragment({ - id: apolloClient.cache.identify({ - __typename: 'Post', - id: post.id, - }), - fragment: FragmentPost, - fragmentName: 'Post', - data: post, - }); - - const responder = new CreateMirrorResponder(apolloClient, sources, mediaTransforms); - - return { - responder, - - get updatedPost() { - return nonNullable( - apolloClient.cache.readFragment({ - id: apolloClient.cache.identify({ - __typename: 'Post', - id: post.id, - }), - fragment: FragmentPost, - fragmentName: 'Post', - }), - "Can't find post in cache", - ); - }, - }; -} - -describe(`Given an instance of the ${CreateMirrorResponder.name}`, () => { - const author = mockProfileFragment(); - - describe(`when "${CreateMirrorResponder.prototype.prepare.name}" method is invoked`, () => { - it(`should optimistically update the total amount of mirrors in publication stats`, async () => { - const post = mockPostFragment({ - profile: author, - }); - - const transactionData = mockTransactionData({ - request: mockCreateMirrorRequest({ - profileId: author.id, - publicationId: post.id, - }), - }); - - const scenario = setupTestScenario({ - post, - transactionData, - expected: null, - }); - - await scenario.responder.prepare(transactionData); - - expect(scenario.updatedPost.stats.totalAmountOfMirrors).toBe( - post.stats.totalAmountOfMirrors + 1, - ); - }); - }); - - describe(`when "${CreateMirrorResponder.prototype.commit.name}" method is invoked`, () => { - it(`should update the original publication 'mirrors' list`, async () => { - const post = mockPostFragment({ - profile: author, - }); - - const transactionData = mockTransactionData({ - request: mockCreateMirrorRequest({ - profileId: author.id, - publicationId: post.id, - }), - }); - - const scenario = setupTestScenario({ - post: { - ...post, - mirrors: post.mirrors.concat(mockPublicationId()), - }, - expected: { - ...post, - mirrors: post.mirrors.concat(mockPublicationId()), - }, - transactionData, - }); - - await scenario.responder.commit(transactionData); - - expect(scenario.updatedPost.mirrors).toHaveLength(post.mirrors.length + 1); - }); - }); - - describe(`when "${CreateMirrorResponder.prototype.rollback.name}" method is invoked`, () => { - it(`should update the original publication back inline with the network response`, async () => { - const post = mockPostFragment({ - profile: author, - }); - - const transactionData = mockTransactionData({ - request: mockCreateMirrorRequest({ - profileId: author.id, - publicationId: post.id, - }), - }); - - const revertedTotalAmountOfMirrorsValue = post.stats.totalAmountOfMirrors - 1; - const revertedMirrorsValue = post.mirrors.slice(0, -1); - const scenario = setupTestScenario({ - post, - expected: { - ...post, - mirrors: revertedMirrorsValue, - stats: { - ...post.stats, - totalAmountOfMirrors: revertedTotalAmountOfMirrorsValue, - }, - }, - transactionData, - }); - - await scenario.responder.rollback(transactionData); - - expect(scenario.updatedPost.mirrors).toEqual(revertedMirrorsValue); - expect(scenario.updatedPost.stats.totalAmountOfMirrors).toEqual( - revertedTotalAmountOfMirrorsValue, - ); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/responders/__tests__/CreatePostResponder.spec.ts b/packages/react-v1/src/transactions/adapters/responders/__tests__/CreatePostResponder.spec.ts deleted file mode 100644 index 68dc19fe8b..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/__tests__/CreatePostResponder.spec.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { Post, Profile } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockPostFragment, - mockProfileFragment, - mockSources, - mockGetPublicationResponse, -} from '@lens-protocol/api-bindings/mocks'; -import { PublicationId } from '@lens-protocol/domain/entities'; -import { - mockCreatePostRequest, - mockTransactionData, - mockTransactionHash, -} from '@lens-protocol/domain/mocks'; -import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; -import { TransactionData } from '@lens-protocol/domain/use-cases/transactions'; - -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../../../mediaTransforms'; -import { mockIProfileCacheManager } from '../../__helpers__/mocks'; -import { CreatePostResponder, recentPosts } from '../CreatePostResponder'; - -function setupTestScenario({ - author, - post = mockPostFragment(), - transactionData = mockTransactionData(), -}: { - author: Profile; - post?: Post; - transactionData?: TransactionData; -}) { - const sources = mockSources(); - const mediaTransforms = defaultMediaTransformsConfig; - const apolloClient = mockLensApolloClient([ - mockGetPublicationResponse({ - variables: { - request: transactionData.txHash - ? { - txHash: transactionData.txHash, - } - : { - publicationId: transactionData.id as PublicationId, - }, - observerId: author.id, - sources, - ...mediaTransformConfigToQueryVariables(mediaTransforms), - }, - publication: post, - }), - ]); - - const profileCacheManager = mockIProfileCacheManager(author); - return new CreatePostResponder(profileCacheManager, apolloClient, sources, mediaTransforms); -} - -describe(`Given an instance of the ${CreatePostResponder.name}`, () => { - const author = mockProfileFragment(); - - afterEach(() => { - recentPosts([]); - }); - - describe(`when "${CreatePostResponder.prototype.prepare.name}" method is invoked`, () => { - it(`should optimistically add a PendingPost at the top of the provided recent posts ReactiveVar`, async () => { - const responder = setupTestScenario({ - author, - }); - - const transactionData = mockTransactionData({ - request: mockCreatePostRequest({ - profileId: author.id, - }), - }); - await responder.prepare(transactionData); - - expect(recentPosts()[0]).toMatchObject({ - __typename: 'PendingPost', - id: transactionData.id, - }); - }); - }); - - describe(`when "${CreatePostResponder.prototype.commit.name}" method is invoked`, () => { - const post = mockPostFragment(); - - it(`should replace the PendingPost added during the "${CreatePostResponder.prototype.prepare.name}" method call with the actual Post retrieved from the BE`, async () => { - const transactionData = mockTransactionData({ - txHash: mockTransactionHash(), - request: mockCreatePostRequest({ - profileId: author.id, - }), - }); - const responder = setupTestScenario({ - author, - post, - transactionData, - }); - - await responder.prepare(transactionData); - await responder.commit(transactionData); - - expect(recentPosts()[0]).toMatchObject({ - __typename: 'Post', - id: post.id, - }); - }); - - it('should fallback to retrieve the Post by PublicationId if the txHash is not available', async () => { - const transactionData = mockTransactionData({ - request: mockCreatePostRequest({ - profileId: author.id, - }), - }); - const responder = setupTestScenario({ - author, - post, - transactionData, - }); - - await responder.prepare(transactionData); - await responder.commit(transactionData); - - expect(recentPosts()[0]).toMatchObject({ - __typename: 'Post', - id: post.id, - }); - }); - }); - - describe(`when "${CreatePostResponder.prototype.rollback.name}" method is invoked`, () => { - const post = mockPostFragment(); - const transactionData = mockTransactionData({ - request: mockCreatePostRequest({ - profileId: author.id, - }), - }); - - it(`should remove the PendingPost added during the "${CreatePostResponder.prototype.prepare.name}" method call`, async () => { - const responder = setupTestScenario({ - author, - post, - transactionData, - }); - - await responder.prepare(transactionData); - await responder.rollback(transactionData); - - expect(recentPosts().length).toBe(0); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/responders/__tests__/FollowProfilesResponder.spec.ts b/packages/react-v1/src/transactions/adapters/responders/__tests__/FollowProfilesResponder.spec.ts deleted file mode 100644 index e21aed4f3d..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/__tests__/FollowProfilesResponder.spec.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { Profile, FragmentProfile } from '@lens-protocol/api-bindings'; -import { - mockLensCache, - mockProfileFragment, - mockProfileStatsFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { mockTransactionData, mockUnconstrainedFollowRequest } from '@lens-protocol/domain/mocks'; - -import { FollowProfilesResponder } from '../FollowProfilesResponder'; - -function setupTestScenario({ existingProfile }: { existingProfile: Profile }) { - const apolloCache = mockLensCache(); - - apolloCache.writeFragment({ - id: apolloCache.identify({ - __typename: 'Profile', - id: existingProfile.id, - }), - fragment: FragmentProfile, - fragmentName: 'Profile', - data: existingProfile, - }); - - const responder = new FollowProfilesResponder(apolloCache); - - return { - responder, - - get updatedProfile() { - return apolloCache.readFragment({ - id: apolloCache.identify({ - __typename: 'Profile', - id: existingProfile.id, - }), - fragment: FragmentProfile, - fragmentName: 'Profile', - }); - }, - }; -} - -describe(`Given the ${FollowProfilesResponder.name}`, () => { - describe(`when "${FollowProfilesResponder.prototype.prepare.name}" method is invoked`, () => { - it(`should update apollo cache with follow information`, async () => { - const request = mockUnconstrainedFollowRequest(); - const transactionData = mockTransactionData({ request }); - const existingProfile = mockProfileFragment({ - id: transactionData.request.profileId, - stats: mockProfileStatsFragment({ - totalFollowers: 2, - }), - }); - const scenario = setupTestScenario({ existingProfile }); - - await scenario.responder.prepare(transactionData); - - expect(scenario.updatedProfile).toMatchObject({ - id: existingProfile.id, - - stats: { - totalFollowers: 3, - }, - }); - }); - }); - - describe(`when "${FollowProfilesResponder.prototype.commit.name}" method is invoked`, () => { - it(`should update apollo cache with follow information`, async () => { - const request = mockUnconstrainedFollowRequest(); - const transactionData = mockTransactionData({ request }); - const existingProfile = mockProfileFragment({ - id: transactionData.request.profileId, - isFollowedByMe: false, - stats: mockProfileStatsFragment({ - totalFollowers: 2, - }), - }); - const scenario = setupTestScenario({ existingProfile }); - - await scenario.responder.commit(transactionData); - - expect(scenario.updatedProfile).toMatchObject({ - id: existingProfile.id, - isFollowedByMe: true, - stats: { - totalFollowers: 3, - }, - }); - }); - }); - - describe(`when "${FollowProfilesResponder.prototype.rollback.name}" method is invoked`, () => { - it(`should update apollo cache with follow information`, async () => { - const request = mockUnconstrainedFollowRequest(); - const transactionData = mockTransactionData({ request }); - const existingProfile = mockProfileFragment({ - id: transactionData.request.profileId, - stats: mockProfileStatsFragment({ - totalFollowers: 2, - }), - }); - const scenario = setupTestScenario({ existingProfile }); - - await scenario.responder.rollback(transactionData); - - expect(scenario.updatedProfile).toMatchObject({ - id: existingProfile.id, - stats: { - totalFollowers: 1, - }, - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/responders/__tests__/UnfollowProfileResponder.spec.ts b/packages/react-v1/src/transactions/adapters/responders/__tests__/UnfollowProfileResponder.spec.ts deleted file mode 100644 index b7a2917e41..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/__tests__/UnfollowProfileResponder.spec.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { InMemoryCache } from '@apollo/client'; -import { FragmentProfile } from '@lens-protocol/api-bindings'; -import { mockProfileFragment, mockProfileStatsFragment } from '@lens-protocol/api-bindings/mocks'; -import { - mockTransactionData, - mockUnfollowRequest, - mockWalletData, -} from '@lens-protocol/domain/mocks'; -import { WalletData } from '@lens-protocol/domain/use-cases/lifecycle'; -import { UnfollowRequest } from '@lens-protocol/domain/use-cases/profile'; -import { TransactionData } from '@lens-protocol/domain/use-cases/transactions'; - -import { UnfollowProfileResponder } from '../UnfollowProfileResponder'; - -function setupTestScenario({ - transactionData, -}: { - transactionData: TransactionData; - walletData: WalletData; -}) { - const apolloCache = new InMemoryCache({ - addTypename: true, - }); - - const existingProfile = mockProfileFragment({ - id: transactionData.request.profileId, - stats: mockProfileStatsFragment({ - totalFollowers: 1, - }), - }); - - apolloCache.writeFragment({ - id: apolloCache.identify({ - __typename: 'Profile', - id: existingProfile.id, - }), - fragment: FragmentProfile, - fragmentName: 'Profile', - data: existingProfile, - }); - - const responder = new UnfollowProfileResponder(apolloCache); - - return { - existingProfile, - - responder, - - get profileCache() { - return apolloCache.readFragment({ - id: apolloCache.identify({ - __typename: 'Profile', - id: transactionData.request.profileId, - }), - fragment: FragmentProfile, - fragmentName: 'Profile', - }); - }, - }; -} - -describe(`Given the ${UnfollowProfileResponder.name}`, () => { - describe(`when "${UnfollowProfileResponder.prototype.commit.name}" method is invoked`, () => { - it(`should update apollo cache with new unfollow information`, async () => { - const walletData = mockWalletData(); - const request = mockUnfollowRequest(); - const transactionData = mockTransactionData({ request }); - const scenario = setupTestScenario({ transactionData, walletData }); - - await scenario.responder.commit(transactionData); - - expect(scenario.profileCache).toEqual( - expect.objectContaining({ - id: scenario.existingProfile.id, - stats: { - ...scenario.existingProfile.stats, - totalFollowers: scenario.existingProfile.stats.totalFollowers - 1, - }, - }), - ); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateDispatcherConfigResponder.spec.ts b/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateDispatcherConfigResponder.spec.ts deleted file mode 100644 index 59c18873a3..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateDispatcherConfigResponder.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { mockProfileFragment } from '@lens-protocol/api-bindings/mocks'; -import { - mockTransactionData, - mockUpdateDispatcherConfigRequest, -} from '@lens-protocol/domain/mocks'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; - -import { mockIProfileCacheManager } from '../../__helpers__/mocks'; -import { UpdateDispatcherConfigResponder } from '../UpdateDispatcherConfigResponder'; - -function setupTestScenario({ profile }: { profile: Profile }) { - const profileCacheManager = mockIProfileCacheManager(profile); - const responder = new UpdateDispatcherConfigResponder(profileCacheManager); - - return { - responder, - - profileCacheManager, - }; -} - -describe(`Given the ${UpdateDispatcherConfigResponder.name}`, () => { - describe(`when "${UpdateDispatcherConfigResponder.prototype.commit.name}" method is invoked`, () => { - it(`should update apollo cache with the new dispatcher configuration`, async () => { - const profile = mockProfileFragment({ dispatcher: null }); - const updated = mockProfileFragment({ - ...profile, - dispatcher: { address: mockEthereumAddress(), canUseRelay: true }, - }); - const request = mockUpdateDispatcherConfigRequest({ - enabled: true, - profileId: profile.id, - }); - const transactionData = mockTransactionData({ request }); - - const { responder, profileCacheManager } = setupTestScenario({ - profile: updated, - }); - - await responder.commit(transactionData); - - expect(profileCacheManager.refreshProfile).toBeCalledWith(profile.id); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateFollowPolicyResponder.spec.ts b/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateFollowPolicyResponder.spec.ts deleted file mode 100644 index 3a072ffd28..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateFollowPolicyResponder.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { mockProfileFragment } from '@lens-protocol/api-bindings/mocks'; -import { - mockTransactionData, - mockChargeFollowConfig, - mockUpdateFollowPolicyRequest, -} from '@lens-protocol/domain/mocks'; -import { FollowPolicyType } from '@lens-protocol/domain/use-cases/profile'; - -import { mockIProfileCacheManager } from '../../__helpers__/mocks'; -import { UpdateFollowPolicyResponder } from '../UpdateFollowPolicyResponder'; - -function setupUpdateFollowPolicyResponder({ profile }: { profile: Profile }) { - const profileCacheManager = mockIProfileCacheManager(profile); - const responder = new UpdateFollowPolicyResponder(profileCacheManager); - - return { - profileCacheManager, - - responder, - }; -} - -describe(`Given the ${UpdateFollowPolicyResponder.name}`, () => { - const profile = mockProfileFragment({ - followPolicy: { - type: FollowPolicyType.ANYONE, - }, - }); - const txData = mockTransactionData({ - request: mockUpdateFollowPolicyRequest({ - profileId: profile.id, - policy: mockChargeFollowConfig(), - }), - }); - - describe(`when "${UpdateFollowPolicyResponder.prototype.prepare.name}" method is invoked`, () => { - it(`should update the profile's follow policy`, async () => { - const { responder, profileCacheManager } = setupUpdateFollowPolicyResponder({ profile }); - - await responder.prepare(txData); - - expect(profileCacheManager.latestProfile).toMatchObject({ - followPolicy: txData.request.policy, - }); - }); - }); - - describe(`when "${UpdateFollowPolicyResponder.prototype.commit.name}" method is invoked`, () => { - it(`should update the correct Profile in the Apollo Cache`, async () => { - const { responder, profileCacheManager } = setupUpdateFollowPolicyResponder({ profile }); - - const txData = mockTransactionData({ - request: mockUpdateFollowPolicyRequest({ profileId: profile.id }), - }); - await responder.commit(txData); - - expect(profileCacheManager.refreshProfile).toHaveBeenCalledWith(profile.id); - }); - }); - - describe(`when "${UpdateFollowPolicyResponder.prototype.rollback.name}" method is invoked`, () => { - it(`should rollback the correct Profile in the Apollo Cache`, async () => { - const { responder, profileCacheManager } = setupUpdateFollowPolicyResponder({ profile }); - - await responder.rollback(txData); - - expect(profileCacheManager.refreshProfile).toHaveBeenCalledWith(profile.id); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateProfileImageResponder.spec.ts b/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateProfileImageResponder.spec.ts deleted file mode 100644 index 3c536b61ae..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateProfileImageResponder.spec.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { Profile } from '@lens-protocol/api-bindings'; -import { mockProfileFragment } from '@lens-protocol/api-bindings/mocks'; -import { - mockTransactionData, - mockUpdateOffChainProfileImageRequest, -} from '@lens-protocol/domain/mocks'; - -import { mockIProfileCacheManager } from '../../__helpers__/mocks'; -import { UpdateProfileImageResponder } from '../UpdateProfileImageResponder'; - -function setupTestScenario({ profile }: { profile: Profile }) { - const profileCacheManager = mockIProfileCacheManager(profile); - const responder = new UpdateProfileImageResponder(profileCacheManager); - - return { profileCacheManager, responder }; -} - -describe(`Given an instance of the ${UpdateProfileImageResponder.name}`, () => { - const profile = mockProfileFragment(); - const newImageUrl = faker.image.imageUrl(600, 600, 'cat', true); - - const transactionData = mockTransactionData({ - request: mockUpdateOffChainProfileImageRequest({ - profileId: profile.id, - url: newImageUrl, - }), - }); - - describe(`when "${UpdateProfileImageResponder.prototype.prepare.name}" method is invoked`, () => { - it(`should update profile picture to the latest one`, async () => { - const { responder, profileCacheManager } = setupTestScenario({ profile }); - - await responder.prepare(transactionData); - - expect(profileCacheManager.latestProfile).toMatchObject({ - ...profile, - picture: { - original: { - url: newImageUrl, - }, - }, - }); - }); - }); - - describe(`when "${UpdateProfileImageResponder.prototype.commit.name}" method is invoked`, () => { - it(`should query server again for update profile details`, async () => { - const { responder, profileCacheManager } = setupTestScenario({ profile }); - - await responder.prepare(transactionData); - await responder.commit(transactionData); - - expect(profileCacheManager.refreshProfile).toHaveBeenCalledWith(profile.id); - }); - }); - - describe(`when "${UpdateProfileImageResponder.prototype.rollback.name}" method is invoked`, () => { - it(`should restore the original profile picture from the server`, async () => { - const { responder, profileCacheManager } = setupTestScenario({ profile }); - - await responder.prepare(transactionData); - await responder.rollback(transactionData); - - expect(profileCacheManager.refreshProfile).toHaveBeenCalledWith(profile.id); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateProfileMetadataResponder.spec.ts b/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateProfileMetadataResponder.spec.ts deleted file mode 100644 index 863b63f735..0000000000 --- a/packages/react-v1/src/transactions/adapters/responders/__tests__/UpdateProfileMetadataResponder.spec.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { mockProfileFragment } from '@lens-protocol/api-bindings/mocks'; -import { mockUpdateProfileDetailsRequest, mockTransactionData } from '@lens-protocol/domain/mocks'; - -import { mockIProfileCacheManager } from '../../__helpers__/mocks'; -import { UpdateProfileMetadataResponder } from '../UpdateProfileMetadataResponder'; - -function setupUpdateProfileMetadataResponder({ profile }: { profile: Profile }) { - const profileCacheManager = mockIProfileCacheManager(profile); - const responder = new UpdateProfileMetadataResponder(profileCacheManager); - - return { profileCacheManager, responder }; -} - -describe(`Given the ${UpdateProfileMetadataResponder.name}`, () => { - const profile = mockProfileFragment(); - const request = mockUpdateProfileDetailsRequest({ - profileId: profile.id, - attributes: { - foo: 42, - dob: new Date(0), - label: 'bar', - }, - }); - const transactionData = mockTransactionData({ request }); - - describe(`when "${UpdateProfileMetadataResponder.prototype.prepare.name}" method is invoked with PendingTransactionData`, () => { - it(`should update the correct Profile in the Apollo Cache`, async () => { - const { responder, profileCacheManager } = setupUpdateProfileMetadataResponder({ profile }); - - await responder.prepare(transactionData); - - expect(profileCacheManager.latestProfile).toMatchObject({ - name: request.name, - bio: request.bio, - __attributes: [ - { - __typename: 'Attribute', - key: 'foo', - value: '42', - displayType: 'number', - }, - { - __typename: 'Attribute', - key: 'dob', - value: new Date(0).toISOString(), - displayType: 'date', - }, - { - __typename: 'Attribute', - key: 'label', - value: 'bar', - displayType: 'string', - }, - ], - }); - }); - }); - - describe(`when "${UpdateProfileMetadataResponder.prototype.rollback.name}" method is invoked with TransactionData`, () => { - it(`should revert the previous changes to the correct Profile in the Apollo Cache`, async () => { - const { responder, profileCacheManager } = setupUpdateProfileMetadataResponder({ profile }); - - await responder.prepare(transactionData); - await responder.rollback(transactionData); - - expect(profileCacheManager.latestProfile).toMatchObject(profile); - }); - }); - - describe(`when "${UpdateProfileMetadataResponder.prototype.commit.name}" method is invoked with BroadcastedTransactionData`, () => { - const transactionData = mockTransactionData({ request }); - - it(`should confirm the cache changes on the correct Profile with fresh data from the server`, async () => { - const { responder, profileCacheManager } = setupUpdateProfileMetadataResponder({ profile }); - - await responder.prepare(transactionData); - await responder.commit(transactionData); - - expect(profileCacheManager.refreshProfile).toHaveBeenCalledWith(profile.id); - }); - - it('should clear any previous profile snapshot for the given request', async () => { - const { responder, profileCacheManager } = setupUpdateProfileMetadataResponder({ profile }); - - await responder.prepare(transactionData); - await responder.commit(transactionData); - - // although it's not a real use case to call "rollback" after "commit", to prove - // the responder is clearing its internal state correctly, we test it here. - await responder.rollback(transactionData); - - expect(profileCacheManager.updateProfile).toBeCalledTimes(1); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/schemas/__tests__/Erc20Amount.spec.ts b/packages/react-v1/src/transactions/adapters/schemas/__tests__/Erc20Amount.spec.ts deleted file mode 100644 index 517ad2b766..0000000000 --- a/packages/react-v1/src/transactions/adapters/schemas/__tests__/Erc20Amount.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { mockDaiAmount } from '@lens-protocol/shared-kernel/mocks'; - -import { Erc20AmountInstanceSchema, SerializedErc20AmountSchema } from '../common'; - -describe(`Given the Erc20Amount schemas`, () => { - const amount = mockDaiAmount(1); - - describe(`when parsing a value with SerializedErc20AmountSchema`, () => { - it('should be able return the expected Erc20Amount instance', () => { - const serialized = JSON.parse(JSON.stringify(amount)) as object; - - const parsed = SerializedErc20AmountSchema.parse(serialized); - - expect(parsed.eq(amount)).toBe(true); - }); - }); - - describe(`when parsing a value with Erc20AmountInstanceSchema`, () => { - it('should verify instances of Erc20Amount', () => { - const parsed = Erc20AmountInstanceSchema.parse(amount); - - expect(parsed.eq(amount)).toBe(true); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/schemas/__tests__/formatters.spec.ts b/packages/react-v1/src/transactions/adapters/schemas/__tests__/formatters.spec.ts deleted file mode 100644 index f881bbff1f..0000000000 --- a/packages/react-v1/src/transactions/adapters/schemas/__tests__/formatters.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { SafeParseError, SafeParseReturnType, z } from 'zod'; - -import { formatZodError } from '../formatters'; - -function assertZodError( - result: SafeParseReturnType, -): asserts result is SafeParseError { - if (result.success) { - throw new Error('Expected an error'); - } -} - -describe(`Given the schema formatters`, () => { - describe(`when using the "${formatZodError.name}" function`, () => { - const Schema = z.object({ - number: z.number().optional(), - required: z.string(), - empty: z.array(z.string()).nonempty(), - array: z.array(z.string()), - union: z.union([ - z.string(), - z.number(), - z.object({ - required: z.string(), - }), - ]), - tuple: z.tuple([z.string(), z.number()]), - }); - - it('should generate the expected message', () => { - const result = Schema.safeParse({ - number: 'not a number', - empty: [], - array: ['1', 2, '3'], - union: true, - tuple: [42, 'not a string'], - }); - assertZodError(result); - - expect(formatZodError(result.error)).toMatchInlineSnapshot(` - "fix the following issues - · "number": Expected number, received string - · "required": Required - · "empty": Array must contain at least 1 element(s) - · "array[1]": Expected string, received number - · "union" expected to match one of the following groups: - · "union": Expected string, received boolean - OR: - · "union": Expected number, received boolean - OR: - · "union": Expected object, received boolean - · "tuple[0]": Expected string, received number - · "tuple[1]": Expected number, received string" - `); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/schemas/__tests__/validators.spec.ts b/packages/react-v1/src/transactions/adapters/schemas/__tests__/validators.spec.ts deleted file mode 100644 index 7023301a2c..0000000000 --- a/packages/react-v1/src/transactions/adapters/schemas/__tests__/validators.spec.ts +++ /dev/null @@ -1,653 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { - AddressOwnershipCriterion, - CollectPublicationCriterion, - DecryptionCriteriaType, - Erc20OwnershipCriterion, - FollowProfileCriterion, - NftContractType, - NftOwnershipCriterion, - ProfileOwnershipCriterion, - TransactionKind, -} from '@lens-protocol/domain/entities'; -import { - mockAddressOwnershipCriterion, - mockCollectPublicationCriterion, - mockCollectThisPublicationCriterion, - mockCreatePostRequest, - mockFollowProfileCriterion, - mockNftOwnershipCriterion, - mockProfileId, - mockProfileOwnershipCriterion, - mockPublicationId, -} from '@lens-protocol/domain/mocks'; -import { FollowPolicyType } from '@lens-protocol/domain/use-cases/profile'; -import { - CollectPolicyType, - ContentFocus, - ReferencePolicyType, -} from '@lens-protocol/domain/use-cases/publications'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; - -import { - validateCreateCommentRequest, - validateCreatePostRequest, - validateTokenAllowanceRequest, - validateUpdateFollowPolicyRequest, - validateUpdateProfileDetailsRequest, -} from '../validators'; - -describe(`Given the validator helpers`, () => { - describe(`when testing the "validateCreatePostRequest" on a request`, () => { - describe('with invalid "NftOwnershipCriterion" criteria for "decryptionCriteria"', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.AND, - and: [ - { - type: DecryptionCriteriaType.NFT_OWNERSHIP, - } as NftOwnershipCriterion, - { - type: DecryptionCriteriaType.NFT_OWNERSHIP, - contractAddress: mockEthereumAddress(), - chainId: 1, - contractType: NftContractType.Erc721, - tokenIds: [], - }, - { - type: DecryptionCriteriaType.NFT_OWNERSHIP, - contractAddress: mockEthereumAddress(), - chainId: 1, - contractType: NftContractType.Erc721, - tokenIds: Array.from({ length: 31 }, faker.datatype.hexadecimal), - }, - ], - }, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.and[0].contractAddress": Required - · "decryptionCriteria.and[0].chainId": Required - · "decryptionCriteria.and[0].contractType": Required - · "decryptionCriteria.and[1].tokenIds": Array must contain at least 1 element(s) - · "decryptionCriteria.and[2].tokenIds": Array must contain at most 30 element(s)" - `); - }); - }); - - describe('with invalid "Erc20OwnershipCriterion" criteria for "decryptionCriteria"', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.ERC20_OWNERSHIP, - } as Erc20OwnershipCriterion, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.amount": value not instance of Amount - · "decryptionCriteria.condition": Required" - `); - }); - }); - - describe('with invalid "AddressOwnershipCriterion" criteria for "decryptionCriteria"', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.ADDRESS_OWNERSHIP, - } as AddressOwnershipCriterion, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.address": Required" - `); - }); - }); - - describe('with invalid "ProfileOwnershipCriterion" criteria for "decryptionCriteria"', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.PROFILE_OWNERSHIP, - } as ProfileOwnershipCriterion, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.profileId": Required" - `); - }); - }); - - describe('with invalid "FollowProfileCriterion" criteria for "decryptionCriteria"', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.FOLLOW_PROFILE, - } as FollowProfileCriterion, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.profileId": Required" - `); - }); - }); - - describe('with invalid "CollectPublicationCriterion" criteria for "decryptionCriteria"', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.COLLECT_PUBLICATION, - } as CollectPublicationCriterion, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.publicationId": Required" - `); - }); - }); - - describe('with invalid "AndCriterion" criteria for "decryptionCriteria"', () => { - it('should provide an actionable error message for not enough criteria', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.AND, - and: [mockCollectThisPublicationCriterion()], - }, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.and": Array must contain at least 2 element(s)" - `); - }); - - it('should provide an actionable error message for duplicated criteria', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.AND, - and: [mockCollectThisPublicationCriterion(), mockCollectThisPublicationCriterion()], - }, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.and": Must be an array of unique criteria" - `); - }); - - it('should provide an actionable error message for too many criteria', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.AND, - and: [ - mockCollectThisPublicationCriterion(), - mockCollectPublicationCriterion(), - mockNftOwnershipCriterion(), - mockAddressOwnershipCriterion(), - mockProfileOwnershipCriterion(), - mockFollowProfileCriterion(), - ], - }, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.and": Array must contain at most 5 element(s)" - `); - }); - }); - - describe('with invalid "OrCriterion" criteria for "decryptionCriteria"', () => { - it('should provide an actionable error message for not enough criteria', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.OR, - or: [mockCollectThisPublicationCriterion()], - }, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.or": Array must contain at least 2 element(s)" - `); - }); - - it('should provide an actionable error message for duplicated criteria', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.OR, - or: [mockCollectThisPublicationCriterion(), mockCollectThisPublicationCriterion()], - }, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.or": Must be an array of unique criteria" - `); - }); - - it('should provide an actionable error message for too many criteria', () => { - expect(() => - validateCreatePostRequest( - mockCreatePostRequest({ - decryptionCriteria: { - type: DecryptionCriteriaType.OR, - or: [ - mockCollectThisPublicationCriterion(), - mockCollectPublicationCriterion(), - mockNftOwnershipCriterion(), - mockAddressOwnershipCriterion(), - mockProfileOwnershipCriterion(), - mockFollowProfileCriterion(), - ], - }, - }), - ), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "decryptionCriteria.or": Array must contain at most 5 element(s)" - `); - }); - }); - - describe('with invalid "collect" policy', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest({ - contentFocus: ContentFocus.TEXT_ONLY, - content: '', - collect: { - type: CollectPolicyType.CHARGE, - fee: '1', - }, - delegate: false, - locale: 'en', - kind: TransactionKind.CREATE_POST, - offChain: false, - profileId: mockProfileId(), - reference: { - type: ReferencePolicyType.ANYONE, - }, - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "collect" expected to match one of the following groups: - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.metadata": Required - · "collect.mirrorReward": Required - · "collect.recipient": Required - · "collect.timeLimited": Required - OR: - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.metadata": Required - · "collect.mirrorReward": Required - · "collect.recipients": Required - OR: - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.metadata": Required - · "collect.mirrorReward": Required - · "collect.recipient": Required - · "collect.vault": Required - OR: - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.metadata": Required - · "collect.mirrorReward": Required - · "collect.recipient": Required - · "collect.depositToAave": Invalid literal value, expected true - OR: - · "collect.type": Invalid literal value, expected "FREE" - · "collect.metadata": Required - · "collect.followersOnly": Required - OR: - · "collect.type": Invalid literal value, expected "NO_COLLECT"" - `); - }); - }); - - describe('with invalid "collect.metadata" for collectable publications', () => { - it('should provide an actionable error message in case of "collect.metadata" misconfiguration', () => { - expect(() => - validateCreatePostRequest({ - contentFocus: ContentFocus.TEXT_ONLY, - content: '', - collect: { - type: CollectPolicyType.FREE, - metadata: {}, - }, - delegate: false, - locale: 'en', - kind: TransactionKind.CREATE_POST, - offChain: false, - profileId: mockProfileId(), - reference: { - type: ReferencePolicyType.ANYONE, - }, - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "collect" expected to match one of the following groups: - · "collect.type": Invalid literal value, expected "CHARGE" - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.mirrorReward": Required - · "collect.recipient": Required - · "collect.timeLimited": Required - OR: - · "collect.type": Invalid literal value, expected "CHARGE" - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.mirrorReward": Required - · "collect.recipients": Required - OR: - · "collect.type": Invalid literal value, expected "CHARGE" - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.mirrorReward": Required - · "collect.recipient": Required - · "collect.vault": Required - OR: - · "collect.type": Invalid literal value, expected "CHARGE" - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.mirrorReward": Required - · "collect.recipient": Required - · "collect.depositToAave": Invalid literal value, expected true - OR: - · "collect.followersOnly": Required - OR: - · "collect.type": Invalid literal value, expected "NO_COLLECT"" - `); - }); - }); - - describe('with invalid "attributes"', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest({ - attributes: {}, - contentFocus: ContentFocus.TEXT_ONLY, - content: '', - collect: { - type: CollectPolicyType.NO_COLLECT, - }, - delegate: false, - locale: 'en', - kind: TransactionKind.CREATE_POST, - offChain: false, - profileId: mockProfileId(), - reference: { - type: ReferencePolicyType.ANYONE, - }, - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "attributes": Expected array, received object" - `); - }); - }); - - describe('with invalid "image"', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest({ - contentFocus: ContentFocus.TEXT_ONLY, - content: '', - collect: { - type: CollectPolicyType.NO_COLLECT, - }, - delegate: false, - image: {}, - locale: 'en', - kind: TransactionKind.CREATE_POST, - offChain: false, - profileId: mockProfileId(), - reference: { - type: ReferencePolicyType.ANYONE, - }, - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "image.mimeType": Required - · "image.url": Required" - `); - }); - }); - - describe('with invalid "name"', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest({ - contentFocus: ContentFocus.TEXT_ONLY, - content: '', - collect: { - type: CollectPolicyType.NO_COLLECT, - }, - delegate: false, - name: 42, // <<<<<< - locale: 'en', - kind: TransactionKind.CREATE_POST, - offChain: false, - profileId: mockProfileId(), - reference: { - type: ReferencePolicyType.ANYONE, - }, - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "name": Expected string, received number" - `); - }); - }); - - describe('with invalid "attributes"', () => { - it('should provide an actionable error message', () => { - expect(() => - validateCreatePostRequest({ - contentFocus: ContentFocus.TEXT_ONLY, - content: '', - collect: { - type: CollectPolicyType.NO_COLLECT, - }, - delegate: false, - locale: 'en', - kind: TransactionKind.CREATE_POST, - offChain: false, - profileId: mockProfileId(), - reference: { - type: ReferencePolicyType.DEGREES_OF_SEPARATION, - }, - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "reference.params": Required" - `); - }); - }); - }); - - describe(`when testing the "validateCreateCommentRequest"`, () => { - it('should provide an actionable error message in case of "collect" policy misconfiguration', () => { - expect(() => - validateCreateCommentRequest({ - contentFocus: ContentFocus.TEXT_ONLY, - content: '', - collect: { - type: CollectPolicyType.CHARGE, - fee: '1', - }, - delegate: false, - locale: 'en', - kind: TransactionKind.CREATE_COMMENT, - offChain: false, - profileId: mockProfileId(), - publicationId: mockPublicationId(), - reference: { - type: ReferencePolicyType.ANYONE, - }, - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "collect" expected to match one of the following groups: - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.metadata": Required - · "collect.mirrorReward": Required - · "collect.recipient": Required - · "collect.timeLimited": Required - OR: - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.metadata": Required - · "collect.mirrorReward": Required - · "collect.recipients": Required - OR: - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.metadata": Required - · "collect.mirrorReward": Required - · "collect.recipient": Required - · "collect.vault": Required - OR: - · "collect.fee": value not instance of Amount - · "collect.followersOnly": Required - · "collect.metadata": Required - · "collect.mirrorReward": Required - · "collect.recipient": Required - · "collect.depositToAave": Invalid literal value, expected true - OR: - · "collect.type": Invalid literal value, expected "FREE" - · "collect.metadata": Required - · "collect.followersOnly": Required - OR: - · "collect.type": Invalid literal value, expected "NO_COLLECT"" - `); - }); - - it('should provide an actionable error message in case of "reference" policy misconfiguration', () => { - expect(() => - validateCreateCommentRequest({ - contentFocus: ContentFocus.TEXT_ONLY, - content: '', - collect: { - type: CollectPolicyType.NO_COLLECT, - }, - delegate: false, - locale: 'en', - kind: TransactionKind.CREATE_COMMENT, - offChain: false, - profileId: mockProfileId(), - publicationId: mockPublicationId(), - reference: { - type: ReferencePolicyType.DEGREES_OF_SEPARATION, - }, - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "reference.params": Required" - `); - }); - }); - - describe(`when testing the "validateTokenAllowanceRequest"`, () => { - it('should provide an actionable error message in case of misuse', () => { - expect(() => - validateTokenAllowanceRequest({ - amount: 42, - kind: TransactionKind.APPROVE_MODULE, - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "amount": value not instance of Amount - · "spender": Required - · "limit": Required" - `); - }); - }); - - describe(`when testing the "validateUpdateFollowPolicyRequest"`, () => { - it('should provide an actionable error message in case of misuse', () => { - expect(() => - validateUpdateFollowPolicyRequest({ - kind: TransactionKind.UPDATE_FOLLOW_POLICY, - policy: { - type: FollowPolicyType.CHARGE, - amount: 42, - }, - profileId: mockProfileId(), - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "policy.amount": value not instance of Amount - · "policy.recipient": Required" - `); - }); - }); - - describe(`when testing the "validateUpdateProfileDetailsRequest"`, () => { - it('should provide an actionable error message in case of misuse', () => { - expect(() => - validateUpdateProfileDetailsRequest({ - attributes: { - foo: new RegExp('foo'), - }, - bio: 42, - coverPicture: null, - delegate: false, - kind: TransactionKind.UPDATE_PROFILE_DETAILS, - policy: { - type: FollowPolicyType.CHARGE, - amount: 42, - }, - profileId: mockProfileId(), - }), - ).toThrowErrorMatchingInlineSnapshot(` - "fix the following issues - · "attributes.foo" expected to match one of the following groups: - · "attributes.foo": Expected boolean, received object - OR: - · "attributes.foo": Invalid date - OR: - · "attributes.foo": Expected number, received object - OR: - · "attributes.foo": Expected string, received object - OR: - · "attributes.foo": Expected null, received object - · "bio": Expected string, received number - · "name": Required" - `); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/adapters/schemas/common.ts b/packages/react-v1/src/transactions/adapters/schemas/common.ts deleted file mode 100644 index bbcbd8439a..0000000000 --- a/packages/react-v1/src/transactions/adapters/schemas/common.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* eslint-disable @typescript-eslint/unbound-method */ -import { ProfileId, PublicationId, Signature } from '@lens-protocol/domain/entities'; -import { - Amount, - BigDecimal, - ChainType, - Erc20, - erc20, - Erc20Amount, - Kind, - UnknownObject, -} from '@lens-protocol/shared-kernel'; -import { z } from 'zod'; - -import { profileId, publicationId } from '../../../utils'; - -const Erc20Schema: z.Schema = z - .object({ - kind: z.literal(Kind.ERC20), - name: z.string(), - decimals: z.number(), - symbol: z.string(), - address: z.string(), - chainType: z.nativeEnum(ChainType), - }) - .transform((value) => erc20(value)); - -/** - * The type annotation here to reduce the likelihood of incurring in the TS7056 error down the line: - * ``` - * error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed. - * ``` - */ -export const SerializedErc20AmountSchema: z.Schema = z - .object({ - asset: Erc20Schema, - value: z.string(), - }) - .transform((value) => Amount.erc20(value.asset, value.value)); - -export const ProfileIdSchema: z.Schema = z - .string() - .transform(profileId); - -export const PublicationIdSchema: z.Schema = z - .string() - .transform(publicationId); - -// Checky workaround to private constructor -const AmountCtor = Amount.ether(0).constructor as new ( - asset: Erc20, - value: BigDecimal, -) => Erc20Amount; - -export const Erc20AmountInstanceSchema: z.Schema = - z.instanceof(AmountCtor, 'value not instance of Amount'); - -export type Erc20AmountSchema = z.Schema; - -export const SignatureSchema: z.Schema = z - .string() - .transform((value) => value as Signature); diff --git a/packages/react-v1/src/transactions/adapters/schemas/erc20.ts b/packages/react-v1/src/transactions/adapters/schemas/erc20.ts deleted file mode 100644 index af41760b8d..0000000000 --- a/packages/react-v1/src/transactions/adapters/schemas/erc20.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TransactionKind } from '@lens-protocol/domain/entities'; -import { TokenAllowanceLimit } from '@lens-protocol/domain/use-cases/wallets'; -import { z } from 'zod'; - -import { Erc20AmountSchema } from './common'; - -export function tokenAllowanceRequestSchema( - amountSchema: TAmountSchema, -) { - return z.object({ - amount: amountSchema, - spender: z.string(), - limit: z.nativeEnum(TokenAllowanceLimit), - kind: z.literal(TransactionKind.APPROVE_MODULE), - }); -} diff --git a/packages/react-v1/src/transactions/adapters/schemas/formatters.ts b/packages/react-v1/src/transactions/adapters/schemas/formatters.ts deleted file mode 100644 index aee01751c7..0000000000 --- a/packages/react-v1/src/transactions/adapters/schemas/formatters.ts +++ /dev/null @@ -1,102 +0,0 @@ -// Heavily customized and simplified version of https://www.npmjs.com/package/zod-validation-error - -import { assertNonEmptyArray, hasAtLeastOne, NonEmptyArray } from '@lens-protocol/shared-kernel'; -import { z } from 'zod'; - -const maxIssuesInMessage = 99; -const issueSeparator = '\n'; -const prefix = '· '; - -function escapeQuotes(str: string): string { - return str.replace(/"/g, '\\"'); -} - -/** - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#identifiers - */ -const identifierRegex = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/u; - -function formatPath(path: NonEmptyArray): string { - if (path.length === 1) { - return path[0].toString(); - } - - return path.reduce((acc, item) => { - // handle numeric indices - if (typeof item === 'number') { - return acc + '[' + item.toString() + ']'; - } - - // handle quoted values - if (item.includes('"')) { - return acc + '["' + escapeQuotes(item) + '"]'; - } - - // handle special characters - if (!identifierRegex.test(item)) { - return acc + '["' + item + '"]'; - } - - // handle normal values - const separator = acc.length === 0 ? '' : '.'; - return acc + separator + item; - }, ''); -} - -function formatZozInvalidUnionIssue(issue: z.ZodInvalidUnionIssue): string { - const groups = issue.unionErrors.reduce((acc, zodError) => { - const newIssues = zodError.issues - .map((nested) => { - if (hasAtLeastOne(nested.path)) { - return `\t\t${prefix}"${formatPath(nested.path)}": ${nested.message}`; - } - return issue.message; - }) - .join(issueSeparator); - - if (!acc.includes(newIssues)) { - acc.push(newIssues); - } - - return acc; - }, []); - - const path = Array.isArray(issue.path) ? issue.path : [issue.path]; - assertNonEmptyArray(path); - - return ( - `${prefix}"${formatPath(path)}" expected to match one of the following groups:\n` + - `${groups.join(`${issueSeparator}\tOR:${issueSeparator}`)}` - ); -} - -function formatZodIssue(issue: z.ZodIssue): string { - if (issue.code === z.ZodIssueCode.invalid_union) { - return formatZozInvalidUnionIssue(issue); - } - - if (hasAtLeastOne(issue.path)) { - return `${prefix}"${formatPath(issue.path)}": ${issue.message}`; - } - - return issue.message; -} - -export function formatZodError(zodError: z.ZodError): string { - const reason = zodError.errors - // limit max number of issues printed in the reason section - .slice(0, maxIssuesInMessage) - // format error message - .map((issue) => formatZodIssue(issue)) - // concat as string - .join(issueSeparator); - - if (reason.length === 0) { - return ( - 'invalid argument, it was not possible to determine a more detailed reason.\n' + - 'Check the input you provided and try again.' - ); - } - - return `fix the following issues\n${reason}`; -} diff --git a/packages/react-v1/src/transactions/adapters/schemas/profiles.ts b/packages/react-v1/src/transactions/adapters/schemas/profiles.ts deleted file mode 100644 index f00d250684..0000000000 --- a/packages/react-v1/src/transactions/adapters/schemas/profiles.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { TransactionKind } from '@lens-protocol/domain/entities'; -import { FollowPolicyType } from '@lens-protocol/domain/use-cases/profile'; -import { z } from 'zod'; - -import { - Erc20AmountSchema, - ProfileIdSchema, - SerializedErc20AmountSchema, - SignatureSchema, -} from './common'; - -export const CreateProfileRequestSchema = z.object({ - handle: z.string(), - kind: z.literal(TransactionKind.CREATE_PROFILE), -}); - -const FollowRequestFeeSchema = z.object({ - amount: SerializedErc20AmountSchema, - contractAddress: z.string(), - recipient: z.string(), -}); - -export const UnconstrainedFollowRequestSchema = z.object({ - followerAddress: z.string(), - profileId: ProfileIdSchema, - kind: z.literal(TransactionKind.FOLLOW_PROFILES), -}); - -export const PaidFollowRequestSchema = z.object({ - followerAddress: z.string(), - profileId: ProfileIdSchema, - kind: z.literal(TransactionKind.FOLLOW_PROFILES), - fee: FollowRequestFeeSchema, -}); - -export const ProfileOwnerFollowRequestSchema = z.object({ - followerAddress: z.string(), - profileId: ProfileIdSchema, - kind: z.literal(TransactionKind.FOLLOW_PROFILES), - followerProfileId: z.string(), -}); - -export const UnfollowRequestSchema = z.object({ - profileId: ProfileIdSchema, - kind: z.literal(TransactionKind.UNFOLLOW_PROFILE), -}); - -export const UpdateDispatcherConfigRequestSchema = z.object({ - profileId: ProfileIdSchema, - enabled: z.boolean(), - kind: z.literal(TransactionKind.UPDATE_DISPATCHER_CONFIG), -}); - -function chargeFollowPolicyConfigSchema( - amountSchema: TAmountSchema, -) { - return z.object({ - type: z.literal(FollowPolicyType.CHARGE), - amount: amountSchema, - recipient: z.string(), - }); -} - -const AnyoneFollowPolicyConfigSchema = z.object({ - type: z.literal(FollowPolicyType.ANYONE), -}); - -const OnlyProfileOwnersFollowPolicyConfigSchema = z.object({ - type: z.literal(FollowPolicyType.ONLY_PROFILE_OWNERS), -}); - -const NoOneFollowPolicyConfigSchema = z.object({ - type: z.literal(FollowPolicyType.NO_ONE), -}); - -export function updateFollowPolicyRequestSchema( - amountSchema: TAmountSchema, -) { - return z.object({ - profileId: ProfileIdSchema, - policy: z.discriminatedUnion('type', [ - chargeFollowPolicyConfigSchema(amountSchema), - AnyoneFollowPolicyConfigSchema, - OnlyProfileOwnersFollowPolicyConfigSchema, - NoOneFollowPolicyConfigSchema, - ]), - kind: z.literal(TransactionKind.UPDATE_FOLLOW_POLICY), - }); -} - -const PartialAttributesUpdateSchema = z.record( - z.union([z.boolean(), z.coerce.date(), z.number(), z.string(), z.null()]), -); - -export const UpdateProfileDetailsRequestSchema = z.object({ - attributes: PartialAttributesUpdateSchema.optional(), - bio: z.string().nullable().optional(), - coverPicture: z.string().nullable().optional(), - name: z.string(), - profileId: ProfileIdSchema, - kind: z.literal(TransactionKind.UPDATE_PROFILE_DETAILS), - delegate: z.boolean(), -}); - -const NftOwnershipSignatureSchema = z.object({ - id: z.string(), - signature: SignatureSchema, -}); - -export const UpdateNftProfileImageRequestSchema = z.object({ - kind: z.literal(TransactionKind.UPDATE_PROFILE_IMAGE), - profileId: ProfileIdSchema, - signature: NftOwnershipSignatureSchema, - delegate: z.boolean(), -}); - -export const UpdateOffChainProfileImageRequestSchema = z.object({ - url: z.string(), - kind: z.literal(TransactionKind.UPDATE_PROFILE_IMAGE), - profileId: ProfileIdSchema, - delegate: z.boolean(), -}); diff --git a/packages/react-v1/src/transactions/adapters/schemas/publications.ts b/packages/react-v1/src/transactions/adapters/schemas/publications.ts deleted file mode 100644 index 32bbe85c03..0000000000 --- a/packages/react-v1/src/transactions/adapters/schemas/publications.ts +++ /dev/null @@ -1,408 +0,0 @@ -import { - AppId, - DecryptionCriteriaType, - Erc20ComparisonOperator, - NftContractType, - TransactionKind, -} from '@lens-protocol/domain/entities'; -import { - SupportedFileType, - CollectPolicyType, - CollectType, - ContentFocus, - MetadataAttributeDisplayType, - ReferencePolicyType, - ContentWarning, - ImageType, -} from '@lens-protocol/domain/use-cases/publications'; -import { z } from 'zod'; - -import { appId } from '../../../utils'; -import { - Erc20AmountSchema, - SerializedErc20AmountSchema, - ProfileIdSchema, - PublicationIdSchema, -} from './common'; - -const NftOwnershipCriterionSchema = z.object({ - type: z.literal(DecryptionCriteriaType.NFT_OWNERSHIP), - contractAddress: z.string(), - chainId: z.number(), - contractType: z.nativeEnum(NftContractType), - tokenIds: z.array(z.string()).min(1).max(30).optional(), -}); - -function erc20OwnershipCriterionSchema( - amountSchema: TAmountSchema, -) { - return z.object({ - type: z.literal(DecryptionCriteriaType.ERC20_OWNERSHIP), - amount: amountSchema, - condition: z.nativeEnum(Erc20ComparisonOperator), - }); -} - -const AddressOwnershipCriterionSchema = z.object({ - type: z.literal(DecryptionCriteriaType.ADDRESS_OWNERSHIP), - address: z.string(), -}); - -const ProfileOwnershipCriterionSchema = z.object({ - type: z.literal(DecryptionCriteriaType.PROFILE_OWNERSHIP), - profileId: ProfileIdSchema, -}); - -const FollowOwnershipCriterionSchema = z.object({ - type: z.literal(DecryptionCriteriaType.FOLLOW_PROFILE), - profileId: ProfileIdSchema, -}); - -const CollectPublicationCriterionSchema = z.object({ - type: z.literal(DecryptionCriteriaType.COLLECT_PUBLICATION), - publicationId: PublicationIdSchema, -}); - -const CollectThisPublicationCriterionSchema = z.object({ - type: z.literal(DecryptionCriteriaType.COLLECT_THIS_PUBLICATION), -}); - -function simpleCriterionSchema( - amountSchema: TAmountSchema, -) { - return z.discriminatedUnion('type', [ - NftOwnershipCriterionSchema, - erc20OwnershipCriterionSchema(amountSchema), - AddressOwnershipCriterionSchema, - ProfileOwnershipCriterionSchema, - FollowOwnershipCriterionSchema, - CollectPublicationCriterionSchema, - CollectThisPublicationCriterionSchema, - ]); -} - -function unique(items: Array) { - return new Set(items.map((item) => JSON.stringify(item))).size === items.length; -} - -function orCriterionSchema(amountSchema: TAmountSchema) { - return z.object({ - type: z.literal(DecryptionCriteriaType.OR), - or: z.array(simpleCriterionSchema(amountSchema)).min(2).max(5).refine(unique, { - message: 'Must be an array of unique criteria', - }), - }); -} - -function andCriterionSchema(amountSchema: TAmountSchema) { - return z.object({ - type: z.literal(DecryptionCriteriaType.AND), - and: z.array(simpleCriterionSchema(amountSchema)).min(2).max(5).refine(unique, { - message: 'Must be an array of unique criteria', - }), - }); -} - -function decryptionCriteriaSchema( - amountSchema: TAmountSchema, -) { - return z - .discriminatedUnion('type', [ - orCriterionSchema(amountSchema), - andCriterionSchema(amountSchema), - NftOwnershipCriterionSchema, - erc20OwnershipCriterionSchema(amountSchema), - AddressOwnershipCriterionSchema, - ProfileOwnershipCriterionSchema, - FollowOwnershipCriterionSchema, - CollectPublicationCriterionSchema, - CollectThisPublicationCriterionSchema, - ]) - .optional(); -} - -const MetadataAttributeSchema = z.discriminatedUnion('displayType', [ - z.object({ - displayType: z.literal(MetadataAttributeDisplayType.Date), - value: z.coerce.date(), - traitType: z.string(), - }), - z.object({ - displayType: z.literal(MetadataAttributeDisplayType.Number), - value: z.number(), - traitType: z.string(), - }), - z.object({ - displayType: z.literal(MetadataAttributeDisplayType.String), - value: z.string(), - traitType: z.string(), - }), -]); - -const NftMetadataSchema = z.object({ - name: z.string().optional(), - description: z.string().optional(), - attributes: z.array(MetadataAttributeSchema).optional(), - externalUrl: z.string().optional(), - image: z.string().optional(), - imageMimeType: z.nativeEnum(ImageType).optional(), -}); - -const RecipientWithSplitSchema = z.object({ - recipient: z.string(), - split: z.number(), -}); - -function aaveChargeCollectPolicyConfigSchema( - feeSchema: TAmountSchema, -) { - return z.object({ - type: z.literal(CollectPolicyType.CHARGE), - fee: feeSchema, - followersOnly: z.boolean(), - metadata: NftMetadataSchema, - mirrorReward: z.number(), - collectLimit: z.number().optional(), - - recipient: z.string(), - depositToAave: z.literal(true), - endTimestamp: z.number().optional(), - }); -} - -function vaultChargeCollectPolicyConfigSchema( - feeSchema: TAmountSchema, -) { - return z.object({ - type: z.literal(CollectPolicyType.CHARGE), - fee: feeSchema, - followersOnly: z.boolean(), - metadata: NftMetadataSchema, - mirrorReward: z.number(), - collectLimit: z.number().optional(), - - recipient: z.string(), - vault: z.string(), - endTimestamp: z.number().optional(), - }); -} - -function multirecipientChargeCollectPolicyConfigSchema( - feeSchema: TAmountSchema, -) { - return z.object({ - type: z.literal(CollectPolicyType.CHARGE), - fee: feeSchema, - followersOnly: z.boolean(), - metadata: NftMetadataSchema, - mirrorReward: z.number(), - collectLimit: z.number().optional(), - - recipients: z.array(RecipientWithSplitSchema), - endTimestamp: z.number().optional(), - }); -} - -function simpleChargeCollectPolicyConfigSchema( - feeSchema: TAmountSchema, -) { - return z.object({ - type: z.literal(CollectPolicyType.CHARGE), - fee: feeSchema, - followersOnly: z.boolean(), - metadata: NftMetadataSchema, - mirrorReward: z.number(), - collectLimit: z.number().optional(), - - recipient: z.string(), - timeLimited: z.boolean(), - }); -} - -const FreeCollectPolicyConfigSchema = z.object({ - type: z.literal(CollectPolicyType.FREE), - metadata: NftMetadataSchema, - followersOnly: z.boolean(), -}); - -const NoCollectPolicyConfigSchema = z.object({ - type: z.literal(CollectPolicyType.NO_COLLECT), -}); - -function collectPolicyConfigSchema( - feeSchema: TAmountSchema, -) { - return z.union([ - simpleChargeCollectPolicyConfigSchema(feeSchema), - multirecipientChargeCollectPolicyConfigSchema(feeSchema), - vaultChargeCollectPolicyConfigSchema(feeSchema), - aaveChargeCollectPolicyConfigSchema(feeSchema), - FreeCollectPolicyConfigSchema, - NoCollectPolicyConfigSchema, - ]); -} - -const MediaObjectSchema = z.object({ - altTag: z.string().optional(), - cover: z.string().optional(), - mimeType: z.nativeEnum(SupportedFileType), - url: z.string(), -}); - -const MetadataImageSchema = z.object({ - mimeType: z.nativeEnum(ImageType), - url: z.string(), -}); - -const AnyoneReferencePolicyConfigSchema = z.object({ - type: z.literal(ReferencePolicyType.ANYONE), -}); - -const DegreesOfSeparationReferencePolicyConfigSchema = z.object({ - type: z.literal(ReferencePolicyType.DEGREES_OF_SEPARATION), - params: z.object({ - commentsRestricted: z.boolean(), - mirrorsRestricted: z.boolean(), - degreesOfSeparation: z.number(), - }), -}); - -const FollowersOnlyReferencePolicyConfigSchema = z.object({ - type: z.literal(ReferencePolicyType.FOLLOWERS_ONLY), -}); - -const ReferencePolicyConfigSchema = z.discriminatedUnion('type', [ - AnyoneReferencePolicyConfigSchema, - DegreesOfSeparationReferencePolicyConfigSchema, - FollowersOnlyReferencePolicyConfigSchema, -]); - -const AppIdSchema: z.Schema = z.any().transform(appId); - -function createCommonPublicationRequestSchema( - amountSchema: TAmountSchema, -) { - return z.object({ - appId: AppIdSchema.optional(), - attributes: z.array(MetadataAttributeSchema).optional(), - collect: collectPolicyConfigSchema(amountSchema), - contentWarning: z.nativeEnum(ContentWarning).optional(), - decryptionCriteria: decryptionCriteriaSchema(amountSchema), - delegate: z.boolean(), - image: MetadataImageSchema.optional(), - name: z.string().optional(), - locale: z.string(), - offChain: z.boolean(), - profileId: ProfileIdSchema, - reference: ReferencePolicyConfigSchema, - tags: z.array(z.string()).optional(), - }); -} - -function createBasePostRequestSchema( - amountSchema: TAmountSchema, -) { - return createCommonPublicationRequestSchema(amountSchema).extend({ - kind: z.literal(TransactionKind.CREATE_POST), - }); -} - -export function createTextualPostRequestSchema( - amountSchema: TAmountSchema, -) { - return createBasePostRequestSchema(amountSchema).extend({ - content: z.string(), - contentFocus: z.enum([ContentFocus.ARTICLE, ContentFocus.LINK, ContentFocus.TEXT_ONLY]), - media: z.array(MediaObjectSchema).optional(), - }); -} - -export function createMediaPostRequestSchema( - amountSchema: TAmountSchema, -) { - return createBasePostRequestSchema(amountSchema).extend({ - content: z.string().optional(), - contentFocus: z.enum([ContentFocus.AUDIO, ContentFocus.IMAGE, ContentFocus.VIDEO]), - media: z.array(MediaObjectSchema), - }); -} - -export function createEmbedPostRequestSchema( - amountSchema: TAmountSchema, -) { - return createBasePostRequestSchema(amountSchema).extend({ - animationUrl: z.string(), - content: z.string().optional(), - contentFocus: z.enum([ContentFocus.EMBED]), - media: z.array(MediaObjectSchema).optional(), - }); -} - -function createBaseCommentRequestSchema( - amountSchema: TAmountSchema, -) { - return createCommonPublicationRequestSchema(amountSchema).extend({ - publicationId: PublicationIdSchema, - kind: z.literal(TransactionKind.CREATE_COMMENT), - }); -} - -export function createTextualCommentRequestSchema( - amountSchema: TAmountSchema, -) { - return createBaseCommentRequestSchema(amountSchema).extend({ - content: z.string(), - contentFocus: z.enum([ContentFocus.ARTICLE, ContentFocus.LINK, ContentFocus.TEXT_ONLY]), - media: z.array(MediaObjectSchema).optional(), - }); -} - -export function createMediaCommentRequestSchema( - amountSchema: TAmountSchema, -) { - return createBaseCommentRequestSchema(amountSchema).extend({ - content: z.string().optional(), - contentFocus: z.enum([ContentFocus.AUDIO, ContentFocus.IMAGE, ContentFocus.VIDEO]), - media: z.array(MediaObjectSchema), - }); -} - -export function createEmbedCommentRequestSchema( - amountSchema: TAmountSchema, -) { - return createBaseCommentRequestSchema(amountSchema).extend({ - animationUrl: z.string(), - content: z.string().optional(), - contentFocus: z.enum([ContentFocus.EMBED]), - media: z.array(MediaObjectSchema).optional(), - }); -} - -export const CreateMirrorRequestSchema = z.object({ - profileId: ProfileIdSchema, - publicationId: PublicationIdSchema, - kind: z.literal(TransactionKind.MIRROR_PUBLICATION), - delegate: z.boolean(), - offChain: z.boolean(), -}); - -const BaseCollectRequestSchema = z.object({ - kind: z.literal(TransactionKind.COLLECT_PUBLICATION), - profileId: ProfileIdSchema, - publicationId: PublicationIdSchema, -}); - -export const FreeCollectRequestSchema = BaseCollectRequestSchema.extend({ - type: z.literal(CollectType.FREE), - followerOnly: z.boolean(), -}); - -const CollectFeeSchema = z.object({ - amount: SerializedErc20AmountSchema, - contractAddress: z.string(), -}); - -export const PaidCollectRequestSchema = BaseCollectRequestSchema.extend({ - type: z.literal(CollectType.PAID), - fee: CollectFeeSchema, -}); diff --git a/packages/react-v1/src/transactions/adapters/schemas/transactions.ts b/packages/react-v1/src/transactions/adapters/schemas/transactions.ts deleted file mode 100644 index d741f9d3c3..0000000000 --- a/packages/react-v1/src/transactions/adapters/schemas/transactions.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { ProxyActionStatus } from '@lens-protocol/domain/entities'; -import { - AnyTransactionRequest, - ProtocolTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, UnknownObject } from '@lens-protocol/shared-kernel'; -import { z } from 'zod'; - -import { SerializedErc20AmountSchema } from './common'; -import { tokenAllowanceRequestSchema } from './erc20'; -import { - CreateProfileRequestSchema, - PaidFollowRequestSchema, - ProfileOwnerFollowRequestSchema, - UnconstrainedFollowRequestSchema, - UnfollowRequestSchema, - UpdateDispatcherConfigRequestSchema, - updateFollowPolicyRequestSchema, - UpdateNftProfileImageRequestSchema, - UpdateOffChainProfileImageRequestSchema, - UpdateProfileDetailsRequestSchema, -} from './profiles'; -import { - createEmbedCommentRequestSchema, - createEmbedPostRequestSchema, - createMediaCommentRequestSchema, - createMediaPostRequestSchema, - CreateMirrorRequestSchema, - createTextualCommentRequestSchema, - createTextualPostRequestSchema, - FreeCollectRequestSchema, - PaidCollectRequestSchema, -} from './publications'; - -// the repetition of the schemas compared to AnyTransactionRequestSchema -// is intentional due to https://github.com/colinhacks/zod/issues/2106 -const ProtocolTransactionRequestSchema: z.Schema< - ProtocolTransactionRequest, - z.ZodTypeDef, - UnknownObject -> = z.union([ - // CollectRequest schemas - FreeCollectRequestSchema, - PaidCollectRequestSchema, - - // FollowRequest schemas - PaidFollowRequestSchema, - ProfileOwnerFollowRequestSchema, - UnconstrainedFollowRequestSchema, - - // CreatePostRequest schemas - createEmbedPostRequestSchema(SerializedErc20AmountSchema), - createMediaPostRequestSchema(SerializedErc20AmountSchema), - createTextualPostRequestSchema(SerializedErc20AmountSchema), - - // CreateCommentRequest schemas - createEmbedCommentRequestSchema(SerializedErc20AmountSchema), - createMediaCommentRequestSchema(SerializedErc20AmountSchema), - createTextualCommentRequestSchema(SerializedErc20AmountSchema), - - CreateMirrorRequestSchema, - - CreateProfileRequestSchema, - - UnfollowRequestSchema, - - UpdateDispatcherConfigRequestSchema, - - updateFollowPolicyRequestSchema(SerializedErc20AmountSchema), - - UpdateProfileDetailsRequestSchema, - - // UpdateProfileImageRequest schemas - UpdateNftProfileImageRequestSchema, - UpdateOffChainProfileImageRequestSchema, -]); - -// the repetition of the schemas compared to ProtocolTransactionRequestSchema -// is intentional due to https://github.com/colinhacks/zod/issues/2106 -const AnyTransactionRequestSchema: z.Schema = - z.union([ - tokenAllowanceRequestSchema(SerializedErc20AmountSchema), - - // CollectRequest schemas - FreeCollectRequestSchema, - PaidCollectRequestSchema, - - // FollowRequest schemas - PaidFollowRequestSchema, - ProfileOwnerFollowRequestSchema, - UnconstrainedFollowRequestSchema, - - // CreatePostRequest schemas - createEmbedPostRequestSchema(SerializedErc20AmountSchema), - createMediaPostRequestSchema(SerializedErc20AmountSchema), - createTextualPostRequestSchema(SerializedErc20AmountSchema), - - // CreateCommentRequest schemas - createEmbedCommentRequestSchema(SerializedErc20AmountSchema), - createMediaCommentRequestSchema(SerializedErc20AmountSchema), - createTextualCommentRequestSchema(SerializedErc20AmountSchema), - - CreateMirrorRequestSchema, - - CreateProfileRequestSchema, - - UnfollowRequestSchema, - - UpdateDispatcherConfigRequestSchema, - - updateFollowPolicyRequestSchema(SerializedErc20AmountSchema), - - UpdateProfileDetailsRequestSchema, - - // UpdateProfileImageRequest schemas - UpdateNftProfileImageRequestSchema, - UpdateOffChainProfileImageRequestSchema, - ]); - -export enum TransactionType { - Native, - Meta, - Proxy, - Data, -} - -const MetaTransactionSchema = z.object({ - type: z.literal(TransactionType.Meta), - chainType: z.nativeEnum(ChainType), - id: z.string(), - indexingId: z.string(), - txHash: z.string(), - nonce: z.number(), - request: ProtocolTransactionRequestSchema, -}); - -type MetaTransactionSchema = z.infer; - -const NativeTransactionSchema = z.object({ - type: z.literal(TransactionType.Native), - chainType: z.nativeEnum(ChainType), - id: z.string(), - indexingId: z.string().optional(), - txHash: z.string(), - request: AnyTransactionRequestSchema, -}); - -type NativeTransactionSchema = z.infer; - -const ProxyTransactionSchema = z.object({ - type: z.literal(TransactionType.Proxy), - chainType: z.nativeEnum(ChainType), - id: z.string(), - proxyId: z.string(), - txHash: z.string().optional(), - status: z.nativeEnum(ProxyActionStatus).optional(), - request: ProtocolTransactionRequestSchema, -}); - -type ProxyTransactionSchema = z.infer; - -const DataTransactionSchema = z.object({ - type: z.literal(TransactionType.Data), - id: z.string(), - request: ProtocolTransactionRequestSchema, -}); - -type DataTransactionSchema = z.infer; - -export const TransactionSchema = z.discriminatedUnion('type', [ - MetaTransactionSchema, - NativeTransactionSchema, - ProxyTransactionSchema, - DataTransactionSchema, -]); - -export type TransactionSchema = z.infer; - -export const TransactionStorageSchema = z.array(TransactionSchema); - -export type TransactionStorageSchema = z.infer; diff --git a/packages/react-v1/src/transactions/adapters/schemas/validators.ts b/packages/react-v1/src/transactions/adapters/schemas/validators.ts deleted file mode 100644 index afb975c1f8..0000000000 --- a/packages/react-v1/src/transactions/adapters/schemas/validators.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { - UpdateFollowPolicyRequest, - UpdateProfileDetailsRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { - CreateCommentRequest, - CreatePostRequest, -} from '@lens-protocol/domain/use-cases/publications'; -import { TokenAllowanceRequest } from '@lens-protocol/domain/use-cases/wallets'; -import { never } from '@lens-protocol/shared-kernel'; -import { z } from 'zod'; - -import { Erc20AmountInstanceSchema } from './common'; -import { tokenAllowanceRequestSchema } from './erc20'; -import { formatZodError } from './formatters'; -import { updateFollowPolicyRequestSchema, UpdateProfileDetailsRequestSchema } from './profiles'; -import { - createEmbedCommentRequestSchema, - createEmbedPostRequestSchema, - createMediaCommentRequestSchema, - createMediaPostRequestSchema, - createTextualCommentRequestSchema, - createTextualPostRequestSchema, -} from './publications'; - -export type Validator = (request: unknown) => asserts request is T; - -type InferShape> = T extends z.ZodType ? R : never; - -function createRequestValidator>(schema: T) { - return (request: unknown): asserts request is InferShape => { - const result = schema.safeParse(request); - - if (result.success) return; - - never(formatZodError(result.error)); - }; -} - -const CreatePostRequestSchema = z.discriminatedUnion('contentFocus', [ - createEmbedPostRequestSchema(Erc20AmountInstanceSchema), - createMediaPostRequestSchema(Erc20AmountInstanceSchema), - createTextualPostRequestSchema(Erc20AmountInstanceSchema), -]); - -export const validateCreatePostRequest: Validator = - createRequestValidator(CreatePostRequestSchema); - -const CreateCommentRequestSchema = z.discriminatedUnion('contentFocus', [ - createEmbedCommentRequestSchema(Erc20AmountInstanceSchema), - createMediaCommentRequestSchema(Erc20AmountInstanceSchema), - createTextualCommentRequestSchema(Erc20AmountInstanceSchema), -]); - -export const validateCreateCommentRequest: Validator = createRequestValidator( - CreateCommentRequestSchema, -); - -const TokenAllowanceRequestSchema = tokenAllowanceRequestSchema(Erc20AmountInstanceSchema); - -export const validateTokenAllowanceRequest: Validator = - createRequestValidator(TokenAllowanceRequestSchema); - -const UpdateFollowPolicyRequestSchema = updateFollowPolicyRequestSchema(Erc20AmountInstanceSchema); - -export const validateUpdateFollowPolicyRequest: Validator = - createRequestValidator(UpdateFollowPolicyRequestSchema); - -export const validateUpdateProfileDetailsRequest: Validator = - createRequestValidator(UpdateProfileDetailsRequestSchema); diff --git a/packages/react-v1/src/transactions/adapters/useApproveModuleController.ts b/packages/react-v1/src/transactions/adapters/useApproveModuleController.ts deleted file mode 100644 index 45da23f9a6..0000000000 --- a/packages/react-v1/src/transactions/adapters/useApproveModuleController.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - InsufficientGasError, - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { TokenAllowance, TokenAllowanceRequest } from '@lens-protocol/domain/use-cases/wallets'; - -import { useSharedDependencies } from '../../shared'; -import { ApproveTransactionGateway } from './ApproveTransactionGateway'; -import { PromiseResultPresenter } from './PromiseResultPresenter'; -import { validateTokenAllowanceRequest } from './schemas/validators'; - -export function useApproveModuleController() { - const { providerFactory, activeWallet, transactionQueue } = useSharedDependencies(); - - return async (request: TokenAllowanceRequest) => { - validateTokenAllowanceRequest(request); - - const presenter = new PromiseResultPresenter< - void, - InsufficientGasError | PendingSigningRequestError | UserRejectedError | WalletConnectionError - >(); - const approveTransactionGateway = new ApproveTransactionGateway(providerFactory); - - const tokenAllowance = new TokenAllowance( - activeWallet, - approveTransactionGateway, - presenter, - transactionQueue, - ); - - await tokenAllowance.increaseAllowance(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useCollectController.ts b/packages/react-v1/src/transactions/adapters/useCollectController.ts deleted file mode 100644 index 78e15dbadc..0000000000 --- a/packages/react-v1/src/transactions/adapters/useCollectController.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - CollectPublication, - CollectRequest, - FreeCollectRequest, -} from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - SignlessSubsidizeOnChain, - SubsidizeOnChain, -} from '@lens-protocol/domain/use-cases/transactions'; -import { - InsufficientAllowanceError, - InsufficientFundsError, -} from '@lens-protocol/domain/use-cases/wallets'; - -import { useSharedDependencies } from '../../shared'; -import { CollectPublicationGateway } from './CollectPublicationGateway'; -import { TransactionResultPresenter } from './TransactionResultPresenter'; - -export function useCollectController() { - const { - activeWallet, - apolloClient, - logger, - onChainRelayer, - tokenAvailability, - transactionFactory, - transactionGateway, - transactionQueue, - } = useSharedDependencies(); - - return async (request: CollectRequest) => { - const collectPublicationGateway = new CollectPublicationGateway( - apolloClient, - transactionFactory, - logger, - ); - - const presenter = new TransactionResultPresenter< - CollectRequest, - | BroadcastingError - | InsufficientAllowanceError - | InsufficientFundsError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - >(); - - const signedCollect = new SubsidizeOnChain( - activeWallet, - transactionGateway, - collectPublicationGateway, - onChainRelayer, - transactionQueue, - presenter, - ); - - const signlessCollect = new SignlessSubsidizeOnChain( - collectPublicationGateway, - transactionQueue, - presenter, - ); - - const collectPublication = new CollectPublication( - tokenAvailability, - signedCollect, - signlessCollect, - presenter, - ); - - await collectPublication.execute(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useCreateCommentController.ts b/packages/react-v1/src/transactions/adapters/useCreateCommentController.ts deleted file mode 100644 index 8500e7dfbe..0000000000 --- a/packages/react-v1/src/transactions/adapters/useCreateCommentController.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { CreateCommentRequest } from '@lens-protocol/domain/use-cases/publications'; - -import { useSharedDependencies } from '../../shared'; -import { PublicationMetadataUploader } from '../infrastructure/PublicationMetadataUploader'; -import { CreateCommentController } from './CreateCommentController'; -import { MetadataUploadHandler } from './MetadataUploadHandler'; -import { validateCreateCommentRequest } from './schemas/validators'; - -export type UseCreateCommentArgs = { - upload: MetadataUploadHandler; -}; - -export function useCreateCommentController({ upload }: UseCreateCommentArgs) { - const { - activeWallet, - apolloClient, - offChainRelayer, - onChainRelayer, - transactionFactory, - transactionGateway, - transactionQueue, - } = useSharedDependencies(); - - return async (request: CreateCommentRequest) => { - validateCreateCommentRequest(request); - - const uploader = PublicationMetadataUploader.create(upload); - const controller = new CreateCommentController({ - activeWallet, - apolloClient, - offChainRelayer, - onChainRelayer, - transactionFactory, - transactionGateway, - transactionQueue, - uploader, - }); - - return controller.execute(request); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useCreateEncryptedCommentController.ts b/packages/react-v1/src/transactions/adapters/useCreateEncryptedCommentController.ts deleted file mode 100644 index 7b63a6f931..0000000000 --- a/packages/react-v1/src/transactions/adapters/useCreateEncryptedCommentController.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { CreateCommentRequest } from '@lens-protocol/domain/use-cases/publications'; -import { invariant } from '@lens-protocol/shared-kernel'; - -import { EncryptionConfig } from '../../config'; -import { useSharedDependencies } from '../../shared'; -import { useActiveWalletSigner, useWalletLogin } from '../../wallet'; -import { AccessConditionBuilderFactory } from '../infrastructure/AccessConditionBuilderFactory'; -import { - CreateEncryptedCommentRequest, - EncryptedPublicationMetadataUploader, -} from '../infrastructure/EncryptedPublicationMetadataUploader'; -import { PublicationIdPredictor } from '../infrastructure/PublicationIdPredictor'; -import { createGatedClient } from '../infrastructure/createGatedClient'; -import { CreateCommentController } from './CreateCommentController'; -import { MetadataUploadHandler } from './MetadataUploadHandler'; - -export type UseCreateCommentArgs = { - encryption: EncryptionConfig; - upload: MetadataUploadHandler; -}; - -export function useCreateEncryptedCommentController({ encryption, upload }: UseCreateCommentArgs) { - const { - activeWallet, - apolloClient, - offChainRelayer, - onChainRelayer, - storageProvider, - transactionFactory, - transactionGateway, - transactionQueue, - environment, - } = useSharedDependencies(); - const { data: signer } = useActiveWalletSigner(); - - return async (request: CreateCommentRequest) => { - invariant( - signer, - `Cannot find the Active Wallet Signer, did you login with ${useWalletLogin.name}?`, - ); - - const createGatedClientFn = encryption.createGatedClient || createGatedClient; - - const client = createGatedClientFn({ - config: encryption.authentication, - signer, - encryptionProvider: encryption.provider, - environment, - storageProvider, - }); - - const publicationIdPredictor = new PublicationIdPredictor(apolloClient, transactionGateway); - - const accessConditionBuilderFactory = new AccessConditionBuilderFactory( - environment.chains, - publicationIdPredictor, - ); - - const uploader = EncryptedPublicationMetadataUploader.create( - client, - accessConditionBuilderFactory, - upload, - ); - - const controller = new CreateCommentController({ - activeWallet, - apolloClient, - offChainRelayer, - onChainRelayer, - transactionFactory, - transactionGateway, - transactionQueue, - uploader, - }); - - return controller.execute(request); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useCreateEncryptedPostController.ts b/packages/react-v1/src/transactions/adapters/useCreateEncryptedPostController.ts deleted file mode 100644 index 05fe39a9ae..0000000000 --- a/packages/react-v1/src/transactions/adapters/useCreateEncryptedPostController.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; -import { invariant } from '@lens-protocol/shared-kernel'; - -import { EncryptionConfig } from '../../config'; -import { useSharedDependencies } from '../../shared'; -import { useActiveWalletSigner, useWalletLogin } from '../../wallet'; -import { AccessConditionBuilderFactory } from '../infrastructure/AccessConditionBuilderFactory'; -import { - CreateEncryptedPostRequest, - EncryptedPublicationMetadataUploader, -} from '../infrastructure/EncryptedPublicationMetadataUploader'; -import { PublicationIdPredictor } from '../infrastructure/PublicationIdPredictor'; -import { createGatedClient } from '../infrastructure/createGatedClient'; -import { CreatePostController } from './CreatePostController'; -import { MetadataUploadHandler } from './MetadataUploadHandler'; - -export type UseCreatePostArgs = { - encryption: EncryptionConfig; - upload: MetadataUploadHandler; -}; - -export function useCreateEncryptedPostController({ encryption, upload }: UseCreatePostArgs) { - const { - activeWallet, - apolloClient, - environment, - offChainRelayer, - onChainRelayer, - publicationCacheManager, - storageProvider, - transactionFactory, - transactionGateway, - transactionQueue, - } = useSharedDependencies(); - const { data: signer } = useActiveWalletSigner(); - - return async (request: CreatePostRequest) => { - invariant( - signer, - `Cannot find the Active Wallet Signer, did you login with ${useWalletLogin.name}?`, - ); - - const createGatedClientFn = encryption.createGatedClient || createGatedClient; - - const client = createGatedClientFn({ - config: encryption.authentication, - signer, - encryptionProvider: encryption.provider, - environment, - storageProvider, - }); - - const publicationIdPredictor = new PublicationIdPredictor(apolloClient, transactionGateway); - - const accessConditionBuilderFactory = new AccessConditionBuilderFactory( - environment.chains, - publicationIdPredictor, - ); - - const uploader = EncryptedPublicationMetadataUploader.create( - client, - accessConditionBuilderFactory, - upload, - ); - - const controller = new CreatePostController({ - activeWallet, - apolloClient, - offChainRelayer, - onChainRelayer, - publicationCacheManager, - transactionFactory, - transactionGateway, - transactionQueue, - uploader, - }); - - return controller.execute(request); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useCreateMirrorController.tsx b/packages/react-v1/src/transactions/adapters/useCreateMirrorController.tsx deleted file mode 100644 index 547347dd6f..0000000000 --- a/packages/react-v1/src/transactions/adapters/useCreateMirrorController.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { CreateMirror, CreateMirrorRequest } from '@lens-protocol/domain/use-cases/publications'; -import { - BroadcastingError, - DelegableSigning, - SubsidizeOffChain, - SubsidizeOnChain, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { useSharedDependencies } from '../../shared'; -import { TransactionResultPresenter } from './TransactionResultPresenter'; -import { CreateOffChainMirrorGateway } from './publication-call-gateways/CreateOffChainMirrorGateway'; -import { CreateOnChainMirrorGateway } from './publication-call-gateways/CreateOnChainMirrorGateway'; - -export function useCreateMirrorController() { - const { - activeWallet, - apolloClient, - transactionFactory, - transactionGateway, - offChainRelayer, - onChainRelayer, - transactionQueue, - } = useSharedDependencies(); - - return async (request: CreateMirrorRequest) => { - const presenter = new TransactionResultPresenter< - CreateMirrorRequest, - BroadcastingError | PendingSigningRequestError | UserRejectedError | WalletConnectionError - >(); - - const onChainGateway = new CreateOnChainMirrorGateway(apolloClient, transactionFactory); - - const onChainMirror = new SubsidizeOnChain( - activeWallet, - transactionGateway, - onChainGateway, - onChainRelayer, - transactionQueue, - presenter, - ); - - const delegableOnChainMirror = new DelegableSigning( - onChainMirror, - onChainGateway, - transactionQueue, - presenter, - ); - - const offChainGateway = new CreateOffChainMirrorGateway(apolloClient, transactionFactory); - - const offChainMirror = new SubsidizeOffChain( - activeWallet, - offChainGateway, - offChainRelayer, - transactionQueue, - presenter, - ); - - const delegableOffChainMirror = new DelegableSigning( - offChainMirror, - offChainGateway, - transactionQueue, - presenter, - ); - - const createMirror = new CreateMirror(delegableOnChainMirror, delegableOffChainMirror); - - await createMirror.execute(request); - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useCreatePostController.ts b/packages/react-v1/src/transactions/adapters/useCreatePostController.ts deleted file mode 100644 index 87dbc3c4c3..0000000000 --- a/packages/react-v1/src/transactions/adapters/useCreatePostController.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { CreatePostRequest } from '@lens-protocol/domain/use-cases/publications'; - -import { useSharedDependencies } from '../../shared'; -import { PublicationMetadataUploader } from '../infrastructure/PublicationMetadataUploader'; -import { CreatePostController } from './CreatePostController'; -import { MetadataUploadHandler } from './MetadataUploadHandler'; -import { validateCreatePostRequest } from './schemas/validators'; - -export type UseCreatePostArgs = { - upload: MetadataUploadHandler; -}; - -export function useCreatePostController({ upload }: UseCreatePostArgs) { - const { - activeWallet, - apolloClient, - offChainRelayer, - onChainRelayer, - publicationCacheManager, - transactionFactory, - transactionGateway, - transactionQueue, - } = useSharedDependencies(); - - return async (request: CreatePostRequest) => { - validateCreatePostRequest(request); - - const uploader = PublicationMetadataUploader.create(upload); - const controller = new CreatePostController({ - activeWallet, - apolloClient, - offChainRelayer, - onChainRelayer, - publicationCacheManager, - transactionFactory, - transactionGateway, - transactionQueue, - uploader, - }); - - return controller.execute(request); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useFollowController.ts b/packages/react-v1/src/transactions/adapters/useFollowController.ts deleted file mode 100644 index 031ebc102c..0000000000 --- a/packages/react-v1/src/transactions/adapters/useFollowController.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - FollowProfiles, - FollowRequest, - UnconstrainedFollowRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { - BroadcastingError, - SignlessSubsidizeOnChain, - SubsidizeOnChain, -} from '@lens-protocol/domain/use-cases/transactions'; -import { - InsufficientAllowanceError, - InsufficientFundsError, -} from '@lens-protocol/domain/use-cases/wallets'; - -import { useSharedDependencies } from '../../shared'; -import { FollowProfilesGateway } from './FollowProfilesGateway'; -import { TransactionResultPresenter } from './TransactionResultPresenter'; - -export function useFollowController() { - const { - activeWallet, - apolloClient, - logger, - onChainRelayer, - tokenAvailability, - transactionFactory, - transactionGateway, - transactionQueue, - } = useSharedDependencies(); - - return async (request: FollowRequest) => { - const presenter = new TransactionResultPresenter< - FollowRequest, - | BroadcastingError - | InsufficientAllowanceError - | InsufficientFundsError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - >(); - - const followProfilesGateway = new FollowProfilesGateway( - apolloClient, - transactionFactory, - logger, - ); - - const signedFollow = new SubsidizeOnChain( - activeWallet, - transactionGateway, - followProfilesGateway, - onChainRelayer, - transactionQueue, - presenter, - ); - - const signlessFollow = new SignlessSubsidizeOnChain( - followProfilesGateway, - transactionQueue, - presenter, - ); - - const followProfiles = new FollowProfiles( - tokenAvailability, - signedFollow, - signlessFollow, - presenter, - ); - - void followProfiles.execute(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/usePayTransactionController.ts b/packages/react-v1/src/transactions/adapters/usePayTransactionController.ts deleted file mode 100644 index 0055e30605..0000000000 --- a/packages/react-v1/src/transactions/adapters/usePayTransactionController.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - InsufficientGasError, - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - AnyTransactionRequest, - PayTransaction, - ProtocolTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; - -import { useSharedDependencies } from '../../shared'; -import { SelfFundedProtocolCallGateway } from './SelfFundedProtocolCallGateway'; -import { SelfFundedProtocolTransactionRequest } from './SelfFundedProtocolTransactionRequest'; -import { TransactionResultPresenter } from './TransactionResultPresenter'; - -export function usePayTransactionController() { - const { activeWallet, providerFactory, transactionQueue } = useSharedDependencies(); - - return async (request: SelfFundedProtocolTransactionRequest) => { - const gateway = new SelfFundedProtocolCallGateway(providerFactory); - - const presenter = new TransactionResultPresenter< - AnyTransactionRequest, - InsufficientGasError | PendingSigningRequestError | WalletConnectionError | UserRejectedError - >(); - - const payTransaction = new PayTransaction(activeWallet, gateway, presenter, transactionQueue); - - await payTransaction.execute(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useUnfollowController.ts b/packages/react-v1/src/transactions/adapters/useUnfollowController.ts deleted file mode 100644 index 1855397096..0000000000 --- a/packages/react-v1/src/transactions/adapters/useUnfollowController.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { - PendingSigningRequestError, - WalletConnectionError, - UserRejectedError, -} from '@lens-protocol/domain/entities'; -import { UnfollowProfile, UnfollowRequest } from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; - -import { useSharedDependencies } from '../../shared'; -import { TransactionResultPresenter } from './TransactionResultPresenter'; -import { UnfollowProfileCallGateway } from './UnfollowProfileCallGateway'; - -export function useUnfollowController() { - const { activeWallet, apolloClient, transactionGateway, onChainRelayer, transactionQueue } = - useSharedDependencies(); - - return async (request: UnfollowRequest) => { - const presenter = new TransactionResultPresenter< - UnfollowRequest, - BroadcastingError | PendingSigningRequestError | WalletConnectionError | UserRejectedError - >(); - - const unfollowProfileCallGateway = new UnfollowProfileCallGateway(apolloClient); - - const unfollowProfiles = new UnfollowProfile( - activeWallet, - transactionGateway, - unfollowProfileCallGateway, - onChainRelayer, - transactionQueue, - presenter, - ); - - await unfollowProfiles.execute(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useUpdateDispatcherConfigController.ts b/packages/react-v1/src/transactions/adapters/useUpdateDispatcherConfigController.ts deleted file mode 100644 index 27d36842fc..0000000000 --- a/packages/react-v1/src/transactions/adapters/useUpdateDispatcherConfigController.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - UpdateDispatcherConfig, - UpdateDispatcherConfigRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; - -import { useSharedDependencies } from '../../shared'; -import { DispatcherConfigCallGateway } from './DispatcherConfigCallGateway'; -import { TransactionResultPresenter } from './TransactionResultPresenter'; - -export function useUpdateDispatcherConfigController() { - const { activeWallet, transactionGateway, onChainRelayer, transactionQueue, apolloClient } = - useSharedDependencies(); - - return async (request: UpdateDispatcherConfigRequest) => { - const presenter = new TransactionResultPresenter< - UpdateDispatcherConfigRequest, - BroadcastingError | PendingSigningRequestError | UserRejectedError | WalletConnectionError - >(); - const gateway = new DispatcherConfigCallGateway(apolloClient); - const updateDispatcherConfig = new UpdateDispatcherConfig( - activeWallet, - transactionGateway, - gateway, - onChainRelayer, - transactionQueue, - presenter, - ); - - await updateDispatcherConfig.execute(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useUpdateFollowPolicyController.ts b/packages/react-v1/src/transactions/adapters/useUpdateFollowPolicyController.ts deleted file mode 100644 index d1532522e8..0000000000 --- a/packages/react-v1/src/transactions/adapters/useUpdateFollowPolicyController.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - UpdateFollowPolicy, - UpdateFollowPolicyRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; - -import { useSharedDependencies } from '../../shared'; -import { TransactionResultPresenter } from './TransactionResultPresenter'; -import { validateUpdateFollowPolicyRequest } from './schemas/validators'; - -export function useUpdateFollowPolicyController() { - const { - activeWallet, - transactionGateway, - followPolicyCallGateway, - onChainRelayer, - transactionQueue, - } = useSharedDependencies(); - - return async (request: UpdateFollowPolicyRequest) => { - validateUpdateFollowPolicyRequest(request); - - const presenter = new TransactionResultPresenter< - UpdateFollowPolicyRequest, - BroadcastingError | PendingSigningRequestError | UserRejectedError | WalletConnectionError - >(); - const updateFollowPolicy = new UpdateFollowPolicy( - activeWallet, - transactionGateway, - followPolicyCallGateway, - onChainRelayer, - transactionQueue, - presenter, - ); - - await updateFollowPolicy.execute(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useUpdateProfileDetailsController.ts b/packages/react-v1/src/transactions/adapters/useUpdateProfileDetailsController.ts deleted file mode 100644 index 712aca5685..0000000000 --- a/packages/react-v1/src/transactions/adapters/useUpdateProfileDetailsController.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ProfileMetadata } from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - UpdateProfileDetails, - UpdateProfileDetailsRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError, SubsidizeOnChain } from '@lens-protocol/domain/use-cases/transactions'; - -import { useSharedDependencies } from '../../shared'; -import { MetadataUploaderErrorMiddleware } from '../infrastructure/MetadataUploaderErrorMiddleware'; -import { IMetadataUploader } from './IMetadataUploader'; -import { MetadataUploadHandler } from './MetadataUploadHandler'; -import { ProfileMetadataCallGateway } from './ProfileMetadataCallGateway'; -import { TransactionResultPresenter } from './TransactionResultPresenter'; -import { validateUpdateProfileDetailsRequest } from './schemas/validators'; - -export type UseUpdateProfileDetailsControllerArgs = { - upload: MetadataUploadHandler; -}; - -export function useUpdateProfileDetailsController({ - upload, -}: UseUpdateProfileDetailsControllerArgs) { - const { - activeWallet, - apolloClient, - mediaTransforms, - onChainRelayer, - transactionFactory, - transactionGateway, - transactionQueue, - } = useSharedDependencies(); - - return async (request: UpdateProfileDetailsRequest) => { - validateUpdateProfileDetailsRequest(request); - - const uploader: IMetadataUploader = new MetadataUploaderErrorMiddleware( - upload, - ); - const gateway = new ProfileMetadataCallGateway( - apolloClient, - transactionFactory, - uploader, - mediaTransforms, - ); - - const presenter = new TransactionResultPresenter< - UpdateProfileDetailsRequest, - BroadcastingError | PendingSigningRequestError | UserRejectedError | WalletConnectionError - >(); - - const signedUpdateProfiles = new SubsidizeOnChain( - activeWallet, - transactionGateway, - gateway, - onChainRelayer, - transactionQueue, - presenter, - ); - const updateProfileDetails = new UpdateProfileDetails( - signedUpdateProfiles, - gateway, - transactionQueue, - presenter, - ); - - await updateProfileDetails.execute(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/transactions/adapters/useUpdateProfileImageController.ts b/packages/react-v1/src/transactions/adapters/useUpdateProfileImageController.ts deleted file mode 100644 index ace38b33c1..0000000000 --- a/packages/react-v1/src/transactions/adapters/useUpdateProfileImageController.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - UpdateProfileImage, - UpdateProfileImageRequest, -} from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError, SubsidizeOnChain } from '@lens-protocol/domain/use-cases/transactions'; - -import { useSharedDependencies } from '../../shared'; -import { ProfileImageCallGateway } from './ProfileImageCallGateway'; -import { TransactionResultPresenter } from './TransactionResultPresenter'; - -export function useUpdateProfileImageController() { - const { - activeWallet, - apolloClient, - transactionGateway, - onChainRelayer, - transactionQueue, - transactionFactory, - } = useSharedDependencies(); - - return async (request: UpdateProfileImageRequest) => { - const profileImageCallGateway = new ProfileImageCallGateway(apolloClient, transactionFactory); - - const presenter = new TransactionResultPresenter< - UpdateProfileImageRequest, - BroadcastingError | PendingSigningRequestError | UserRejectedError | WalletConnectionError - >(); - - const signedUpdateProfileImage = new SubsidizeOnChain( - activeWallet, - transactionGateway, - profileImageCallGateway, - onChainRelayer, - transactionQueue, - presenter, - ); - - const updateProfileImage = new UpdateProfileImage( - signedUpdateProfileImage, - profileImageCallGateway, - transactionQueue, - presenter, - ); - - await updateProfileImage.execute(request); - - return presenter.asResult(); - }; -} diff --git a/packages/react-v1/src/transactions/index.ts b/packages/react-v1/src/transactions/index.ts deleted file mode 100644 index b1fff422e9..0000000000 --- a/packages/react-v1/src/transactions/index.ts +++ /dev/null @@ -1,124 +0,0 @@ -export * from './useApproveModule'; -export * from './useCollect'; -export * from './useCreateComment'; -export * from './useCreateEncryptedPost'; -export * from './useCreateEncryptedComment'; -export * from './useCreateMirror'; -export * from './useCreatePost'; -export * from './useFollow'; -export * from './useRecentPosts'; -export * from './useRecentTransactions'; -export * from './useSelfFundedFallback'; -export * from './useUnfollow'; -export * from './useUpdateDispatcherConfig'; -export * from './useUpdateFollowPolicy'; -export * from './useUpdateProfileDetails'; -export * from './useUpdateProfileImage'; -export * from './useClearRecentPosts'; - -/** - * Domain - */ -export { - TransactionError, - TransactionErrorReason, - TransactionKind, -} from '@lens-protocol/domain/entities'; -export type { - JustProtocolRequest, - PickByKind, - ProtocolTransactionKind, - ProtocolTransactionKinds, - Signature, -} from '@lens-protocol/domain/entities'; - -/** - * Request models - */ -export type { - AnyTransactionRequest, - ProtocolTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -export type { - CreateProfileRequest, - FollowRequest, - FollowRequestFee, - NftOwnershipSignature, - PaidFollowRequest, - PartialAttributesUpdate, - ProfileAttributeValue, - ProfileOwnerFollowRequest, - UnconstrainedFollowRequest, - UnfollowRequest, - UpdateDispatcherConfigRequest, - UpdateFollowPolicyRequest, - UpdateNftProfileImageRequest, - UpdateOffChainProfileImageRequest, - UpdateProfileDetailsRequest, - UpdateProfileImageRequest, -} from '@lens-protocol/domain/use-cases/profile'; -export type { TokenAllowanceRequest } from '@lens-protocol/domain/use-cases/wallets'; -export type { - AaveChargeCollectPolicyConfig, - AnyoneReferencePolicyConfig, - BaseCommentRequest, - BasePostRequest, - ChargeCollectPolicyConfig, - CollectablePolicyConfig, - CollectFee, - CollectPolicyConfig, - CollectRequest, - CreateCommentRequest, - CreateEmbedCommentRequest, - CreateEmbedPostRequest, - CreateMediaCommentRequest, - CreateMediaPostRequest, - CreateMirrorRequest, - CreatePostRequest, - CreateTextualCommentRequest, - CreateTextualPostRequest, - DegreesOfSeparationReferencePolicyConfig, - FollowersOnlyReferencePolicyConfig, - FreeCollectPolicyConfig, - FreeCollectRequest, - Locale, - MediaObject, - MultirecipientChargeCollectPolicyConfig, - MetadataAttribute, - NftMetadata, - NoCollectPolicyConfig, - PaidCollectRequest, - RecipientWithSplit, - ReferencePolicyConfig, - SimpleChargeCollectPolicyConfig, - SupportedPublicationMediaType, - VaultChargeCollectPolicyConfig, -} from '@lens-protocol/domain/use-cases/publications'; -export { - AudioType, - CollectPolicyType, - CollectType, - ContentFocus, - ContentWarning, - ImageType, - MetadataAttributeDisplayType, - ReferencePolicyType, - SupportedFileType, - VideoType, -} from '@lens-protocol/domain/use-cases/publications'; - -/** - * Domain errors - */ -export { - InsufficientAllowanceError, - InsufficientFundsError, -} from '@lens-protocol/domain/use-cases/wallets'; - -/** - * Helpers - */ -export type { TransactionData } from '@lens-protocol/domain/use-cases/transactions'; -export type { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -export type { MetadataUploadHandler } from './adapters/MetadataUploadHandler'; -export { FailedUploadError } from './adapters/IMetadataUploader'; diff --git a/packages/react-v1/src/transactions/infrastructure/AccessConditionBuilderFactory.ts b/packages/react-v1/src/transactions/infrastructure/AccessConditionBuilderFactory.ts deleted file mode 100644 index 1ee0c11786..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/AccessConditionBuilderFactory.ts +++ /dev/null @@ -1,201 +0,0 @@ -import { - AccessCondition, - AndCondition, - AnyCondition, - ContractType, - LeafCondition, - OrCondition, - ScalarOperator, -} from '@lens-protocol/api-bindings'; -import { - AnyCriterion, - DecryptionCriteria, - DecryptionCriteriaType, - Erc20ComparisonOperator, - NftContractType, - ProfileId, - PublicationId, - SimpleCriterion, -} from '@lens-protocol/domain/entities'; -import { assertNever, invariant } from '@lens-protocol/shared-kernel'; - -import { ChainConfigRegistry } from '../../chains'; - -function toContractType(contractType: NftContractType): ContractType { - switch (contractType) { - case NftContractType.Erc721: - return ContractType.Erc721; - case NftContractType.Erc1155: - return ContractType.Erc1155; - } -} - -function toScalarOperator(operator: Erc20ComparisonOperator): ScalarOperator { - switch (operator) { - case Erc20ComparisonOperator.GreaterThan: - return ScalarOperator.GreaterThan; - case Erc20ComparisonOperator.GreaterThanOrEqual: - return ScalarOperator.GreaterThanOrEqual; - case Erc20ComparisonOperator.LessThan: - return ScalarOperator.LessThan; - case Erc20ComparisonOperator.LessThanOrEqual: - return ScalarOperator.LessThanOrEqual; - case Erc20ComparisonOperator.Equal: - return ScalarOperator.Equal; - case Erc20ComparisonOperator.NotEqual: - return ScalarOperator.NotEqual; - } - // fail fast if type checking is bypassed (JS integration or brute-forced TS assertion) - assertNever(operator, 'Unknown Erc20ComparisonOperator'); -} - -async function or(criteria: Promise[]): Promise> { - invariant( - criteria.length > 1, - `"${DecryptionCriteriaType.OR}" criteria must have at least 2 elements`, - ); - invariant( - criteria.length <= 5, - `"${DecryptionCriteriaType.OR}" criteria must have at most 5 elements`, - ); - return { - or: { - criteria: await Promise.all(criteria), - }, - }; -} - -async function and(criteria: Promise[]): Promise> { - invariant( - criteria.length > 1, - `"${DecryptionCriteriaType.AND}" criteria must have at least 2 elements`, - ); - invariant( - criteria.length <= 5, - `"${DecryptionCriteriaType.AND}" criteria must have at most 5 elements`, - ); - return { - and: { - criteria: await Promise.all(criteria), - }, - }; -} - -class AccessConditionBuilder { - constructor( - private readonly ownerId: ProfileId, - private readonly chains: ChainConfigRegistry, - private readonly publicationIdPredictor: IPublicationIdPredictor, - ) {} - - withDecryptionCriteria(decryptionCriteria: DecryptionCriteria) { - return { - build: async (): Promise => { - return { - or: { - criteria: [ - await this.transformSimpleCriterion({ - type: DecryptionCriteriaType.PROFILE_OWNERSHIP, - profileId: this.ownerId, - }), - await this.transformAnyCriterion(decryptionCriteria), - ], - }, - }; - }, - }; - } - - private async transformAnyCriterion( - criterion: AnyCriterion, - ): Promise { - switch (criterion.type) { - case DecryptionCriteriaType.AND: - return and(criterion.and.map((c) => this.transformSimpleCriterion(c))); - - case DecryptionCriteriaType.OR: - return or(criterion.or.map((c) => this.transformSimpleCriterion(c))); - } - return this.transformSimpleCriterion(criterion); - } - - private async transformSimpleCriterion(criterion: SimpleCriterion): Promise { - switch (criterion.type) { - case DecryptionCriteriaType.NFT_OWNERSHIP: - return { - nft: { - chainID: criterion.chainId, - contractAddress: criterion.contractAddress, - contractType: toContractType(criterion.contractType), - tokenIds: criterion.tokenIds ?? null, - }, - }; - case DecryptionCriteriaType.ERC20_OWNERSHIP: - return { - token: { - amount: criterion.amount - .toBigDecimal() - .mul(10 ** criterion.amount.asset.decimals) - .toFixed(), - chainID: this.chains[criterion.amount.asset.chainType].chainId, - contractAddress: criterion.amount.asset.address, - decimals: criterion.amount.asset.decimals, - condition: toScalarOperator(criterion.condition), - }, - }; - case DecryptionCriteriaType.ADDRESS_OWNERSHIP: - return { - eoa: { - address: criterion.address, - }, - }; - case DecryptionCriteriaType.PROFILE_OWNERSHIP: - return { - profile: { - profileId: criterion.profileId, - }, - }; - case DecryptionCriteriaType.FOLLOW_PROFILE: - return { - follow: { - profileId: criterion.profileId, - }, - }; - - case DecryptionCriteriaType.COLLECT_PUBLICATION: - return { - collect: { - publicationId: criterion.publicationId, - thisPublication: false, - }, - }; - - case DecryptionCriteriaType.COLLECT_THIS_PUBLICATION: - return { - collect: { - publicationId: await this.publicationIdPredictor.predictNextPublicationIdFor( - this.ownerId, - ), - thisPublication: true, - }, - }; - } - // fail fast if type checking is bypassed (JS integration or brute-forced TS assertion) - assertNever(criterion, 'Unknown DecryptionCriteriaType'); - } -} - -export interface IPublicationIdPredictor { - predictNextPublicationIdFor(profileId: ProfileId): Promise; -} - -export class AccessConditionBuilderFactory { - constructor( - private readonly chains: ChainConfigRegistry, - private readonly publicationIdPredictor: IPublicationIdPredictor, - ) {} - - createForPublicationBy(ownerId: ProfileId) { - return new AccessConditionBuilder(ownerId, this.chains, this.publicationIdPredictor); - } -} diff --git a/packages/react-v1/src/transactions/infrastructure/Eip1559GasPriceEstimator.ts b/packages/react-v1/src/transactions/infrastructure/Eip1559GasPriceEstimator.ts deleted file mode 100644 index 1a6132fa0e..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/Eip1559GasPriceEstimator.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { FeeHistoryResult } from '@lens-protocol/blockchain-bindings'; -import { - Amount, - BigDecimal, - CryptoNativeAsset, - Denomination, - never, -} from '@lens-protocol/shared-kernel'; -import { providers } from 'ethers'; - -export class Eip1559GasPriceEstimate { - constructor(readonly baseFee: Amount, readonly maxPriorityFeePerGas: Amount) {} - - get maxFeePerGas() { - // Heuristic logic based on https://www.blocknative.com/blog/eip-1559-fees - // > maxFeePerGas = (2 * baseFee) + maxPriorityFeePerGas - // Despite ethers.js uses an hardcoded value for maxPriorityFeePerGas they - // use the same exact logic to compute maxFeePerGas. - // see: https://github.com/ethers-io/ethers.js/blob/7175e2e99c2747e8d2314feb407bf0a0f9371ece/packages/abstract-provider/src.ts/index.ts#L247 - return this.baseFee.mul(2).add(this.maxPriorityFeePerGas); - } - - get estimatedGasPrice() { - return this.baseFee.add(this.maxPriorityFeePerGas); - } -} - -export enum TransactionExecutionSpeed { - FAST = 'fast', - AVERAGE = 'average', - SLOW = 'slow', -} - -const BLOCK_COUNT = 20; - -const LOWER_PERCENTILE = 1; -const MEAN_PERCENTILE = 50; -const HIGHER_PERCENTILE = 99; -const REWARD_PERCENTILES = [LOWER_PERCENTILE, MEAN_PERCENTILE, HIGHER_PERCENTILE] as const; - -const NEWEST_BLOCK = 'pending'; - -function computeFeeHistoryStats(result: FeeHistoryResult) { - const oldestBlock = Number(result.oldestBlock); - let blockNum = oldestBlock; - let index = 0; - const blocks = []; - while (blockNum < oldestBlock + BLOCK_COUNT) { - blocks.push({ - number: blockNum, - baseFeePerGas: BigDecimal.from( - result.baseFeePerGas[index] ?? never(`Cannot find baseFeePerGas for block ${blockNum}`), - ), - priorityFeePerGas: ( - result.reward[index] ?? never(`Cannot find reward for block ${blockNum}`) - ).map((x) => BigDecimal.from(x)), - }); - blockNum += 1; - index += 1; - } - - return { - blocks, - baseFee: (blocks[blocks.length - 1] ?? never('Cannot index last block')).baseFeePerGas, - }; -} - -type FeeHistoryStats = ReturnType; -type BlockStats = FeeHistoryStats['blocks'][0]; - -const transactionSpeedToPercentileIndex: Record = { - [TransactionExecutionSpeed.SLOW]: REWARD_PERCENTILES.indexOf(LOWER_PERCENTILE), - [TransactionExecutionSpeed.AVERAGE]: REWARD_PERCENTILES.indexOf(MEAN_PERCENTILE), - [TransactionExecutionSpeed.FAST]: REWARD_PERCENTILES.indexOf(HIGHER_PERCENTILE), -}; - -function computeMaxPriorityFeePerGas(blocks: BlockStats[], speed: TransactionExecutionSpeed) { - // TODO: set min to 2 Gwei - const index = transactionSpeedToPercentileIndex[speed]; - return BigDecimal.mean( - blocks.map( - (b) => - b.priorityFeePerGas[index] ?? - never('Cannot find priorityFeePerGas for the specified transactions execution speed'), - ), - ); -} - -export type CryptoNativeAmountFactory = ( - value: BigDecimal, -) => Amount; - -export class Eip1559GasPriceEstimator { - constructor( - private readonly provider: providers.JsonRpcProvider, - private readonly createAmount: CryptoNativeAmountFactory, - ) {} - - async estimate(speed: TransactionExecutionSpeed) { - const { blocks, baseFee } = await this.fetchFeeHistoryStats(); - - const maxPriorityFeePerGas = computeMaxPriorityFeePerGas(blocks, speed); - - return new Eip1559GasPriceEstimate( - this.createAmount(Denomination.wei(baseFee)), - this.createAmount(Denomination.wei(maxPriorityFeePerGas)), - ); - } - - private async fetchFeeHistoryStats() { - const response = (await this.provider.send('eth_feeHistory', [ - BLOCK_COUNT, - NEWEST_BLOCK, - REWARD_PERCENTILES, - ])) as FeeHistoryResult; - - return computeFeeHistoryStats(response); - } -} diff --git a/packages/react-v1/src/transactions/infrastructure/EncryptedPublicationMetadataUploader.ts b/packages/react-v1/src/transactions/infrastructure/EncryptedPublicationMetadataUploader.ts deleted file mode 100644 index 67d18c6c22..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/EncryptedPublicationMetadataUploader.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { PublicationMetadata } from '@lens-protocol/api-bindings'; -import { DecryptionCriteria } from '@lens-protocol/domain/entities'; -import { - CreateCommentRequest, - CreatePostRequest, -} from '@lens-protocol/domain/use-cases/publications'; -import { GatedClient } from '@lens-protocol/gated-content'; -import { Overwrite, Prettify } from '@lens-protocol/shared-kernel'; - -import { IMetadataUploader } from '../adapters/IMetadataUploader'; -import { MetadataUploadHandler } from '../adapters/MetadataUploadHandler'; -import { AccessConditionBuilderFactory } from './AccessConditionBuilderFactory'; -import { MetadataUploaderErrorMiddleware } from './MetadataUploaderErrorMiddleware'; -import { createPublicationMetadata } from './createPublicationMetadata'; - -type WithDecryptionCriteria = Prettify< - Overwrite< - T, - { - decryptionCriteria: DecryptionCriteria; - } - > ->; - -export type CreateEncryptedPostRequest = WithDecryptionCriteria; - -export type CreateEncryptedCommentRequest = WithDecryptionCriteria; - -export class EncryptedPublicationMetadataUploader< - T extends WithDecryptionCriteria< - CreatePostRequest | CreateCommentRequest - > = WithDecryptionCriteria, -> implements IMetadataUploader -{ - private constructor( - private readonly client: GatedClient, - private readonly accessConditionBuilderFactory: AccessConditionBuilderFactory, - private readonly uploader: IMetadataUploader, - ) {} - - async upload(request: T): Promise { - const accessCondition = await this.accessConditionBuilderFactory - .createForPublicationBy(request.profileId) - .withDecryptionCriteria(request.decryptionCriteria) - .build(); - - const metadata = createPublicationMetadata(request); - - const result = await this.client.encryptPublication(metadata, accessCondition); - - const encryptedMetadata = result.unwrap(); - - return this.uploader.upload(encryptedMetadata); - } - - static create( - client: GatedClient, - accessConditionBuilderFactory: AccessConditionBuilderFactory, - upload: MetadataUploadHandler, - ) { - return new EncryptedPublicationMetadataUploader( - client, - accessConditionBuilderFactory, - new MetadataUploaderErrorMiddleware(upload), - ); - } -} diff --git a/packages/react-v1/src/transactions/infrastructure/MetadataUploaderErrorMiddleware.ts b/packages/react-v1/src/transactions/infrastructure/MetadataUploaderErrorMiddleware.ts deleted file mode 100644 index 234767a67d..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/MetadataUploaderErrorMiddleware.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Url, assertError, invariant } from '@lens-protocol/shared-kernel'; - -import { FailedUploadError, IMetadataUploader } from '../adapters/IMetadataUploader'; -import { MetadataUploadHandler } from '../adapters/MetadataUploadHandler'; - -const validUrlRegex = /^[a-z]+:\/\/.+$/; - -function isValidUrl(url: string): url is Url { - return validUrlRegex.test(url); -} - -export class MetadataUploaderErrorMiddleware implements IMetadataUploader { - constructor(readonly handler: MetadataUploadHandler) {} - - async upload(data: T): Promise { - const url = await this.attemptToUpload(data); - - invariant( - isValidUrl(url), - `Invalid upload url provided: ${url}\n\n` + - ` Some examples of valid URLs are:\n` + - ` - https://www.example.com/foobar\n` + - ` - ipfs://QmXoypizjW3W\n` + - ` - ar://f2dLOlSJgW-RsofpQ10JDth\n\n` + - ` Check the the return statement of the "upload" function you provided`, - ); - - return url; - } - - private async attemptToUpload(data: T): Promise { - try { - return await this.handler(data); - } catch (err: unknown) { - assertError(err); - - throw new FailedUploadError('Cannot upload metadata', { cause: err }); - } - } -} diff --git a/packages/react-v1/src/transactions/infrastructure/ProfileCacheManager.ts b/packages/react-v1/src/transactions/infrastructure/ProfileCacheManager.ts deleted file mode 100644 index 4fdc02edbe..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/ProfileCacheManager.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { FetchPolicy } from '@apollo/client'; -import { - FragmentProfile, - GetProfileData, - GetProfileDocument, - GetProfileVariables, - getSession, - Profile, - SafeApolloClient, - SessionType, - Sources, -} from '@lens-protocol/api-bindings'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { invariant, never, XOR } from '@lens-protocol/shared-kernel'; - -import { ProfileHandleResolver } from '../../environments'; -import { mediaTransformConfigToQueryVariables, MediaTransformsConfig } from '../../mediaTransforms'; -import { IProfileCacheManager } from '../adapters/IProfileCacheManager'; - -type RequestProfileArgs = XOR< - { - handle: string; - }, - { - id: ProfileId; - } ->; - -export class ProfileCacheManager implements IProfileCacheManager { - constructor( - private readonly client: SafeApolloClient, - private readonly sources: Sources, - private readonly mediaTransforms: MediaTransformsConfig, - private readonly handleResolver: ProfileHandleResolver, - ) {} - - async fetchProfile(id: ProfileId) { - return this.request({ id }, 'cache-first'); - } - - async fetchNewProfile(handlePrefix: string) { - const handle = this.handleResolver(handlePrefix); - const profile = await this.request( - { handle: this.handleResolver(handlePrefix) }, - 'network-only', - ); - - invariant(profile, `Profile "@${handle}" not found`); - - return profile; - } - - async refreshProfile(id: ProfileId) { - const profile = await this.request({ id }, 'network-only'); - - return profile ?? never(); - } - - private async request(args: RequestProfileArgs, fetchPolicy: FetchPolicy) { - const session = getSession(); - - const { data } = await this.client.query({ - query: GetProfileDocument, - variables: { - request: args.id - ? { - profileId: args.id, - } - : { - handle: args.handle, - }, - observerId: session?.type === SessionType.WithProfile ? session.profile.id : null, - sources: this.sources, - ...mediaTransformConfigToQueryVariables(this.mediaTransforms), - }, - fetchPolicy, - }); - - return data.result; - } - - updateProfile(id: string, updateFn: (current: Profile) => Profile): void { - const identifier = - this.client.cache.identify({ __typename: 'Profile', id }) ?? - never('Profile identifier not found'); - - const profile = this.client.cache.readFragment({ - id: identifier, - fragmentName: 'Profile', - fragment: FragmentProfile, - }); - - if (profile) { - const updated = updateFn(profile); - - this.client.cache.writeFragment({ - id: identifier, - fragmentName: 'Profile', - fragment: FragmentProfile, - data: updated, - }); - } - } -} diff --git a/packages/react-v1/src/transactions/infrastructure/PublicationIdPredictor.ts b/packages/react-v1/src/transactions/infrastructure/PublicationIdPredictor.ts deleted file mode 100644 index ab4a692ce6..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/PublicationIdPredictor.ts +++ /dev/null @@ -1,77 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ -import { - SafeApolloClient, - GetPublicationsDocument, - GetPublicationsData, - GetPublicationsVariables, -} from '@lens-protocol/api-bindings'; -import { ProfileId, PublicationId, TransactionKind } from '@lens-protocol/domain/entities'; -import { hasAtLeastOne, never } from '@lens-protocol/shared-kernel'; - -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../mediaTransforms'; -import { publicationId } from '../../utils'; -import { PendingTransactionGateway } from '../adapters/PendingTransactionGateway'; -import { IPublicationIdPredictor } from './AccessConditionBuilderFactory'; - -function formatPublicationId(profileId: ProfileId, newSequentialId: number): PublicationId { - return publicationId(`${profileId}-0x${newSequentialId.toString(16)}`); -} - -export class PublicationIdPredictor implements IPublicationIdPredictor { - constructor( - private readonly apolloClient: SafeApolloClient, - private readonly pendingTransactionGateway: PendingTransactionGateway, - ) {} - - async predictNextPublicationIdFor(profileId: ProfileId): Promise { - const { data } = await this.apolloClient.query({ - query: GetPublicationsDocument, - variables: { - profileId, - sources: [], - limit: 1, - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - }); - - if (hasAtLeastOne(data.result.items)) { - const { id } = data.result.items[0]; - const onchainId = - id.split('-').pop() ?? - never(`Publication id is not in the expected "-" format: ${id}`); - - const last = parseInt(onchainId, 16); - return formatPublicationId(profileId, await this.computeNextSequentialIdFor(last, profileId)); - } - - return formatPublicationId(profileId, await this.computeNextSequentialIdFor(0, profileId)); - } - - private async computeNextSequentialIdFor( - baseline: number, - profileId: ProfileId, - ): Promise { - const pendingPublicationTransactions = await this.countPendingPublicationTransactionsFor( - profileId, - ); - return baseline + pendingPublicationTransactions + 1; - } - - private async countPendingPublicationTransactionsFor(profileId: ProfileId): Promise { - const allPendingTransactions = await this.pendingTransactionGateway.getAll(); - const pendingPublicationTransactions = allPendingTransactions.filter((transaction) => { - switch (transaction.request.kind) { - case TransactionKind.CREATE_COMMENT: - case TransactionKind.CREATE_POST: - case TransactionKind.MIRROR_PUBLICATION: - return transaction.request.profileId === profileId; - } - return false; - }); - - return pendingPublicationTransactions.length; - } -} diff --git a/packages/react-v1/src/transactions/infrastructure/PublicationMetadataUploader.ts b/packages/react-v1/src/transactions/infrastructure/PublicationMetadataUploader.ts deleted file mode 100644 index 0b2aec0fa2..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/PublicationMetadataUploader.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { PublicationMetadata } from '@lens-protocol/api-bindings'; -import { - CreateCommentRequest, - CreatePostRequest, -} from '@lens-protocol/domain/use-cases/publications'; -import { Url } from '@lens-protocol/shared-kernel'; - -import { IMetadataUploader } from '../adapters/IMetadataUploader'; -import { MetadataUploadHandler } from '../adapters/MetadataUploadHandler'; -import { MetadataUploaderErrorMiddleware } from './MetadataUploaderErrorMiddleware'; -import { createPublicationMetadata } from './createPublicationMetadata'; - -export class PublicationMetadataUploader - implements IMetadataUploader -{ - private constructor(private readonly uploader: IMetadataUploader) {} - - async upload(request: T): Promise { - const metadata = createPublicationMetadata(request); - - return this.uploader.upload(metadata); - } - - static create(handler: MetadataUploadHandler) { - return new PublicationMetadataUploader(new MetadataUploaderErrorMiddleware(handler)); - } -} diff --git a/packages/react-v1/src/transactions/infrastructure/TransactionFactory.ts b/packages/react-v1/src/transactions/infrastructure/TransactionFactory.ts deleted file mode 100644 index 0c68af8130..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/TransactionFactory.ts +++ /dev/null @@ -1,451 +0,0 @@ -import { - DataTransaction, - MetaTransaction, - NativeTransaction, - Nonce, - ProtocolTransactionKinds, - ProxyActionStatus, - ProxyTransaction, - TransactionError, - TransactionEvent, - TransactionKind, -} from '@lens-protocol/domain/entities'; -import { - ProtocolTransactionRequest, - AnyTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { ChainType, failure, PromiseResult, success, XOR } from '@lens-protocol/shared-kernel'; - -import { - DataTransactionData, - MetaTransactionData, - NativeTransactionData, - ProxyTransactionData, -} from '../adapters/ITransactionFactory'; -import { - ISerializableMetaTransaction, - ISerializableNativeTransaction, - ISerializableProxyTransaction, - ISerializableTransactionFactory, -} from '../adapters/PendingTransactionGateway'; -import { ISerializableDataTransaction } from '../adapters/PendingTransactionGateway/ISerializableTransactionFactory'; - -export type IndexingEvent = { - indexed: boolean; - txHash: string; -}; - -export type ProxyActionStatusEvent = { - txHash: string; - status: ProxyActionStatus; -}; - -export type ConfirmationRequest = { - txHash: string; - chainType: ChainType; -}; - -export type IndexingEventRequest = XOR<{ txHash: string }, { indexingId: string }>; - -export interface ITransactionObserver { - waitForConfirmation(request: ConfirmationRequest): PromiseResult; - - waitForNextIndexingEvent( - request: IndexingEventRequest, - ): PromiseResult; - - waitForProxyTransactionStatus( - proxyId: string, - ): PromiseResult; -} - -type StateUpdate = { - event: TransactionEvent; - state: T; -}; - -type StateReducer = (state: T) => PromiseResult, TransactionError>; - -type MetaTransactionState = { - chainType: ChainType; - id: string; - indexingId: string; - nonce: Nonce; - request: T; - txHash: string; -}; - -class SerializableMetaTransaction - extends MetaTransaction - implements ISerializableMetaTransaction -{ - constructor( - private state: MetaTransactionState, - private readonly reduce: StateReducer>, - ) { - super(); - } - - toTransactionData(): MetaTransactionData { - return { - chainType: this.state.chainType, - id: this.state.id, - indexingId: this.state.indexingId, - nonce: this.state.nonce, - request: this.state.request, - txHash: this.state.txHash, - }; - } - - get chainType(): ChainType { - return this.state.chainType; - } - - get id(): string { - return this.state.id; - } - - get request(): T { - return this.state.request; - } - - get nonce(): Nonce { - return this.state.nonce; - } - - get hash(): string { - return this.state.txHash; - } - - async waitNextEvent(): PromiseResult { - const result = await this.reduce(this.state); - - if (result.isSuccess()) { - this.state = result.value.state; - return success(result.value.event); - } - return failure(result.error); - } -} - -type ProxyTransactionState = { - chainType: ChainType; - id: string; - proxyId: string; - request: T; - txHash?: string; - status?: ProxyActionStatus; -}; - -class SerializableProxyTransaction - extends ProxyTransaction - implements ISerializableProxyTransaction -{ - constructor( - private state: ProxyTransactionState, - private readonly reduce: StateReducer>, - ) { - super(); - } - - toTransactionData(): ProxyTransactionData { - return { - chainType: this.state.chainType, - id: this.state.id, - proxyId: this.state.proxyId, - request: this.state.request, - txHash: this.state.txHash, - status: this.state.status, - }; - } - - get chainType(): ChainType { - return this.state.chainType; - } - - get id(): string { - return this.state.id; - } - - get request(): T { - return this.state.request; - } - - get hash(): string | undefined { - return this.state.txHash; - } - - get status(): ProxyActionStatus | undefined { - return this.state.status; - } - - async waitNextEvent(): PromiseResult { - const result = await this.reduce(this.state); - - if (result.isSuccess()) { - this.state = result.value.state; - return success(result.value.event); - } - return failure(result.error); - } -} - -type NativeTransactionState = { - chainType: ChainType; - id: string; - indexingId?: string; - request: T; - txHash: string; -}; - -class SerializableNativeTransaction - extends NativeTransaction - implements ISerializableNativeTransaction -{ - constructor( - private state: NativeTransactionState, - private readonly reduce: StateReducer>, - ) { - super(); - } - - toTransactionData(): NativeTransactionData { - return { - chainType: this.state.chainType, - id: this.state.id, - indexingId: this.state.indexingId, - request: this.state.request, - txHash: this.state.txHash, - }; - } - - get nonce(): number { - throw new Error('Method not implemented.'); - } - - get chainType(): ChainType { - return this.state.chainType; - } - - get id(): string { - return this.state.id; - } - - get request(): T { - return this.state.request; - } - - get hash(): string { - return this.state?.txHash; - } - - async waitNextEvent(): PromiseResult { - const result = await this.reduce(this.state); - - if (result.isSuccess()) { - this.state = result.value.state; - return success(result.value.event); - } - return failure(result.error); - } -} - -class SerializableDataTransaction - extends DataTransaction - implements ISerializableDataTransaction -{ - constructor(readonly id: string, readonly request: T) { - super(); - } - - async waitNextEvent(): PromiseResult { - return success(TransactionEvent.SETTLED); - } - - toTransactionData(): DataTransactionData { - return { - id: this.id, - request: this.request, - }; - } -} - -export class TransactionFactory implements ISerializableTransactionFactory { - constructor(private readonly transactionObserver: ITransactionObserver) {} - - createMetaTransaction(init: MetaTransactionData) { - return new SerializableMetaTransaction( - { - chainType: init.chainType, - id: init.id, - indexingId: init.indexingId, - nonce: init.nonce, - request: init.request, - txHash: init.txHash, - }, - this.createProtocolCallStateReducer(), - ); - } - - createNativeTransaction(init: NativeTransactionData) { - if (init.indexingId) { - return new SerializableNativeTransaction( - { - chainType: init.chainType, - id: init.id, - indexingId: init.indexingId, - request: init.request, - txHash: init.txHash, - }, - this.createProtocolCallStateReducer(), - ); - } - - if ((ProtocolTransactionKinds as ReadonlyArray).includes(init.request.kind)) { - return new SerializableNativeTransaction( - { - chainType: init.chainType, - id: init.id, - request: init.request, - txHash: init.txHash, - }, - this.createProtocolCallStateReducer(), - ); - } - return new SerializableNativeTransaction( - { - chainType: init.chainType, - id: init.id, - request: init.request, - txHash: init.txHash, - }, - this.createPureBlockchainStateReducer(), - ); - } - - createProxyTransaction( - init: ProxyTransactionData, - ): ISerializableProxyTransaction { - return new SerializableProxyTransaction( - { - chainType: init.chainType, - id: init.id, - proxyId: init.proxyId, - request: init.request, - txHash: init.txHash, - status: init.status, - }, - this.createProxyActionStateReducer(), - ); - } - - createDataTransaction( - init: DataTransactionData, - ): ISerializableDataTransaction { - return new SerializableDataTransaction(init.id, init.request); - } - - private createProtocolCallStateReducer< - T extends AnyTransactionRequest, - S extends MetaTransactionState | NativeTransactionState, - >(): StateReducer { - return async (state) => { - const request = state.indexingId - ? { indexingId: state.indexingId } - : { txHash: state.txHash }; - - const indexingEventResult = await this.transactionObserver.waitForNextIndexingEvent(request); - - if (indexingEventResult.isFailure()) { - return failure(indexingEventResult.error); - } - - if (indexingEventResult.value.indexed) { - return success({ - event: TransactionEvent.SETTLED, - state: { - ...state, - txHash: indexingEventResult.value.txHash, - }, - }); - } - return success({ - event: TransactionEvent.UPGRADED, - state: { - ...state, - txHash: indexingEventResult.value.txHash, - }, - }); - }; - } - - private createPureBlockchainStateReducer< - T extends AnyTransactionRequest, - S extends NativeTransactionState, - >(): StateReducer { - return async (state) => { - const result = await this.transactionObserver.waitForConfirmation({ - txHash: state.txHash, - chainType: state.chainType, - }); - - if (result.isFailure()) { - return failure(result.error); - } - - return success({ - event: TransactionEvent.SETTLED, - state, - }); - }; - } - - private createProxyActionStateReducer< - T extends AnyTransactionRequest, - S extends ProxyTransactionState, - >(): StateReducer { - return async (state) => { - const result = await this.transactionObserver.waitForProxyTransactionStatus(state.proxyId); - - if (result.isFailure()) { - return failure(result.error); - } - - switch (result.value.status) { - case ProxyActionStatus.MINTING: - return success({ - event: - state.status === ProxyActionStatus.MINTING - ? TransactionEvent.UPGRADED - : TransactionEvent.BROADCASTED, - state: { - ...state, - status: ProxyActionStatus.MINTING, - txHash: result.value.txHash, - }, - }); - case ProxyActionStatus.TRANSFERRING: - return success({ - event: - state.status === ProxyActionStatus.TRANSFERRING - ? TransactionEvent.UPGRADED - : TransactionEvent.BROADCASTED, - state: { - ...state, - status: ProxyActionStatus.TRANSFERRING, - txHash: result.value.txHash, - }, - }); - case ProxyActionStatus.COMPLETE: - return success({ - event: TransactionEvent.SETTLED, - state: { - ...state, - status: ProxyActionStatus.COMPLETE, - txHash: result.value.txHash, - }, - }); - } - }; - } -} diff --git a/packages/react-v1/src/transactions/infrastructure/TransactionObserver.ts b/packages/react-v1/src/transactions/infrastructure/TransactionObserver.ts deleted file mode 100644 index 495bf22789..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/TransactionObserver.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { - HasTxHashBeenIndexedDocument, - HasTxHashBeenIndexedData, - HasTxHashBeenIndexedVariables, - SafeApolloClient, - ProxyActionStatusDocument, - ProxyActionStatusData, - ProxyActionStatusVariables, - ProxyActionStatusTypes, - TransactionErrorReasons, -} from '@lens-protocol/api-bindings'; -import { - ProxyActionStatus, - TransactionError, - TransactionErrorReason, -} from '@lens-protocol/domain/entities'; -import { failure, PromiseResult, Result, success } from '@lens-protocol/shared-kernel'; - -import { IProviderFactory } from '../../wallet/adapters/IProviderFactory'; -import { - ConfirmationRequest, - IndexingEvent, - IndexingEventRequest, - ITransactionObserver, - ProxyActionStatusEvent, -} from './TransactionFactory'; - -const ONE_SECOND = 1000; // ms - -/** - * The transaction observer timings - * - * @internal - */ -export type TransactionObserverTimings = { - pollingInterval: number; // ms // TODO move this definition closer to EnvironmentConfig, not used by TransactionObserver - maxMiningWaitTime: number; // ms - maxIndexingWaitTime: number; // ms -}; - -function delay(waitInMs: number) { - return new Promise((resolve) => setTimeout(resolve, waitInMs)); -} - -function resolveTransactionErrorReason(reason: TransactionErrorReasons) { - switch (reason) { - case TransactionErrorReasons.Reverted: - return TransactionErrorReason.REVERTED; - default: - return TransactionErrorReason.UNKNOWN; - } -} - -export class TransactionObserver implements ITransactionObserver { - constructor( - private readonly providerFactory: IProviderFactory, - private readonly apolloClient: SafeApolloClient, - private readonly timings: TransactionObserverTimings, - ) {} - - async waitForConfirmation(request: ConfirmationRequest): PromiseResult { - const provider = await this.providerFactory.createProvider({ chainType: request.chainType }); - const startedAt = Date.now(); - - while (Date.now() - startedAt <= this.timings.maxMiningWaitTime) { - const txResponse = await provider.getTransaction(request.txHash); - - if (txResponse === null) { - await delay(ONE_SECOND); - continue; - } - try { - await Promise.race([ - txResponse.wait(1), - - delay(this.timings.maxMiningWaitTime).then(() => { - throw new TransactionError(TransactionErrorReason.MINING_TIMEOUT); - }), - ]); - return success(); - } catch (e) { - if (e instanceof TransactionError) { - return failure(e); - } - throw e; - } - } - return failure(new TransactionError(TransactionErrorReason.MINING_TIMEOUT)); - } - - async waitForNextIndexingEvent( - request: IndexingEventRequest, - ): PromiseResult { - const startedAt = Date.now(); - const observable = this.apolloClient.poll< - HasTxHashBeenIndexedData, - HasTxHashBeenIndexedVariables - >({ - query: HasTxHashBeenIndexedDocument, - variables: { - request: request.indexingId - ? { - txId: request.indexingId, - } - : { - txHash: request.txHash, - }, - }, - }); - let previousTxHash: string | null = null; - - return new Promise>((resolve, reject) => { - const subscription = observable.subscribe({ - next: async ({ result }) => { - switch (result.__typename) { - case 'TransactionIndexedResult': - if (previousTxHash === null) { - previousTxHash = result.txHash; - } - - if (previousTxHash !== result.txHash || result.indexed) { - subscription.unsubscribe(); - resolve( - success({ - indexed: result.indexed, - txHash: result.txHash, - }), - ); - return; - } - break; - - case 'TransactionError': - subscription.unsubscribe(); - resolve(failure(new TransactionError(resolveTransactionErrorReason(result.reason)))); - } - - if (Date.now() - startedAt > this.timings.maxIndexingWaitTime) { - subscription.unsubscribe(); - - resolve(failure(new TransactionError(TransactionErrorReason.INDEXING_TIMEOUT))); - } - }, - error: reject, - }); - }); - } - - async waitForProxyTransactionStatus( - proxyId: string, - ): PromiseResult { - const startedAt = Date.now(); - const observable = this.apolloClient.poll({ - query: ProxyActionStatusDocument, - variables: { proxyActionId: proxyId }, - }); - let previousTxHash: string | null = null; - - return new Promise>((resolve, reject) => { - const subscription = observable.subscribe({ - next: async ({ result }) => { - switch (result.__typename) { - case 'ProxyActionStatusResult': - if (previousTxHash === null) { - previousTxHash = result.txHash; - } - - if ( - previousTxHash !== result.txHash || - result.status === ProxyActionStatusTypes.Complete - ) { - subscription.unsubscribe(); - resolve( - success({ - txHash: result.txHash, - status: ProxyActionStatus.COMPLETE, - }), - ); - return; - } - break; - - case 'ProxyActionError': - subscription.unsubscribe(); - resolve(failure(new TransactionError(TransactionErrorReason.UNKNOWN))); - } - - // handle timeout as the last possible case, otherwise can fail with timeout on Complete tx - if (Date.now() - startedAt > this.timings.maxIndexingWaitTime) { - subscription.unsubscribe(); - - resolve(failure(new TransactionError(TransactionErrorReason.INDEXING_TIMEOUT))); - } - }, - error: reject, - }); - }); - } -} diff --git a/packages/react-v1/src/transactions/infrastructure/TransactionStorage.ts b/packages/react-v1/src/transactions/infrastructure/TransactionStorage.ts deleted file mode 100644 index c641284221..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/TransactionStorage.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { BaseStorageSchema, IStorageProvider, Storage } from '@lens-protocol/storage'; - -import { TransactionStorageSchema } from '../adapters/schemas/transactions'; - -export function createTransactionStorage(storageProvider: IStorageProvider, namespace: string) { - const schema = new BaseStorageSchema(`lens.${namespace}.transactions`, TransactionStorageSchema); - return Storage.createForSchema(schema, storageProvider); -} diff --git a/packages/react-v1/src/transactions/infrastructure/__helpers__/mocks.ts b/packages/react-v1/src/transactions/infrastructure/__helpers__/mocks.ts deleted file mode 100644 index 7d9e188667..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__helpers__/mocks.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { ProxyActionStatus, TransactionError } from '@lens-protocol/domain/entities'; -import { mockTransactionHash } from '@lens-protocol/domain/mocks'; -import { - ChainType, - failure, - invariant, - never, - PromiseResult, - Result, - success, -} from '@lens-protocol/shared-kernel'; - -import { - ConfirmationRequest, - IndexingEvent, - IndexingEventRequest, - ITransactionObserver, - ProxyActionStatusEvent, -} from '../TransactionFactory'; - -type WaitForConfirmationInstructions = { - txHash: string; - chainType: ChainType; - result: Result; -}; - -type WaitForNextIndexingEventInstructions = { - request: IndexingEventRequest; - events: Array; -}; - -type WaitForProxyTransactionStatusInstructions = { - request: string; - statuses: Array; -}; - -type MockedTransactionObserverInstructions = - | WaitForConfirmationInstructions - | WaitForNextIndexingEventInstructions - | WaitForProxyTransactionStatusInstructions; - -export class MockedTransactionObserver implements ITransactionObserver { - private constructor(private readonly instructions: MockedTransactionObserverInstructions) {} - - async waitForConfirmation({ - txHash, - chainType, - }: ConfirmationRequest): PromiseResult { - if (!('txHash' in this.instructions)) { - throw new Error('Method not implemented.'); - } - invariant(txHash === this.instructions.txHash, 'txHash mismatch'); - invariant(chainType === this.instructions.chainType, 'chainType mismatch'); - - return this.instructions.result; - } - - async waitForNextIndexingEvent( - request: IndexingEventRequest, - ): PromiseResult { - if (!('events' in this.instructions)) { - throw new Error('Method not implemented.'); - } - invariant( - JSON.stringify(request) === JSON.stringify(this.instructions.request), - 'Indexing event request mismatch', - ); - - const item = this.instructions.events.shift(); - - invariant(item, 'Indexing events sequence is empty'); - - if (item instanceof TransactionError) { - return failure(item); - } - - if ('indexed' in item) { - return success(item); - } - - never(`Unexpected item in indexing events sequence`); - } - - async waitForProxyTransactionStatus( - proxyId: string, - ): PromiseResult { - if (!('statuses' in this.instructions)) { - throw new Error('Method not implemented.'); - } - - invariant(proxyId === this.instructions.request, 'Proxy ID mismatch'); - - const item = this.instructions.statuses.shift(); - - invariant(item, 'Indexing events sequence is empty'); - - if (item instanceof TransactionError) { - return failure(item); - } - - if ('status' in item) { - return success(item); - } - - never(`Unexpected item in indexing events sequence`); - } - - static withIndexingEventSequence( - instructions: WaitForNextIndexingEventInstructions, - ): MockedTransactionObserver { - return new MockedTransactionObserver(instructions); - } - - static withProxyStatusSequence( - instructions: WaitForProxyTransactionStatusInstructions, - ): MockedTransactionObserver { - return new MockedTransactionObserver(instructions); - } - - static withExecutedOutcome(instructions: WaitForConfirmationInstructions) { - return new MockedTransactionObserver(instructions); - } -} - -export function mockProxyActionStatusEvent( - overrides?: Partial, -): ProxyActionStatusEvent { - return { - txHash: mockTransactionHash(), - status: ProxyActionStatus.MINTING, - ...overrides, - }; -} diff --git a/packages/react-v1/src/transactions/infrastructure/__tests__/AccessConditionBuilderFactory.spec.ts b/packages/react-v1/src/transactions/infrastructure/__tests__/AccessConditionBuilderFactory.spec.ts deleted file mode 100644 index 5643795d34..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__tests__/AccessConditionBuilderFactory.spec.ts +++ /dev/null @@ -1,280 +0,0 @@ -import { ContractType, ScalarOperator } from '@lens-protocol/api-bindings'; -import { - DecryptionCriteriaType, - Erc20ComparisonOperator, - NftContractType, - PublicationId, -} from '@lens-protocol/domain/entities'; -import { - mockAddressOwnershipCriterion, - mockAndCriterion, - mockCollectPublicationCriterion, - mockCollectThisPublicationCriterion, - mockErc20OwnershipCriterion, - mockFollowProfileCriterion, - mockNftOwnershipCriterion, - mockOrCriterion, - mockProfileId, - mockPublicationId, -} from '@lens-protocol/domain/mocks'; -import { InvariantError } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; -import { when } from 'jest-when'; - -import { staging } from '../../../environments'; -import { - AccessConditionBuilderFactory, - IPublicationIdPredictor, -} from '../AccessConditionBuilderFactory'; - -const ownerId = mockProfileId(); -const addressOwnershipCriterion = mockAddressOwnershipCriterion(); -const collectPublicationCriterion = mockCollectPublicationCriterion(); -const erc20OwnershipCriterion = mockErc20OwnershipCriterion({ - condition: Erc20ComparisonOperator.Equal, -}); -const followProfileCriterion = mockFollowProfileCriterion(); -const nftOwnershipCriterion = mockNftOwnershipCriterion({ - contractType: NftContractType.Erc1155, -}); - -function setupTestScenario({ - predictedPublicationId = mockPublicationId(), -}: { predictedPublicationId?: PublicationId } = {}) { - const publicationIdPredictor = mock(); - const factory = new AccessConditionBuilderFactory(staging.chains, publicationIdPredictor); - - when(publicationIdPredictor.predictNextPublicationIdFor) - .calledWith(ownerId) - .mockResolvedValue(predictedPublicationId); - - return { factory }; -} - -describe(`Given an instance of the ${AccessConditionBuilderFactory.name}`, () => { - describe(`when using it to build new AccessCondition`, () => { - it.each([ - { - criterion: addressOwnershipCriterion, - expected: { - eoa: { - address: addressOwnershipCriterion.address, - }, - }, - }, - { - criterion: collectPublicationCriterion, - expected: { - collect: { - publicationId: collectPublicationCriterion.publicationId, - thisPublication: false, - }, - }, - }, - { - criterion: erc20OwnershipCriterion, - expected: { - token: { - amount: erc20OwnershipCriterion.amount - .toBigDecimal() - .mul(10 ** erc20OwnershipCriterion.amount.asset.decimals) - .toFixed(), - chainID: staging.chains[erc20OwnershipCriterion.amount.asset.chainType].chainId, - contractAddress: erc20OwnershipCriterion.amount.asset.address, - decimals: erc20OwnershipCriterion.amount.asset.decimals, - condition: ScalarOperator.Equal, - }, - }, - }, - { - criterion: followProfileCriterion, - expected: { - follow: { - profileId: followProfileCriterion.profileId, - }, - }, - }, - { - criterion: nftOwnershipCriterion, - expected: { - nft: { - chainID: nftOwnershipCriterion.chainId, - contractAddress: nftOwnershipCriterion.contractAddress, - contractType: ContractType.Erc1155, - tokenIds: nftOwnershipCriterion.tokenIds ?? null, - }, - }, - }, - ])('should support "$criterion.type" criterion', async ({ criterion, expected }) => { - const { factory } = setupTestScenario(); - - const actual = await factory - .createForPublicationBy(ownerId) - .withDecryptionCriteria(criterion) - .build(); - - expect(actual).toMatchObject({ - or: { - criteria: [ - { - profile: { - profileId: ownerId, - }, - }, - expected, - ], - }, - }); - }); - - it(`should support "${DecryptionCriteriaType.COLLECT_THIS_PUBLICATION}" criterion`, async () => { - const predictedPublicationId = mockPublicationId(); - const { factory } = setupTestScenario({ predictedPublicationId }); - - const criterion = mockCollectThisPublicationCriterion(); - const actual = await factory - .createForPublicationBy(ownerId) - .withDecryptionCriteria(criterion) - .build(); - - expect(actual).toMatchObject({ - or: { - criteria: [ - { - profile: { - profileId: ownerId, - }, - }, - { - collect: { - publicationId: predictedPublicationId, - thisPublication: true, - }, - }, - ], - }, - }); - }); - - it.each([ - { - criterion: mockOrCriterion([addressOwnershipCriterion, followProfileCriterion]), - expected: { - or: { - criteria: [ - { - profile: { - profileId: ownerId, - }, - }, - { - or: { - criteria: [ - { - eoa: { - address: addressOwnershipCriterion.address, - }, - }, - { - follow: { - profileId: followProfileCriterion.profileId, - }, - }, - ], - }, - }, - ], - }, - }, - }, - { - criterion: mockAndCriterion([addressOwnershipCriterion, followProfileCriterion]), - expected: { - or: { - criteria: [ - { - profile: { - profileId: ownerId, - }, - }, - { - and: { - criteria: [ - { - eoa: { - address: addressOwnershipCriterion.address, - }, - }, - { - follow: { - profileId: followProfileCriterion.profileId, - }, - }, - ], - }, - }, - ], - }, - }, - }, - ])( - `should support nested conditions using an "$criterion.type" operator`, - async ({ criterion, expected }) => { - const { factory } = setupTestScenario(); - - const actual = await factory - .createForPublicationBy(ownerId) - .withDecryptionCriteria(criterion) - .build(); - - expect(actual).toMatchObject(expected); - }, - ); - - it.each([ - mockOrCriterion([addressOwnershipCriterion]), - mockAndCriterion([addressOwnershipCriterion]), - ])( - `should throw an ${InvariantError.name} if less than 2 criteria are provided in a nested "$type" condition`, - async (criterion) => { - const { factory } = setupTestScenario(); - - const builder = factory.createForPublicationBy(ownerId); - - await expect(() => builder.withDecryptionCriteria(criterion).build()).rejects.toThrowError( - InvariantError, - ); - }, - ); - - it.each([ - mockOrCriterion([ - addressOwnershipCriterion, - followProfileCriterion, - followProfileCriterion, - followProfileCriterion, - followProfileCriterion, - followProfileCriterion, - ]), - mockAndCriterion([ - addressOwnershipCriterion, - followProfileCriterion, - followProfileCriterion, - followProfileCriterion, - followProfileCriterion, - followProfileCriterion, - ]), - ])( - `should throw an ${InvariantError.name} if more than 5 criteria are provided in a nested "$type" condition`, - async (criterion) => { - const { factory } = setupTestScenario(); - - const builder = factory.createForPublicationBy(ownerId); - - await expect(() => builder.withDecryptionCriteria(criterion).build()).rejects.toThrowError( - InvariantError, - ); - }, - ); - }); -}); diff --git a/packages/react-v1/src/transactions/infrastructure/__tests__/Eip1559GasPriceEstimator.spec.ts b/packages/react-v1/src/transactions/infrastructure/__tests__/Eip1559GasPriceEstimator.spec.ts deleted file mode 100644 index e1595955a2..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__tests__/Eip1559GasPriceEstimator.spec.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { mockFeeHistoryResult } from '@lens-protocol/blockchain-bindings/mocks'; -import { Amount, CryptoNativeAmount, CryptoNativeAsset } from '@lens-protocol/shared-kernel'; -import { mockEtherGweiAmount, mockMaticGweiAmount } from '@lens-protocol/shared-kernel/mocks'; -import { providers } from 'ethers'; -import { mock } from 'jest-mock-extended'; -import { when } from 'jest-when'; - -import { - Eip1559GasPriceEstimator, - Eip1559GasPriceEstimate, - TransactionExecutionSpeed, - CryptoNativeAmountFactory, -} from '../Eip1559GasPriceEstimator'; - -function mockEip1559GasPriceSupport( - provider: providers.JsonRpcProvider, - using: { - currentBaseFee: Amount; - rewardPercentiles: AmountRewardPercentilesTuple; - }, -) { - const blockCount = 20; - const originalSend = provider.send; - - jest.spyOn(provider, 'send'); - - when(provider.send) - .mockImplementation(async (method: string, params: unknown[]) => { - return originalSend.call(provider, method, params); - }) - .calledWith('eth_feeHistory', [blockCount, 'pending', [1, 50, 99]]) - .mockResolvedValue( - mockFeeHistoryResult({ - blockCount: blockCount, - lastBlockBaseFee: using.currentBaseFee, - rewardPercentiles: using.rewardPercentiles, - }), - ); -} - -type AmountRewardPercentilesTuple = [Amount, Amount, Amount]; - -describe(`Given an instance of the ${Eip1559GasPriceEstimator.name}`, () => { - describe.each<{ - baseFee: CryptoNativeAmount; - createAmount: CryptoNativeAmountFactory; - rewardPercentiles: AmountRewardPercentilesTuple; - speed: TransactionExecutionSpeed; - expectedMaxPriorityFeePerGas: CryptoNativeAmount; - }>([ - { - baseFee: mockEtherGweiAmount(80), - createAmount: (value) => Amount.ether(value), - rewardPercentiles: [mockEtherGweiAmount(2), mockEtherGweiAmount(3), mockEtherGweiAmount(5)], - speed: TransactionExecutionSpeed.SLOW, - expectedMaxPriorityFeePerGas: mockEtherGweiAmount(2), - }, - { - baseFee: mockMaticGweiAmount(80), - createAmount: (value) => Amount.matic(value), - rewardPercentiles: [mockMaticGweiAmount(2), mockMaticGweiAmount(3), mockMaticGweiAmount(5)], - speed: TransactionExecutionSpeed.AVERAGE, - expectedMaxPriorityFeePerGas: mockMaticGweiAmount(3), - }, - { - baseFee: mockEtherGweiAmount(80), - createAmount: (value) => Amount.ether(value), - rewardPercentiles: [mockEtherGweiAmount(2), mockEtherGweiAmount(3), mockEtherGweiAmount(5)], - speed: TransactionExecutionSpeed.FAST, - expectedMaxPriorityFeePerGas: mockEtherGweiAmount(5), - }, - ])( - 'when estimating gas price for speed: $speed', - ({ baseFee, createAmount, rewardPercentiles, speed, expectedMaxPriorityFeePerGas }) => { - it(`should create a ${Eip1559GasPriceEstimate.name} w/ the expected estimates`, async () => { - const provider = mock(); - - mockEip1559GasPriceSupport(provider, { - currentBaseFee: baseFee, - rewardPercentiles, - }); - - const gasEstimator = new Eip1559GasPriceEstimator(provider, createAmount); - const estimation = await gasEstimator.estimate(speed); - - const expected = new Eip1559GasPriceEstimate(baseFee, expectedMaxPriorityFeePerGas); - expect(estimation).toEqual(expected); - }); - }, - ); -}); diff --git a/packages/react-v1/src/transactions/infrastructure/__tests__/EncryptedPublicationMetadataUploader.spec.ts b/packages/react-v1/src/transactions/infrastructure/__tests__/EncryptedPublicationMetadataUploader.spec.ts deleted file mode 100644 index dea94b0fca..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__tests__/EncryptedPublicationMetadataUploader.spec.ts +++ /dev/null @@ -1,120 +0,0 @@ -/* - * @jest-environment node - */ -import { faker } from '@faker-js/faker'; -import { PublicationMainFocus } from '@lens-protocol/api-bindings'; -import { DecryptionCriteria } from '@lens-protocol/domain/entities'; -import { - mockAddressOwnershipCriterion, - mockCreateCommentRequest, - mockCreatePostRequest, -} from '@lens-protocol/domain/mocks'; -import { GatedClient } from '@lens-protocol/gated-content'; -import { webCryptoProvider } from '@lens-protocol/gated-content/web'; -import { InMemoryStorageProvider } from '@lens-protocol/storage'; -import { Wallet } from 'ethers'; -import { mock } from 'jest-mock-extended'; - -import { staging } from '../../../environments'; -import { MetadataUploadHandler } from '../../adapters/MetadataUploadHandler'; -import { - AccessConditionBuilderFactory, - IPublicationIdPredictor, -} from '../AccessConditionBuilderFactory'; -import { EncryptedPublicationMetadataUploader } from '../EncryptedPublicationMetadataUploader'; -import { createGatedClient } from '../createGatedClient'; - -const signer = Wallet.createRandom(); - -function setupTestScenario({ uploadHandler }: { uploadHandler: MetadataUploadHandler }) { - const client = createGatedClient({ - config: { - domain: 'localhost', - uri: 'https://localhost/login', - }, - environment: staging, - signer, - encryptionProvider: webCryptoProvider(), - storageProvider: new InMemoryStorageProvider(), - }); - - const publicationIdPredictor = mock(); - - const accessConditionBuilderFactory = new AccessConditionBuilderFactory( - staging.chains, - publicationIdPredictor, - ); - - const uploader = EncryptedPublicationMetadataUploader.create( - client, - accessConditionBuilderFactory, - uploadHandler, - ); - - return { uploader }; -} - -const url = faker.internet.url(); -const uploadHandler = jest.fn().mockResolvedValue(url); - -function assertHasDecryptionCriteria(request: { - decryptionCriteria?: DecryptionCriteria; -}): asserts request is { decryptionCriteria: DecryptionCriteria } { - if (!request.decryptionCriteria) { - throw new Error('Missing decryption criteria'); - } -} - -describe(`Given an instance of the ${EncryptedPublicationMetadataUploader.name}`, () => { - describe(`when the "${EncryptedPublicationMetadataUploader.prototype.upload.name}" method is invoked`, () => { - describe.each([ - { - request: 'CreateEncryptedPostRequest', - mockCreatePublicationRequest: mockCreatePostRequest, - }, - { - request: 'CreateEncryptedCommentRequest', - mockCreatePublicationRequest: mockCreateCommentRequest, - }, - ])('with a $request', ({ mockCreatePublicationRequest }) => { - const request = mockCreatePublicationRequest({ - decryptionCriteria: mockAddressOwnershipCriterion({ address: signer.address }), - }); - assertHasDecryptionCriteria(request); - - it(`should: - - create AccessCondition criteria - - create Publication Metadata - - use the ${GatedClient.name} to encrypt the metadata - - eventually upload the metadata using the provided upload handler`, async () => { - const { uploader } = setupTestScenario({ uploadHandler }); - - const result = await uploader.upload(request); - - expect(result).toEqual(url); - expect(uploadHandler).toHaveBeenCalledWith( - expect.objectContaining({ - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - encryptionParams: expect.objectContaining({ - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - accessCondition: { - or: { - criteria: [ - { - profile: { profileId: request.profileId }, - }, - { - eoa: { address: signer.address }, - }, - ], - }, - }, - }), - content: 'This publication is gated.', - mainContentFocus: PublicationMainFocus[request.contentFocus], - }), - ); - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/infrastructure/__tests__/MetadataUploaderErrorMiddleware.spec.ts b/packages/react-v1/src/transactions/infrastructure/__tests__/MetadataUploaderErrorMiddleware.spec.ts deleted file mode 100644 index d062637a1f..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__tests__/MetadataUploaderErrorMiddleware.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { InvariantError } from '@lens-protocol/shared-kernel'; -import { when } from 'jest-when'; - -import { FailedUploadError } from '../../adapters/IMetadataUploader'; -import { MetadataUploaderErrorMiddleware } from '../MetadataUploaderErrorMiddleware'; - -const payload = {}; -const uploadHandler = jest.fn(); - -describe(`Given an instance of the ${MetadataUploaderErrorMiddleware.name}`, () => { - describe(`when the "${MetadataUploaderErrorMiddleware.prototype.upload.name}" method is invoked`, () => { - it('should upload the metadata using the provided upload handler', async () => { - const url = faker.internet.url(); - when(uploadHandler).calledWith(payload).mockResolvedValue(url); - - const middleware = new MetadataUploaderErrorMiddleware(uploadHandler); - - const actual = await middleware.upload(payload); - - expect(actual).toBe(url); - }); - - it.each(['not a valid url', '//missing-protocol.com', null, undefined, {}])( - `should throw a ${InvariantError.name} if the upload handler returns a "%s"`, - async (url) => { - when(uploadHandler).calledWith(payload).mockResolvedValue(url); - const middleware = new MetadataUploaderErrorMiddleware(uploadHandler); - - await expect(() => middleware.upload(payload)).rejects.toThrow(InvariantError); - }, - ); - - it(`should throw a ${FailedUploadError.name} if the upload fails`, async () => { - when(uploadHandler).calledWith(payload).mockRejectedValue(new Error('Unknown error')); - const middleware = new MetadataUploaderErrorMiddleware(uploadHandler); - - await expect(() => middleware.upload(payload)).rejects.toThrow(FailedUploadError); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/infrastructure/__tests__/ProfileCacheManager.spec.ts b/packages/react-v1/src/transactions/infrastructure/__tests__/ProfileCacheManager.spec.ts deleted file mode 100644 index 90a5ca2f22..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__tests__/ProfileCacheManager.spec.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { Profile, FragmentProfile, SingleProfileQueryRequest } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockGetProfileResponse, - mockProfileFragment, - mockSources, - simulateAuthenticatedWallet, - simulateAuthenticatedProfile, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { mockProfile, mockProfileId } from '@lens-protocol/domain/mocks'; -import identity from 'lodash/identity'; - -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../../mediaTransforms'; -import { ProfileCacheManager } from '../ProfileCacheManager'; - -function setupTestScenario({ - profile, - expectedObserverId = null, - cacheEntry = profile, - expectedRequest = { profileId: profile.id }, -}: { - expectedRequest?: SingleProfileQueryRequest; - cacheEntry?: Profile | null; - expectedObserverId?: ProfileId | null; - profile: Profile; -}) { - const handleResolver = (v: string) => v; - const sources = mockSources(); - const mediaTransforms = defaultMediaTransformsConfig; - const client = mockLensApolloClient([ - mockGetProfileResponse({ - profile: profile, - variables: { - request: expectedRequest, - observerId: expectedObserverId, - sources, - ...mediaTransformConfigToQueryVariables(mediaTransforms), - }, - }), - ]); - - const profileIdentifier = client.cache.identify({ - __typename: 'Profile', - id: profile.id, - }); - - client.cache.writeFragment({ - id: profileIdentifier, - fragment: FragmentProfile, - fragmentName: 'Profile', - data: cacheEntry, - }); - - const manager = new ProfileCacheManager(client, sources, mediaTransforms, handleResolver); - - return { - manager, - - get profileFromCache() { - return client.cache.readFragment({ - id: profileIdentifier, - fragmentName: 'Profile', - fragment: FragmentProfile, - }); - }, - }; -} - -describe(`Given an instance of the ${ProfileCacheManager.name}`, () => { - const profile = mockProfileFragment(); - const expectations = { __typename: 'Profile', id: profile.id }; - - describe(`when invoking the "${ProfileCacheManager.prototype.fetchProfile.name}" method`, () => { - beforeAll(() => { - simulateAuthenticatedWallet(); - }); - - it('should allow to query by profile Id', async () => { - const { manager } = setupTestScenario({ profile }); - - const actual = await manager.fetchProfile(profile.id); - - expect(actual).toMatchObject(expectations); - }); - - it('should use the Active Profile if available as observerId', async () => { - const activeProfile = mockProfile(); - simulateAuthenticatedProfile(activeProfile); - - const { manager } = setupTestScenario({ - profile, - expectedObserverId: activeProfile.id, - }); - - const actual = await manager.fetchProfile(profile.id); - - expect(actual).toMatchObject(expectations); - }); - }); - - describe(`when invoking the "${ProfileCacheManager.prototype.fetchNewProfile.name}" method`, () => { - beforeAll(() => { - simulateAuthenticatedWallet(); - }); - - it('should allow to query by profile handle', async () => { - const { manager } = setupTestScenario({ - profile, - expectedRequest: { handle: profile.handle }, - }); - - const actual = await manager.fetchNewProfile(profile.handle); - - expect(actual).toMatchObject(expectations); - }); - - it('should use the Active Profile if available as observerId', async () => { - const activeProfile = mockProfile(); - simulateAuthenticatedProfile(activeProfile); - - const { manager } = setupTestScenario({ - profile, - expectedRequest: { handle: profile.handle }, - expectedObserverId: activeProfile.id, - }); - - const actual = await manager.fetchNewProfile(profile.handle); - - expect(actual).toMatchObject(expectations); - }); - }); - - describe(`when invoking the "${ProfileCacheManager.prototype.refreshProfile.name}" method`, () => { - beforeAll(() => { - simulateAuthenticatedWallet(); - }); - - it('should update the cache with fresh data from the API', async () => { - const cacheEntry = mockProfileFragment({ - id: profile.id, - handle: profile.handle, - ownedBy: profile.ownedBy, - }); - - const scenario = setupTestScenario({ - profile, - cacheEntry, - }); - - const actual = await scenario.manager.refreshProfile(profile.id); - - expect(scenario.profileFromCache).toMatchObject(expectations); - expect(actual).toMatchObject(expectations); - }); - - it('should update the cache even if the initial cache entry is null', async () => { - const scenario = setupTestScenario({ - profile, - cacheEntry: null, - }); - - const actual = await scenario.manager.refreshProfile(profile.id); - - expect(scenario.profileFromCache).toMatchObject(expectations); - expect(actual).toMatchObject(expectations); - }); - }); - - describe(`when invoking the "${ProfileCacheManager.prototype.updateProfile.name}" method`, () => { - it(`should update properly the profile fragment in the`, () => { - const scenario = setupTestScenario({ profile }); - - scenario.manager.updateProfile(profile.id, (current) => ({ - ...current, - name: 'Bob', - })); - - expect(scenario.profileFromCache).toMatchObject({ - name: 'Bob', - }); - }); - - it(`should be resilient to missing entry in cache`, () => { - const scenario = setupTestScenario({ profile }); - - expect(() => scenario.manager.updateProfile(mockProfileId(), identity)).not.toThrowError(); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/infrastructure/__tests__/PublicationIdPredictor.spec.ts b/packages/react-v1/src/transactions/infrastructure/__tests__/PublicationIdPredictor.spec.ts deleted file mode 100644 index 4e07f0d587..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__tests__/PublicationIdPredictor.spec.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { AnyPublication } from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockGetPublicationsResponse, - mockPostFragment, -} from '@lens-protocol/api-bindings/mocks'; -import { ProfileId } from '@lens-protocol/domain/entities'; -import { - mockCreateCommentRequest, - mockCreateMirrorRequest, - mockCreatePostRequest, - mockPaidFollowRequest, - mockProfileId, -} from '@lens-protocol/domain/mocks'; -import { ProtocolTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; -import { never } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; - -import { - defaultMediaTransformsConfig, - mediaTransformConfigToQueryVariables, -} from '../../../mediaTransforms'; -import { PendingTransactionGateway } from '../../adapters/PendingTransactionGateway'; -import { mockITransactionFactory, mockMetaTransactionData } from '../../adapters/__helpers__/mocks'; -import { PublicationIdPredictor } from '../PublicationIdPredictor'; - -function setupTestScenario({ - profileId, - publications, - pendingTransactionsFor = [], -}: { - profileId: ProfileId; - publications: AnyPublication[]; - pendingTransactionsFor?: ProtocolTransactionRequest[]; -}) { - const apolloClient = mockLensApolloClient([ - mockGetPublicationsResponse({ - variables: { - profileId, - limit: 1, - sources: [], - ...mediaTransformConfigToQueryVariables(defaultMediaTransformsConfig), - }, - publications, - }), - ]); - - const transactionGateway = mock(); - - const factory = mockITransactionFactory(); - const transactions = pendingTransactionsFor.map((request) => { - const init = mockMetaTransactionData({ request }); - return factory.createMetaTransaction(init); - }); - - transactionGateway.getAll.mockResolvedValue(transactions); - - const publicationIdPredictor = new PublicationIdPredictor(apolloClient, transactionGateway); - - return { publicationIdPredictor }; -} - -describe(`Given an instance of the ${PublicationIdPredictor.name}`, () => { - describe('when predicting the first publication id', () => { - it('should return the very first publication id for the given profile', async () => { - const profileId = mockProfileId(); - const { publicationIdPredictor } = setupTestScenario({ - profileId, - publications: [], - }); - - const actual = await publicationIdPredictor.predictNextPublicationIdFor(profileId); - - const expected = `${profileId}-0x1`; - expect(actual).toEqual(expected); - }); - }); - - describe('when predicting the next publication id', () => { - it(`should retrieve the last finalized publication id`, async () => { - const post = mockPostFragment(); - const { publicationIdPredictor } = setupTestScenario({ - profileId: post.profile.id, - publications: [post], - }); - - const actual = await publicationIdPredictor.predictNextPublicationIdFor(post.profile.id); - - const onchainId = post.id.split('-').pop() ?? never(); - const newSequentialId = parseInt(onchainId, 16) + 1; - const expected = `${post.profile.id}-0x${newSequentialId.toString(16)}`; - expect(actual).toEqual(expected); - }); - - it('should account for pending transactions involving publications (comment, post, mirror)', async () => { - const post = mockPostFragment(); - const { publicationIdPredictor } = setupTestScenario({ - profileId: post.profile.id, - publications: [post], - pendingTransactionsFor: [ - mockPaidFollowRequest(), - mockCreateCommentRequest({ profileId: post.profile.id }), // only these should count - mockCreateCommentRequest(), - mockCreatePostRequest({ profileId: post.profile.id }), // only these should count - mockCreatePostRequest(), - mockCreateMirrorRequest({ profileId: post.profile.id }), // only these should count - mockCreateMirrorRequest(), - ], - }); - - const actual = await publicationIdPredictor.predictNextPublicationIdFor(post.profile.id); - - const onchainId = post.id.split('-').pop() ?? never(); - const newSequentialId = parseInt(onchainId, 16) + 1 + 3; // 3 pending transactions - const expected = `${post.profile.id}-0x${newSequentialId.toString(16)}`; - expect(actual).toEqual(expected); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/infrastructure/__tests__/PublicationMetadataUploader.spec.ts b/packages/react-v1/src/transactions/infrastructure/__tests__/PublicationMetadataUploader.spec.ts deleted file mode 100644 index 3155ba5402..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__tests__/PublicationMetadataUploader.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { PublicationMainFocus } from '@lens-protocol/api-bindings'; -import { mockCreateCommentRequest, mockCreatePostRequest } from '@lens-protocol/domain/mocks'; - -import { MetadataUploadHandler } from '../../adapters/MetadataUploadHandler'; -import { PublicationMetadataUploader } from '../PublicationMetadataUploader'; - -function setupTestScenario({ uploadHandler }: { uploadHandler: MetadataUploadHandler }) { - return PublicationMetadataUploader.create(uploadHandler); -} - -const url = faker.internet.url(); -const uploadHandler = jest.fn().mockResolvedValue(url); - -describe(`Given an instance of the ${PublicationMetadataUploader.name}`, () => { - describe(`when the "${PublicationMetadataUploader.prototype.upload.name}" method is invoked`, () => { - describe.each([ - { request: 'CreatePostRequest', mockPublication: mockCreatePostRequest }, - { request: 'CreateCommentRequest', mockPublication: mockCreateCommentRequest }, - ])('with a $request', ({ mockPublication }) => { - const request = mockPublication(); - - it('should upload the expected publication metadata using the provided upload handler', async () => { - const metadataUploader = setupTestScenario({ uploadHandler }); - - const result = await metadataUploader.upload(request); - - expect(result).toEqual(url); - expect(uploadHandler).toHaveBeenCalledWith( - expect.objectContaining({ - content: request.content, - mainContentFocus: PublicationMainFocus[request.contentFocus], - }), - ); - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/infrastructure/__tests__/TransactionFactory.spec.ts b/packages/react-v1/src/transactions/infrastructure/__tests__/TransactionFactory.spec.ts deleted file mode 100644 index 4f89ee2cc4..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__tests__/TransactionFactory.spec.ts +++ /dev/null @@ -1,364 +0,0 @@ -import { - MetaTransaction, - NativeTransaction, - ProtocolTransactionKinds, - ProxyActionStatus, - ProxyTransaction, - TransactionError, - TransactionErrorReason, - TransactionEvent, - TransactionKind, -} from '@lens-protocol/domain/entities'; -import { mockTransactionHash, mockAnyTransactionRequestModel } from '@lens-protocol/domain/mocks'; -import { - ProtocolTransactionRequest, - AnyTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { success } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; - -import { - mockMetaTransactionData, - mockNativeTransactionData, - mockNativeTransactionDataWithIndexingId, - mockProxyTransactionData, -} from '../../adapters/__helpers__/mocks'; -import { IndexingEvent, ITransactionObserver, TransactionFactory } from '../TransactionFactory'; -import { MockedTransactionObserver, mockProxyActionStatusEvent } from '../__helpers__/mocks'; - -function mockIndexingEvent(overrides?: Partial): IndexingEvent { - return { - indexed: false, - txHash: mockTransactionHash(), - ...overrides, - }; -} - -function setupTransactionFactory({ - observer = mock(), -}: { observer?: ITransactionObserver } = {}) { - return new TransactionFactory(observer); -} - -describe(`Given an instance of the ${TransactionFactory.name}`, () => { - describe(`and a ${MetaTransaction.name} instance created via MetaTransactionData`, () => { - const init = mockMetaTransactionData(); - - describe(`when invoking the "waitNextEvent" method`, () => { - it(`should - - resolve with Success as the txHash changes while not yet indexed - - and update the tx hash`, async () => { - const indexingEvent = mockIndexingEvent({ indexed: false }); - const observer = MockedTransactionObserver.withIndexingEventSequence({ - request: { - indexingId: init.indexingId, - }, - events: [indexingEvent], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createMetaTransaction(init); - - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.UPGRADED); - expect(transaction.hash).toEqual(indexingEvent.txHash); - }); - - it(`should: - - resolve with Success as soon as indexed by the BE - - and update the tx hash if changed`, async () => { - const indexingEvent = mockIndexingEvent({ indexed: true }); - const observer = MockedTransactionObserver.withIndexingEventSequence({ - request: { - indexingId: init.indexingId, - }, - events: [indexingEvent], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createMetaTransaction(init); - - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.SETTLED); - expect(transaction.hash).toEqual(indexingEvent.txHash); - }); - - it(`should forward any ${TransactionError.name} from the ITransactionObserver`, async () => { - const error = new TransactionError(TransactionErrorReason.MINING_TIMEOUT); - const observer = MockedTransactionObserver.withIndexingEventSequence({ - request: { - indexingId: init.indexingId, - }, - events: [error], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createMetaTransaction(init); - - const result = await transaction.waitNextEvent(); - - expect(() => result.unwrap()).toThrow(error); - }); - }); - }); - - describe(`and a ${NativeTransaction.name} instance created via NativeTransactionData`, () => { - describe(`with "indexingId"`, () => { - const init = mockNativeTransactionDataWithIndexingId(); - - describe(`when invoking the "waitNextEvent" method`, () => { - it(`should - - resolve with Success as the txHash changes while not yet indexed - - and update the tx hash`, async () => { - const indexingEvent = mockIndexingEvent({ indexed: false }); - const observer = MockedTransactionObserver.withIndexingEventSequence({ - request: { - indexingId: init.indexingId, - }, - events: [indexingEvent], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createNativeTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.UPGRADED); - expect(transaction.hash).toEqual(indexingEvent.txHash); - }); - - it(`should: - - resolve with Success as soon as indexed by the BE - - and update the tx hash if changed`, async () => { - const indexingEvent = mockIndexingEvent({ indexed: true }); - const observer = MockedTransactionObserver.withIndexingEventSequence({ - request: { - indexingId: init.indexingId, - }, - events: [indexingEvent], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createNativeTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.SETTLED); - expect(transaction.hash).toEqual(indexingEvent.txHash); - }); - - it(`should forward any ${TransactionError.name} from the ITransactionObserver`, async () => { - const error = new TransactionError(TransactionErrorReason.MINING_TIMEOUT); - const observer = MockedTransactionObserver.withIndexingEventSequence({ - request: { - indexingId: init.indexingId, - }, - events: [error], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createNativeTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(() => result.unwrap()).toThrow(error); - }); - }); - }); - - describe(`with NO "indexingId"`, () => { - describe.each(ProtocolTransactionKinds)( - `and the transaction request is for an "%s" transaction`, - (kind) => { - describe(`when invoking the "waitNextEvent" method`, () => { - const init = mockNativeTransactionData({ - request: mockAnyTransactionRequestModel({ kind }) as AnyTransactionRequest, - }); - - it(`should resolve with Success as soon as indexed by the BE`, async () => { - const indexingEvent = mockIndexingEvent({ indexed: true }); - const observer = MockedTransactionObserver.withIndexingEventSequence({ - request: { - txHash: init.txHash, - }, - events: [indexingEvent], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createNativeTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.SETTLED); - }); - }); - }, - ); - - describe(`and the transaction request is for an "${TransactionKind.APPROVE_MODULE}" transaction`, () => { - describe(`when invoking the "waitNextEvent" method`, () => { - const init = mockNativeTransactionData({ - request: mockAnyTransactionRequestModel({ - kind: TransactionKind.APPROVE_MODULE, - }) as AnyTransactionRequest, - }); - - it(`should resolve with Success as soon as the transaction is executed`, async () => { - const observer = MockedTransactionObserver.withExecutedOutcome({ - txHash: init.txHash, - chainType: init.chainType, - result: success(), - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createNativeTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.SETTLED); - }); - }); - }); - }); - }); - - describe(`and a ${ProxyTransaction.name} instance created via ProxyTransactionData`, () => { - describe(`when invoking the "waitNextEvent" method`, () => { - it(`should: - - resolve with Success as soon as the proxy action status is ${ProxyActionStatus.COMPLETE} - - update the tx hash`, async () => { - const init = mockProxyTransactionData(); - const proxyActionStatusEvent = mockProxyActionStatusEvent({ - txHash: mockTransactionHash(), - status: ProxyActionStatus.COMPLETE, - }); - const observer = MockedTransactionObserver.withProxyStatusSequence({ - request: init.proxyId, - statuses: [proxyActionStatusEvent], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createProxyTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.SETTLED); - expect(transaction.hash).toEqual(proxyActionStatusEvent.txHash); - }); - - it(`should: - - resolve with Success as soon as the proxy action status is ${ProxyActionStatus.MINTING} - - update the status to ${ProxyActionStatus.MINTING} - - update the tx hash`, async () => { - const init = mockProxyTransactionData({ - txHash: undefined, - status: undefined, - }); - - const proxyActionStatusEvent = mockProxyActionStatusEvent({ - txHash: mockTransactionHash(), - status: ProxyActionStatus.MINTING, - }); - - const observer = MockedTransactionObserver.withProxyStatusSequence({ - request: init.proxyId, - statuses: [proxyActionStatusEvent], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createProxyTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.BROADCASTED); - expect(transaction.hash).toEqual(proxyActionStatusEvent.txHash); - expect(transaction.status).toBe(ProxyActionStatus.MINTING); - }); - - it(`should: - - resolve with Success as soon as the proxy action status transitions from ${ProxyActionStatus.MINTING} to ${ProxyActionStatus.TRANSFERRING} - - update the status to ${ProxyActionStatus.TRANSFERRING} - - update the tx hash`, async () => { - const init = mockProxyTransactionData({ - status: ProxyActionStatus.MINTING, - }); - - const proxyActionStatusEvent = mockProxyActionStatusEvent({ - txHash: mockTransactionHash(), - status: ProxyActionStatus.TRANSFERRING, - }); - - const observer = MockedTransactionObserver.withProxyStatusSequence({ - request: init.proxyId, - statuses: [proxyActionStatusEvent], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createProxyTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.BROADCASTED); - expect(transaction.hash).toEqual(proxyActionStatusEvent.txHash); - expect(transaction.status).toBe(ProxyActionStatus.TRANSFERRING); - }); - - it(`should reflect tx hash changes the proxy action status is ${ProxyActionStatus.MINTING}`, async () => { - const init = mockProxyTransactionData({ - status: ProxyActionStatus.MINTING, - }); - - const proxyActionStatusEvent = mockProxyActionStatusEvent({ - txHash: mockTransactionHash(), - status: ProxyActionStatus.MINTING, - }); - - const observer = MockedTransactionObserver.withProxyStatusSequence({ - request: init.proxyId, - statuses: [proxyActionStatusEvent], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createProxyTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.UPGRADED); - expect(transaction.hash).toEqual(proxyActionStatusEvent.txHash); - expect(transaction.status).toBe(ProxyActionStatus.MINTING); - }); - - it(`should reflect tx hash changes the proxy action status is ${ProxyActionStatus.TRANSFERRING}`, async () => { - const init = mockProxyTransactionData({ - status: ProxyActionStatus.TRANSFERRING, - }); - - const proxyActionStatusEvent = mockProxyActionStatusEvent({ - txHash: mockTransactionHash(), - status: ProxyActionStatus.TRANSFERRING, - }); - - const observer = MockedTransactionObserver.withProxyStatusSequence({ - request: init.proxyId, - statuses: [proxyActionStatusEvent], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createProxyTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(result.unwrap()).toBe(TransactionEvent.UPGRADED); - expect(transaction.hash).toEqual(proxyActionStatusEvent.txHash); - expect(transaction.status).toBe(ProxyActionStatus.TRANSFERRING); - }); - - it(`should forward any ${TransactionError.name} from the ITransactionObserver`, async () => { - const init = mockProxyTransactionData(); - const error = new TransactionError(TransactionErrorReason.MINING_TIMEOUT); - const observer = MockedTransactionObserver.withProxyStatusSequence({ - request: init.proxyId, - statuses: [error], - }); - const factory = setupTransactionFactory({ observer }); - - const transaction = factory.createProxyTransaction(init); - const result = await transaction.waitNextEvent(); - - expect(() => result.unwrap()).toThrow(error); - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/infrastructure/__tests__/TransactionObserver.spec.ts b/packages/react-v1/src/transactions/infrastructure/__tests__/TransactionObserver.spec.ts deleted file mode 100644 index 8582388287..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__tests__/TransactionObserver.spec.ts +++ /dev/null @@ -1,461 +0,0 @@ -/** - * @jest-environment node - */ - -import { faker } from '@faker-js/faker'; -import { - SafeApolloClient, - ProxyActionStatusTypes, - TransactionErrorReasons, -} from '@lens-protocol/api-bindings'; -import { - mockLensApolloClient, - mockHasTxHashBeenIndexedData, - mockHasTxHashBeenIndexedResponse, - mockProxyActionStatusResponse, -} from '@lens-protocol/api-bindings/mocks'; -import { - ProxyActionStatus, - TransactionError, - TransactionErrorReason, -} from '@lens-protocol/domain/entities'; -import { mockTransactionHash } from '@lens-protocol/domain/mocks'; -import { ChainType } from '@lens-protocol/shared-kernel'; -import { MockProvider } from 'ethereum-waffle'; -import { providers, utils, Wallet } from 'ethers'; -import { mock } from 'jest-mock-extended'; - -import { mockIProviderFactory } from '../../../wallet/adapters/__helpers__/mocks'; -import { TransactionObserver, TransactionObserverTimings } from '../TransactionObserver'; - -const chainType = ChainType.POLYGON; - -function setupTransactionObserver({ - apolloClient = mock(), - timings = { - pollingInterval: 1, - maxIndexingWaitTime: 1000, - maxMiningWaitTime: 1000, - }, - provider = mock(), -}: { - apolloClient?: SafeApolloClient; - timings?: TransactionObserverTimings; - provider?: providers.JsonRpcProvider; -}) { - const providerFactory = mockIProviderFactory({ - chainType, - provider, - }); - return new TransactionObserver(providerFactory, apolloClient, timings); -} - -async function createBlockchainTransaction(provider: MockProvider) { - const [walletFrom, walletTo] = provider.getWallets() as [Wallet, Wallet]; - const txResponse = await walletFrom.sendTransaction({ - to: walletTo.address, - from: walletFrom.address, - value: utils.parseEther('1'), - }); - return txResponse.hash; -} - -describe(`Given an instance of the ${TransactionObserver.name}`, () => { - describe(`when invoking ${TransactionObserver.prototype.waitForConfirmation.name} with a tx hash`, () => { - it('should succeed if the tx is mined within a reasonable time', async () => { - const provider = new MockProvider(); - const transaction = setupTransactionObserver({ - provider, - }); - - const txHash = await createBlockchainTransaction(provider); - const result = await transaction.waitForConfirmation({ txHash, chainType }); - - expect(result.isSuccess()).toBe(true); - }, 15_000); - - it(`should fail with ${TransactionError.name}[reason: ${TransactionErrorReason.MINING_TIMEOUT}] if the tx is not found within a reasonable time`, async () => { - const provider = new MockProvider(); - - const transaction = setupTransactionObserver({ - provider, - }); - const txHash = mockTransactionHash(); - const result = await transaction.waitForConfirmation({ txHash, chainType }); - - expect(() => result.unwrap()).toThrow(TransactionError); - expect(result.isFailure() && result.error.reason).toBe(TransactionErrorReason.MINING_TIMEOUT); - }, 15_000); - - // This test is temporarily skipped because the previous strategy to test stale tx does not work with the new version of Ganache - it.skip(`should fail with ${TransactionError.name}[reason: ${TransactionErrorReason.MINING_TIMEOUT}] if the tx is found but not mined within a reasonable time`, async () => { - const provider = new MockProvider({ - ganacheOptions: { - miner: { - blockTime: 60, // seconds - }, - }, - }); - const transaction = setupTransactionObserver({ - timings: { - pollingInterval: 1, - maxMiningWaitTime: 1000, // ms - maxIndexingWaitTime: 120_000, // ms - }, - provider, - }); - - const txHash = await createBlockchainTransaction(provider); - const result = await transaction.waitForConfirmation({ txHash, chainType }); - - expect(() => result.unwrap()).toThrow(TransactionError); - expect(result.isFailure() && result.error.reason).toBe(TransactionErrorReason.MINING_TIMEOUT); - }, 15_000); - }); - - describe(`when invoking ${TransactionObserver.prototype.waitForNextIndexingEvent.name} with a tx hash"`, () => { - const txHash = mockTransactionHash(); - - it('should succeed with indexed=true if the tx has been indexed by the BE', async () => { - const responses = [ - mockHasTxHashBeenIndexedResponse({ - variables: { - request: { txHash }, - }, - data: mockHasTxHashBeenIndexedData({ - indexed: true, - txHash, - }), - }), - ]; - const apolloClient = mockLensApolloClient(responses); - const transaction = setupTransactionObserver({ - apolloClient, - }); - - const event = await transaction.waitForNextIndexingEvent({ txHash }); - expect(event.unwrap()).toEqual({ - indexed: true, - txHash, - }); - }); - - it(`should fail with ${TransactionError.name}[reason: ${TransactionErrorReason.REVERTED}] if the tx gets reverted`, async () => { - const apolloClient = mockLensApolloClient([ - mockHasTxHashBeenIndexedResponse({ - variables: { - request: { txHash }, - }, - data: mockHasTxHashBeenIndexedData({ - reason: TransactionErrorReasons.Reverted, - }), - }), - ]); - const transaction = setupTransactionObserver({ - apolloClient, - }); - - const result = await transaction.waitForNextIndexingEvent({ txHash }); - - expect(() => result.unwrap()).toThrow(TransactionError); - expect(result.isFailure() && result.error.reason).toBe(TransactionErrorReason.REVERTED); - }); - - it(`should fail with ${TransactionError.name}[reason: ${TransactionErrorReason.INDEXING_TIMEOUT}] if the tx is not indexed within a reasonable time`, async () => { - const txHash = mockTransactionHash(); - const apolloClient = mockLensApolloClient([ - mockHasTxHashBeenIndexedResponse({ - variables: { - request: { txHash }, - }, - data: mockHasTxHashBeenIndexedData({ - indexed: false, - txHash, - }), - }), - ]); - - const transaction = setupTransactionObserver({ - apolloClient, - timings: { - pollingInterval: 1, - maxMiningWaitTime: 1000, // ms - maxIndexingWaitTime: 1, // ms - }, - }); - const result = await transaction.waitForNextIndexingEvent({ txHash }); - - expect(() => result.unwrap()).toThrow(TransactionError); - expect(result.isFailure() && result.error.reason).toBe( - TransactionErrorReason.INDEXING_TIMEOUT, - ); - }); - }); - - describe(`when invoking ${TransactionObserver.prototype.waitForNextIndexingEvent.name} with an indexing ID`, () => { - const indexingId = faker.datatype.uuid(); - - it('should succeed with indexed=true if the tx has been indexed by the BE', async () => { - const txHash = mockTransactionHash(); - const responses = [ - mockHasTxHashBeenIndexedResponse({ - variables: { - request: { txId: indexingId }, - }, - data: mockHasTxHashBeenIndexedData({ - indexed: true, - txHash, - }), - }), - ]; - const apolloClient = mockLensApolloClient(responses); - const transaction = setupTransactionObserver({ - apolloClient, - }); - - const event = await transaction.waitForNextIndexingEvent({ indexingId }); - expect(event.unwrap()).toEqual({ - indexed: true, - txHash, - }); - }); - - it('should succeed with any new txHash if the it changes before being indexed', async () => { - const upgradedTxHash = mockTransactionHash(); - const responses = [ - mockHasTxHashBeenIndexedResponse({ - variables: { - request: { txId: indexingId }, - }, - data: mockHasTxHashBeenIndexedData({ - indexed: false, - txHash: mockTransactionHash(), - }), - }), - mockHasTxHashBeenIndexedResponse({ - variables: { - request: { txId: indexingId }, - }, - data: mockHasTxHashBeenIndexedData({ - indexed: false, - txHash: upgradedTxHash, - }), - }), - ]; - const apolloClient = mockLensApolloClient(responses); - const transaction = setupTransactionObserver({ - apolloClient, - }); - - const event = await transaction.waitForNextIndexingEvent({ indexingId }); - expect(event.unwrap()).toEqual({ - indexed: false, - txHash: upgradedTxHash, - }); - }); - - it('should succeed return any new txHash also as the tx is flagged as indexed by the BE', async () => { - const initialTxHash = mockTransactionHash(); - const upgradedTxHash = mockTransactionHash(); - const responses = [ - mockHasTxHashBeenIndexedResponse({ - variables: { - request: { txId: indexingId }, - }, - data: mockHasTxHashBeenIndexedData({ - indexed: false, - txHash: initialTxHash, - }), - }), - mockHasTxHashBeenIndexedResponse({ - variables: { - request: { txId: indexingId }, - }, - data: mockHasTxHashBeenIndexedData({ - indexed: true, - txHash: upgradedTxHash, - }), - }), - ]; - const apolloClient = mockLensApolloClient(responses); - const transaction = setupTransactionObserver({ - apolloClient, - }); - - const event = await transaction.waitForNextIndexingEvent({ indexingId }); - expect(event.unwrap()).toEqual({ - indexed: true, - txHash: upgradedTxHash, - }); - }); - - it(`should fail with ${TransactionError.name}[reason: ${TransactionErrorReason.REVERTED}] if the tx gets reverted`, async () => { - const apolloClient = mockLensApolloClient([ - mockHasTxHashBeenIndexedResponse({ - variables: { - request: { txId: indexingId }, - }, - data: mockHasTxHashBeenIndexedData({ - reason: TransactionErrorReasons.Reverted, - }), - }), - ]); - const transaction = setupTransactionObserver({ - apolloClient, - }); - - const result = await transaction.waitForNextIndexingEvent({ indexingId }); - - expect(() => result.unwrap()).toThrow(TransactionError); - expect(result.isFailure() && result.error.reason).toBe(TransactionErrorReason.REVERTED); - }); - - it(`should fail with ${TransactionError.name}[reason: ${TransactionErrorReason.INDEXING_TIMEOUT}] if the tx is not indexed within a reasonable time`, async () => { - const txHash = mockTransactionHash(); - const apolloClient = mockLensApolloClient([ - mockHasTxHashBeenIndexedResponse({ - variables: { - request: { txId: indexingId }, - }, - data: mockHasTxHashBeenIndexedData({ - indexed: false, - txHash, - }), - }), - ]); - - const transaction = setupTransactionObserver({ - apolloClient, - timings: { - pollingInterval: 1, - maxMiningWaitTime: 1000, // ms - maxIndexingWaitTime: 1, // ms - }, - }); - const result = await transaction.waitForNextIndexingEvent({ indexingId }); - - expect(() => result.unwrap()).toThrow(TransactionError); - expect(result.isFailure() && result.error.reason).toBe( - TransactionErrorReason.INDEXING_TIMEOUT, - ); - }); - }); - - describe(`when invoking ${TransactionObserver.prototype.waitForProxyTransactionStatus.name} with a proxy ID`, () => { - const proxyId = 'proxyId'; - - it(`should succeed with the expected ProxyActionStatusEvent if the action has ${ProxyActionStatusTypes.Complete} status`, async () => { - const txHash = mockTransactionHash(); - const txId = faker.datatype.uuid(); - const responses = [ - mockProxyActionStatusResponse({ - variables: { proxyActionId: proxyId }, - result: { status: ProxyActionStatusTypes.Complete, txHash, txId }, - }), - ]; - const apolloClient = mockLensApolloClient(responses); - const transaction = setupTransactionObserver({ - apolloClient, - }); - - const event = await transaction.waitForProxyTransactionStatus(proxyId); - expect(event.unwrap()).toEqual({ - status: ProxyActionStatus.COMPLETE, - txHash, - }); - }); - - it(`should succeed with the expected ProxyActionStatusEvent if the txHash changes before the action reaches ${ProxyActionStatusTypes.Complete} status`, async () => { - const txId = faker.datatype.uuid(); - const initialTxHash = mockTransactionHash(); - const upgradedTxHash = mockTransactionHash(); - const lastTxHash = mockTransactionHash(); - const responses = [ - mockProxyActionStatusResponse({ - variables: { proxyActionId: proxyId }, - result: { - status: ProxyActionStatusTypes.Minting, - txHash: initialTxHash, - txId, - }, - }), - mockProxyActionStatusResponse({ - variables: { proxyActionId: proxyId }, - result: { - status: ProxyActionStatusTypes.Minting, - txHash: upgradedTxHash, - txId, - }, - }), - mockProxyActionStatusResponse({ - variables: { proxyActionId: proxyId }, - result: { - status: ProxyActionStatusTypes.Complete, - txHash: lastTxHash, - txId, - }, - }), - ]; - const apolloClient = mockLensApolloClient(responses); - const transaction = setupTransactionObserver({ - apolloClient, - }); - - const event = await transaction.waitForProxyTransactionStatus(proxyId); - - expect(event.unwrap()).toEqual({ - status: ProxyActionStatus.COMPLETE, - txHash: upgradedTxHash, - }); - }); - - it(`should fail with ${TransactionError.name} for ${TransactionErrorReason.UNKNOWN} reason if the proxy action returns an error`, async () => { - const apolloClient = mockLensApolloClient([ - mockProxyActionStatusResponse({ - variables: { proxyActionId: proxyId }, - result: { - reason: 'UNKNOWN_ERROR', - lastKnownTxId: faker.datatype.uuid(), - }, - }), - ]); - const transaction = setupTransactionObserver({ - apolloClient, - }); - - const result = await transaction.waitForProxyTransactionStatus(proxyId); - - expect(() => result.unwrap()).toThrow(TransactionError); - expect(result.isFailure() && result.error.reason).toBe(TransactionErrorReason.UNKNOWN); - }); - - it(`should fail with ${TransactionError.name} for ${TransactionErrorReason.INDEXING_TIMEOUT} reason if the action is not completed within a reasonable time frame`, async () => { - const txHash = mockTransactionHash(); - const apolloClient = mockLensApolloClient([ - mockProxyActionStatusResponse({ - variables: { proxyActionId: proxyId }, - result: { - status: ProxyActionStatusTypes.Minting, - txHash: txHash, - txId: faker.datatype.uuid(), - }, - }), - ]); - - const transaction = setupTransactionObserver({ - apolloClient, - timings: { - pollingInterval: 1, - maxMiningWaitTime: 1000, // ms - maxIndexingWaitTime: 0.5, // ms - }, - }); - const result = await transaction.waitForProxyTransactionStatus(proxyId); - - expect(() => result.unwrap()).toThrow(TransactionError); - expect(result.isFailure() && result.error.reason).toBe( - TransactionErrorReason.INDEXING_TIMEOUT, - ); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/infrastructure/__tests__/createPublicationMetadata.spec.ts b/packages/react-v1/src/transactions/infrastructure/__tests__/createPublicationMetadata.spec.ts deleted file mode 100644 index d66970c6eb..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/__tests__/createPublicationMetadata.spec.ts +++ /dev/null @@ -1,326 +0,0 @@ -import { faker } from '@faker-js/faker'; -import { - PublicationMainFocus, - PublicationMetadata, - PublicationMetadataDisplayTypes, - PublicationContentWarning, -} from '@lens-protocol/api-bindings'; -import { - mockChargeCollectPolicyConfig, - mockCreateCommentRequest, - mockCreatePostRequest, - mockDateMetadataAttribute, - mockFreeCollectPolicyConfig, - mockMediaObject, - mockMetadataImage, - mockNftMetadata, - mockNoCollectPolicyConfig, - mockNumberMetadataAttribute, - mockStringMetadataAttribute, -} from '@lens-protocol/domain/mocks'; -import { - CollectPolicyType, - ContentFocus, - ContentWarning, - CreateCommentRequest, - CreatePostRequest, - ImageType, - MediaObject, -} from '@lens-protocol/domain/use-cases/publications'; - -import { appId as toAppId } from '../../../utils'; -import { createPublicationMetadata } from '../createPublicationMetadata'; - -const animationUrl = faker.image.imageUrl(); -const content = faker.lorem.sentence(); -const media = [ - mockMediaObject({ - altTag: 'media', - cover: faker.image.imageUrl(), - }), -]; -const dateNftAttribute = mockDateMetadataAttribute(); -const numberNftAttribute = mockNumberMetadataAttribute(); -const stringNftAttribute = mockStringMetadataAttribute(); -const image = mockMetadataImage(); -const nftMetadata = mockNftMetadata({ - attributes: [dateNftAttribute, numberNftAttribute, stringNftAttribute], - description: faker.lorem.sentence(), - externalUrl: faker.internet.url(), - image: faker.image.imageUrl(), - imageMimeType: ImageType.JPEG, - name: faker.lorem.word(), -}); - -function toPublicationMetadataMediaItem(media: MediaObject) { - return { - item: media.url, - type: media.mimeType, - ...(media.altTag && { altTag: media.altTag }), - ...(media.cover && { cover: media.cover }), - }; -} - -describe(`Given the ${createPublicationMetadata.name} helper`, () => { - describe('when creating PublicationMetadata', () => { - describe.each([ - { request: 'CreatePostRequest', mockPublication: mockCreatePostRequest }, - { request: 'CreateCommentRequest', mockPublication: mockCreateCommentRequest }, - ])('from a $request', ({ mockPublication }) => { - it('should return PublicationMetadata with the expected mandatory fields', () => { - const request = mockPublication({ locale: 'it-IT' }); - - const result = createPublicationMetadata(request); - - expect(result).toMatchObject({ - locale: 'it-IT', - metadata_id: expect.any(String), - version: '2.0.0', - }); - }); - - it('should support optional content-agnostic fields', () => { - const appId = toAppId(faker.word.noun()); - const contentWarning = ContentWarning.NSFW; - const tags = [faker.lorem.word()]; - const request = mockPublication({ - appId, - contentWarning, - tags, - }); - - const result = createPublicationMetadata(request); - - expect(result).toMatchObject({ - appId, - contentWarning: PublicationContentWarning[contentWarning], - tags, - }); - }); - - it(`should support 'name', 'attributes', and 'image'`, () => { - const request = mockPublication({ - attributes: [dateNftAttribute, numberNftAttribute, stringNftAttribute], - image, - name: faker.lorem.word(), - }); - - const metadata = createPublicationMetadata(request); - - expect(metadata).toMatchObject({ - attributes: [ - { - displayType: PublicationMetadataDisplayTypes[dateNftAttribute.displayType], - traitType: dateNftAttribute.traitType, - value: dateNftAttribute.value.toString(), - }, - { - displayType: PublicationMetadataDisplayTypes[numberNftAttribute.displayType], - traitType: numberNftAttribute.traitType, - value: numberNftAttribute.value.toString(), - }, - { - displayType: PublicationMetadataDisplayTypes[stringNftAttribute.displayType], - traitType: stringNftAttribute.traitType, - value: stringNftAttribute.value.toString(), - }, - ], - image: image.url, - imageMimeType: image.mimeType, - name: request.name, - }); - }); - - describe.each<{ - description: string; - request: CreatePostRequest | CreateCommentRequest; - expected: Partial; - }>([ - { - description: 'for a text-only publication', - request: mockPublication({ - content, - contentFocus: ContentFocus.TEXT_ONLY, - }), - expected: { - content, - mainContentFocus: PublicationMainFocus.TextOnly, - }, - }, - { - description: 'for an article publication', - request: mockPublication({ - content, - contentFocus: ContentFocus.ARTICLE, - }), - expected: { - content, - }, - }, - { - description: 'for an article publication with attachments', - request: mockPublication({ - content, - contentFocus: ContentFocus.ARTICLE, - media, - }), - expected: { - content, - media: media.map(toPublicationMetadataMediaItem), - }, - }, - { - description: 'for a link publication', - request: mockPublication({ - content, - contentFocus: ContentFocus.LINK, - }), - expected: { - content, - }, - }, - { - description: 'for an audio publication', - request: mockPublication({ - content, - contentFocus: ContentFocus.AUDIO, - media, - }), - expected: { - content, - media: media.map(toPublicationMetadataMediaItem), - }, - }, - { - description: 'for an image publication', - request: mockPublication({ - content, - contentFocus: ContentFocus.IMAGE, - media, - }), - expected: { - content, - media: media.map(toPublicationMetadataMediaItem), - }, - }, - { - description: 'for a video publication', - request: mockPublication({ - content, - contentFocus: ContentFocus.IMAGE, - media, - }), - expected: { - content, - media: media.map(toPublicationMetadataMediaItem), - }, - }, - { - description: 'for an embed publication', - request: mockPublication({ - content, - contentFocus: ContentFocus.EMBED, - media, - animationUrl, - }), - expected: { - content, - media: media.map(toPublicationMetadataMediaItem), - animation_url: animationUrl, - }, - }, - ])('$description', ({ request, expected }) => { - it('should return the expected metadata', () => { - const metadata = createPublicationMetadata(request); - - expect(metadata).toMatchObject({ - ...expected, - mainContentFocus: PublicationMainFocus[request.contentFocus], - }); - }); - }); - - describe.each([ - mockFreeCollectPolicyConfig({ metadata: nftMetadata }), - mockChargeCollectPolicyConfig({ metadata: nftMetadata }), - ])('with $type collect policy', (collectPolicyConfig) => { - beforeAll(() => { - jest.spyOn(console, 'warn').mockImplementation(() => {}); - }); - - afterAll(() => { - jest.restoreAllMocks(); - }); - - it('should return the expected metadata for collectable publications', () => { - const request = mockPublication({ - collect: collectPolicyConfig, - }); - - const metadata = createPublicationMetadata(request); - - expect(metadata).toMatchObject({ - name: collectPolicyConfig.metadata.name, - description: collectPolicyConfig.metadata.description, - external_url: nftMetadata.externalUrl, - }); - }); - - it(`should be backwards compatible with the deprecated: - - 'collect.metadata.name' - - 'collect.metadata.attributes' - - 'collect.metadata.image' - - 'collect.metadata.imageMimeType'`, () => { - const request = mockPublication({ - /** It should not use these */ - name: faker.lorem.word(), - attributes: [dateNftAttribute], - image: mockMetadataImage(), - /** ----------------------- */ - - collect: collectPolicyConfig, - }); - - const metadata = createPublicationMetadata(request); - - expect(metadata).toMatchObject({ - attributes: [ - { - displayType: PublicationMetadataDisplayTypes[dateNftAttribute.displayType], - traitType: dateNftAttribute.traitType, - value: dateNftAttribute.value.toString(), - }, - { - displayType: PublicationMetadataDisplayTypes[numberNftAttribute.displayType], - traitType: numberNftAttribute.traitType, - value: numberNftAttribute.value.toString(), - }, - { - displayType: PublicationMetadataDisplayTypes[stringNftAttribute.displayType], - traitType: stringNftAttribute.traitType, - value: stringNftAttribute.value.toString(), - }, - ], - image: nftMetadata.image, - imageMimeType: nftMetadata.imageMimeType, - name: nftMetadata.name, - }); - }); - }); - - describe(`with ${CollectPolicyType.NO_COLLECT} collect policy`, () => { - it(`should return the expected basic metadata for non-collectable publications`, () => { - const request = mockPublication({ - collect: mockNoCollectPolicyConfig(), - }); - - const metadata = createPublicationMetadata(request); - - expect(metadata).toMatchObject({ - name: 'none', // although "name" is not needed when a publication is not collectable, our Publication Metadata V2 schema requires it ¯\_(ツ)_/¯ - }); - }); - }); - }); - }); -}); diff --git a/packages/react-v1/src/transactions/infrastructure/createGatedClient.ts b/packages/react-v1/src/transactions/infrastructure/createGatedClient.ts deleted file mode 100644 index 0db87e5bb7..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/createGatedClient.ts +++ /dev/null @@ -1,29 +0,0 @@ -import * as GatedContent from '@lens-protocol/gated-content'; -import { IStorageProvider } from '@lens-protocol/storage'; -import { Signer } from 'ethers'; - -import { EnvironmentConfig } from '../../environments'; - -export type GateClientInit = { - config: GatedContent.AuthenticationConfig; - encryptionProvider: GatedContent.IEncryptionProvider; - environment: EnvironmentConfig; - signer: Signer; - storageProvider: IStorageProvider; -}; - -export function createGatedClient({ - config, - signer, - environment, - encryptionProvider, - storageProvider, -}: GateClientInit) { - return new GatedContent.GatedClient({ - authentication: config, - signer, - environment: environment.gated, - encryptionProvider, - storageProvider, - }); -} diff --git a/packages/react-v1/src/transactions/infrastructure/createPublicationMetadata.ts b/packages/react-v1/src/transactions/infrastructure/createPublicationMetadata.ts deleted file mode 100644 index ec0e5a3d27..0000000000 --- a/packages/react-v1/src/transactions/infrastructure/createPublicationMetadata.ts +++ /dev/null @@ -1,169 +0,0 @@ -/* eslint-disable no-console */ -import { - PublicationMetadata, - PublicationMainFocus, - PublicationMetadataDisplayTypes, - PublicationMetadataMediaInput, - PublicationContentWarning, -} from '@lens-protocol/api-bindings'; -import { - CollectablePolicyConfig, - CollectPolicyType, - ContentFocus, - CreateCommentRequest, - CreatePostRequest, - MediaObject, - MetadataAttribute, -} from '@lens-protocol/domain/use-cases/publications'; -import { assertNever, Overwrite } from '@lens-protocol/shared-kernel'; -import { v4 } from 'uuid'; - -type CreatePublicationRequest = CreatePostRequest | CreateCommentRequest; - -type CollectablePublicationRequest = Overwrite< - CreatePublicationRequest, - { collect: CollectablePolicyConfig } ->; - -function mapMetadataAttributes(attributes: MetadataAttribute[]) { - return attributes.map(({ displayType, value, ...rest }) => { - return { - ...rest, - value: value.toString(), - displayType: PublicationMetadataDisplayTypes[displayType], - }; - }); -} - -function mapMedia(media: MediaObject): PublicationMetadataMediaInput { - return { - item: media.url, - type: media.mimeType, - ...(media.altTag && { altTag: media.altTag }), - ...(media.cover && { cover: media.cover }), - }; -} - -function essentialFields(request: CreatePublicationRequest) { - return { - metadata_id: v4(), - version: '2.0.0', - locale: request.locale, - mainContentFocus: PublicationMainFocus[request.contentFocus], - } as const; -} - -function metadataImage(request: CreatePublicationRequest) { - if (!request.image) { - return undefined; - } - return { - image: request.image.url, - imageMimeType: request.image.mimeType, - } as const; -} - -function optionalFields(request: CreatePublicationRequest) { - return { - name: request.name ?? 'none', // Publication Metadata V2 schema requires it ¯\_(ツ)_/¯ - attributes: mapMetadataAttributes(request.attributes ?? []), - ...(request.appId && { appId: request.appId }), - ...(request.contentWarning && { - contentWarning: PublicationContentWarning[request.contentWarning], - }), - ...(request.tags && { tags: request.tags }), - ...metadataImage(request), - } as const; -} - -function contentFields(request: CreatePublicationRequest) { - switch (request.contentFocus) { - case ContentFocus.VIDEO: - case ContentFocus.IMAGE: - case ContentFocus.AUDIO: - case ContentFocus.LINK: - case ContentFocus.ARTICLE: - return { - content: request.content, - media: request.media?.map(mapMedia), - } as const; - - case ContentFocus.TEXT_ONLY: - return { - content: request.content, - } as const; - - case ContentFocus.EMBED: - return { - animation_url: request.animationUrl, - content: request.content, - media: request.media?.map(mapMedia), - } as const; - } -} - -function resolveDeprecatedCollectableMetadata(request: CollectablePublicationRequest) { - return { - attributes: mapMetadataAttributes(request.collect.metadata.attributes ?? []), - image: request.collect.metadata.image, - imageMimeType: request.collect.metadata.imageMimeType, - name: request.collect.metadata.name, - } as const; -} - -function resolveCollectableMetadata(request: CollectablePublicationRequest) { - if ('name' in request.collect.metadata && 'name' in request) { - console.warn( - 'Both "name" and "collect.metadata.name" are provided. Using "collect.metadata.name"', - ); - } - if ('attributes' in request.collect.metadata && 'attributes' in request) { - console.warn( - 'Both "attributes" and "collect.metadata.attributes" are provided. Using "collect.metadata.attributes"', - ); - } - if ('image' in request.collect.metadata && 'image' in request) { - console.warn( - 'Both "image" and "collect.metadata.image" are provided. Using "collect.metadata.image"', - ); - } - - if ('imageMimeType' in request.collect.metadata && 'image' in request) { - console.warn( - 'Both "image" and "collect.metadata.imageMimeType" are provided. Using "collect.metadata.image"', - ); - } - - return { - description: request.collect.metadata.description, - - ...resolveDeprecatedCollectableMetadata(request), - - ...(request.collect.metadata.externalUrl && { - external_url: request.collect.metadata.externalUrl, - }), - } as const; -} - -function resolveCollectMetadata(request: CreatePublicationRequest) { - switch (request.collect.type) { - case CollectPolicyType.NO_COLLECT: - return {}; - - case CollectPolicyType.CHARGE: - case CollectPolicyType.FREE: - return resolveCollectableMetadata(request as CollectablePublicationRequest); - - default: - assertNever(request.collect, `Unexpected collect policy type`); - } -} - -export function createPublicationMetadata(request: CreatePublicationRequest): PublicationMetadata { - return { - ...essentialFields(request), - ...optionalFields(request), - ...contentFields(request), - ...resolveCollectMetadata(request), - }; -} diff --git a/packages/react-v1/src/transactions/useApproveModule.ts b/packages/react-v1/src/transactions/useApproveModule.ts deleted file mode 100644 index 7b490a32c6..0000000000 --- a/packages/react-v1/src/transactions/useApproveModule.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { TransactionState, useWaitUntilTransactionSettled } from '@lens-protocol/api-bindings'; -import { - InsufficientGasError, - PendingSigningRequestError, - TransactionError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - TokenAllowanceLimit, - TokenAllowanceRequest, -} from '@lens-protocol/domain/use-cases/wallets'; -import { - Amount, - Erc20, - EthereumAddress, - failure, - PromiseResult, -} from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useApproveModuleController } from './adapters/useApproveModuleController'; - -export type ApproveModuleArgs = { - amount: Amount; - limit: TokenAllowanceLimit; - spender: EthereumAddress; -}; - -export { TokenAllowanceLimit }; - -export type ApproveModuleOperation = Operation< - void, - | InsufficientGasError - | PendingSigningRequestError - | TransactionError - | UserRejectedError - | WalletConnectionError, - [ApproveModuleArgs] ->; - -/** - * `useApproveModule` is a hook that lets you approve a Lens module to access the authenticated wallet Erc20 for the purpose of paying a fee - * - * You MUST be authenticated via {@link useWalletLogin} to use this hook. - * - * @category Misc - * @group Hooks - * - * @example - * Approve a collect module for the amount specified in the publication collect policy - * ```tsx - * import { useApproveModule, CollectPolicyType, CollectablePublication, TokenAllowanceLimit } from '@lens-protocol/react-web'; - * - * function ApproveCollect({ publication }: { publication: CollectablePublication }) { - * const { execute: approve, error, loading } = useApproveModule(); - * - * const handleClick = async () => { - * if (publication.collectPolicy.type === CollectPolicyType.CHARGE) { - * const result = await approve({ - * // The collect fee amount - * amount: publication.collectPolicy.amount, - * - * // The collect module contract address - * spender: publication.collectPolicy.contractAddress, - * - * // In this case we want to approve the exact amount - * limit: TokenAllowanceLimit.EXACT, - * }) - * } - * }; - * - * return ( - * - * ); - * } - * ``` - */ -export function useApproveModule(): ApproveModuleOperation { - const setAllowance = useApproveModuleController(); - - const waitUntilTransactionIsSettled = useWaitUntilTransactionSettled(); - - return useOperation( - async ({ - amount, - limit, - spender, - }: ApproveModuleArgs): PromiseResult< - void, - | InsufficientGasError - | PendingSigningRequestError - | TransactionError - | UserRejectedError - | WalletConnectionError - > => { - try { - const result = await setAllowance({ - amount, - kind: TransactionKind.APPROVE_MODULE, - limit, - spender, - }); - - if (result.isSuccess()) { - await waitUntilTransactionIsSettled( - (transaction): transaction is TransactionState => - transaction.request.kind === TransactionKind.APPROVE_MODULE && - transaction.request.spender === spender && - transaction.request.amount.asset === amount.asset, - ); - } - - return result; - } catch (e) { - if (e instanceof TransactionError) { - return failure(e); - } - throw e; - } - }, - ); -} diff --git a/packages/react-v1/src/transactions/useClearRecentPosts.ts b/packages/react-v1/src/transactions/useClearRecentPosts.ts deleted file mode 100644 index 37bff6b605..0000000000 --- a/packages/react-v1/src/transactions/useClearRecentPosts.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { recentPosts } from './adapters/responders/CreatePostResponder'; - -/** - * @category Publications - * @group Hooks - */ -export function useClearRecentPosts() { - return () => { - recentPosts([]); - }; -} diff --git a/packages/react-v1/src/transactions/useCollect.ts b/packages/react-v1/src/transactions/useCollect.ts deleted file mode 100644 index eb2400c482..0000000000 --- a/packages/react-v1/src/transactions/useCollect.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - createCollectRequest, - ProfileOwnedByMe, - AnyPublication, -} from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { - InsufficientAllowanceError, - InsufficientFundsError, -} from '@lens-protocol/domain/use-cases/wallets'; - -import { Operation, useOperation } from '../helpers/operations'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { useCollectController } from './adapters/useCollectController'; - -export type UseCollectArgs = { - collector: ProfileOwnedByMe; - publication: AnyPublication; -}; - -export type CollectOperation = Operation< - AsyncTransactionResult, - | BroadcastingError - | InsufficientAllowanceError - | InsufficientFundsError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError ->; - -/** - * @category Publications - * @group Hooks - */ -export function useCollect({ collector, publication }: UseCollectArgs): CollectOperation { - const collect = useCollectController(); - return useOperation(async () => collect(createCollectRequest(publication, collector))); -} diff --git a/packages/react-v1/src/transactions/useCreateComment.ts b/packages/react-v1/src/transactions/useCreateComment.ts deleted file mode 100644 index 35a93e6434..0000000000 --- a/packages/react-v1/src/transactions/useCreateComment.ts +++ /dev/null @@ -1,272 +0,0 @@ -import { isDataAvailabilityPublicationId, ProfileOwnedByMe } from '@lens-protocol/api-bindings'; -import { - AppId, - PendingSigningRequestError, - PublicationId, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - CollectPolicyConfig, - CollectPolicyType, - ContentFocus, - ContentWarning, - Locale, - MediaObject, - MetadataAttribute, - MetadataImage, - ReferencePolicyConfig, - ReferencePolicyType, -} from '@lens-protocol/domain/use-cases/publications'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { failure, PromiseResult, Url } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useSharedDependencies } from '../shared'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { FailedUploadError } from './adapters/IMetadataUploader'; -import { MetadataUploadHandler } from './adapters/MetadataUploadHandler'; -import { useCreateCommentController } from './adapters/useCreateCommentController'; - -export type UseCreateCommentArg = { - publisher: ProfileOwnedByMe; - upload: MetadataUploadHandler; -}; - -/** - * @alpha - */ -export type CreateCommentBaseArgs = { - /** - * @deprecated This was exposed by mistake but was never used. See {@link LensConfig} instead. - */ - appId?: AppId; - /** - * The publication collect policy. Determines the criteria that must be met for a user to be able to collect the publication. - * - * @defaultValue `{ type: CollectPolicyType.NO_COLLECT }` - */ - collect?: CollectPolicyConfig; - /** - * Specifies a content warning for the publication. - */ - contentWarning?: ContentWarning; - /** - * The language of the publication. - * - * It's a locale string in the format of `-` or just ``, where: - * - `language-tag` is a two-letter ISO 639-1 language code, e.g. `en` or `it` - * - `region-tag` is a two-letter ISO 3166-1 alpha-2 region code, e.g. `US` or `IT` - * - * You can just pass in the language tag if you do not know the region or don't need to be specific. - */ - locale: Locale; - /** - * The publication ID to which the publication is being posted. - */ - publicationId: PublicationId; - /** - * The publication reference policy. Determines the criteria that must be met for a user to be able to publication or mirror the publication. - * - * @defaultValue `{ type: ReferencePolicyType.ANYONE }` - */ - reference?: ReferencePolicyConfig; - /** - * A list of tags for the publication. This can be used to categorize the publication. - * - * These are not the same as #hashtag in the publication content. Use these if you don't want to clutter the publication content with tags. - */ - tags?: string[]; - /** - * The name of the collect NFT. - * - * This is the NFT name visible on marketplaces like OpenSea. - */ - name?: string; - /** - * A list of attributes for the collect NFT. - * - * This is the NFT description visible on marketplaces like OpenSea. - */ - attributes?: MetadataAttribute[]; - /** - * The collect NFT image. - * - * This is the NFT image visible on marketplaces like OpenSea. - * - * DO NOT use this as primary storage for publication media. Use the `media` property instead. - * In the case your publication has many media consider to use this field as a static representation - * of the collect NFT. For example if the publication is an album of audio files this could be - * used as album cover image. If the publication is a gallery of images, this could be the gallery - * cover image. - * - * DO NOT use this as media cover image. - * For individual media cover image (e.g. the video thumbnail image) use the `media[n].cover` (see {@link MediaObject}). - */ - image?: MetadataImage; -}; - -export type CreateTextualCommentArgs = CreateCommentBaseArgs & { - /** - * The publication content as Markdown string. - */ - content: string; - /** - * The publication focus. - */ - contentFocus: ContentFocus.ARTICLE | ContentFocus.LINK | ContentFocus.TEXT_ONLY; - /** - * The publication media. An array of media objects. - */ - media?: MediaObject[]; -}; - -export type CreateMediaCommentArgs = CreateCommentBaseArgs & { - /** - * Contextual information as Markdown string. - */ - content?: string; - /** - * The publication focus. - */ - contentFocus: ContentFocus.AUDIO | ContentFocus.IMAGE | ContentFocus.VIDEO; - /** - * The publication media. An array of media objects. - */ - media: MediaObject[]; -}; - -export type CreateEmbedCommentArgs = CreateCommentBaseArgs & { - /** - * A URL to a multi-media attachment for the item. The file extensions GLTF, GLB, WEBM, MP4, M4V, OGV, and OGG are supported. - * It also supports HTML pages, allowing you to build rich experiences and interactive NFTs using JavaScript canvas, - * WebGL, and more. Scripts and relative paths within the HTML page are now supported. However, access to browser extensions is not supported. - */ - animationUrl: Url; - /** - * Contextual information as Markdown string. - */ - content?: string; - /** - * The publication focus. - */ - contentFocus: ContentFocus.EMBED; - /** - * The publication media. An array of media objects. - */ - media?: MediaObject[]; -}; - -export type CreateCommentArgs = - | CreateTextualCommentArgs - | CreateMediaCommentArgs - | CreateEmbedCommentArgs; - -export type CreateCommentOperation = Operation< - AsyncTransactionResult, - | BroadcastingError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - | FailedUploadError, - [CreateCommentArgs] ->; - -/** - * Comment on a post or comment. - * - * @category Publications - * @group Hooks - * @param args - {@link UseCreateCommentArg} - * - * @example - * Create a text-only comment - * ```ts - * import { uploadToIpfs } from './myIpfsUploader'; - * import { ContentFocus, ContentPublication, ProfileOwnedByMe, useCreateComment } from '@lens-protocol/react-web'; - * - * function CommentComposer({ commentOn: ContentPublication, publisher }: { publisher: ProfileOwnedByMe }) { - * const { execute: comment, error, isPending } = useCreateComment({ publisher, upload: uploadToIpfs }); - * - * const submit = async (event: React.FormEvent) => { - * event.preventDefault(); - * - * const form = event.currentTarget; - * - * const formData = new FormData(form); - * const content = (formData.get('content') as string | null) ?? never(); - * - * let result = await comment({ - * content, - * contentFocus: ContentFocus.TEXT_ONLY, - * locale: 'en', - * }); - * - * if (result.isSuccess()) { - * form.reset(); - * } - * }; - * - * return ( - *
- * - * - * - * - * {error &&
{error.message}
} - *
- * ); - * } - * ``` - */ -export function useCreateComment({ - publisher, - upload, -}: UseCreateCommentArg): CreateCommentOperation { - const { appId } = useSharedDependencies(); - const createComment = useCreateCommentController({ upload }); - - return useOperation( - async ({ - collect = { type: CollectPolicyType.NO_COLLECT }, - reference = { type: ReferencePolicyType.ANYONE }, - ...args - }: CreateCommentArgs): PromiseResult< - AsyncTransactionResult, - | BroadcastingError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - | FailedUploadError - > => { - try { - return await createComment({ - kind: TransactionKind.CREATE_COMMENT, - delegate: publisher.dispatcher !== null, - collect, - profileId: publisher.id, - reference, - appId, - offChain: isDataAvailabilityPublicationId(args.publicationId), - ...args, - }); - } catch (err: unknown) { - if (err instanceof FailedUploadError) { - return failure(err); - } - throw err; - } - }, - ); -} diff --git a/packages/react-v1/src/transactions/useCreateEncryptedComment.ts b/packages/react-v1/src/transactions/useCreateEncryptedComment.ts deleted file mode 100644 index 762b70ea37..0000000000 --- a/packages/react-v1/src/transactions/useCreateEncryptedComment.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { ProfileOwnedByMe } from '@lens-protocol/api-bindings'; -import { - DecryptionCriteria, - PendingSigningRequestError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - CollectPolicyType, - ReferencePolicyType, -} from '@lens-protocol/domain/use-cases/publications'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { Distribute, failure, PromiseResult } from '@lens-protocol/shared-kernel'; - -import { EncryptionConfig } from '../config'; -import { Operation, useOperation } from '../helpers/operations'; -import { useSharedDependencies } from '../shared'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { FailedUploadError } from './adapters/IMetadataUploader'; -import { MetadataUploadHandler } from './adapters/MetadataUploadHandler'; -import { useCreateEncryptedCommentController } from './adapters/useCreateEncryptedCommentController'; -import { CreateCommentArgs } from './useCreateComment'; - -export type UseCreateEncryptedCommentArgs = { - encryption: EncryptionConfig; - publisher: ProfileOwnedByMe; - upload: MetadataUploadHandler; -}; - -export type CreateEncryptedCommentArgs = Distribute< - CreateCommentArgs, - { - /** - * The criteria that must be met for a user to be able to decrypt the comment. - */ - decryptionCriteria: DecryptionCriteria; - } ->; - -export type CreateEncryptedCommentOperation = Operation< - AsyncTransactionResult, - | BroadcastingError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - | FailedUploadError, - [CreateEncryptedCommentArgs] ->; - -/** - * @category Publications - * @group Hooks - * @param args - {@link UseCreateEncryptedCommentArgs} - */ -export function useCreateEncryptedComment({ - encryption, - publisher, - upload, -}: UseCreateEncryptedCommentArgs): CreateEncryptedCommentOperation { - const { appId } = useSharedDependencies(); - const createComment = useCreateEncryptedCommentController({ encryption, upload }); - - return useOperation( - async ({ - collect = { type: CollectPolicyType.NO_COLLECT }, - reference = { type: ReferencePolicyType.ANYONE }, - ...args - }: CreateEncryptedCommentArgs): PromiseResult< - AsyncTransactionResult, - | BroadcastingError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - | FailedUploadError - > => { - try { - return await createComment({ - kind: TransactionKind.CREATE_COMMENT, - collect, - delegate: publisher.dispatcher !== null, - profileId: publisher.id, - reference, - appId, - offChain: false, // For now, we only support on-chain token-gated comments - ...args, - }); - } catch (err: unknown) { - if (err instanceof FailedUploadError) { - return failure(err); - } - throw err; - } - }, - ); -} diff --git a/packages/react-v1/src/transactions/useCreateEncryptedPost.ts b/packages/react-v1/src/transactions/useCreateEncryptedPost.ts deleted file mode 100644 index 543bdc09b3..0000000000 --- a/packages/react-v1/src/transactions/useCreateEncryptedPost.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { ProfileOwnedByMe } from '@lens-protocol/api-bindings'; -import { - DecryptionCriteria, - PendingSigningRequestError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - CollectPolicyType, - ReferencePolicyType, -} from '@lens-protocol/domain/use-cases/publications'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { Distribute, failure, PromiseResult } from '@lens-protocol/shared-kernel'; - -import { EncryptionConfig } from '../config'; -import { Operation, useOperation } from '../helpers/operations'; -import { useSharedDependencies } from '../shared'; -import { FailedUploadError } from './adapters/IMetadataUploader'; -import { MetadataUploadHandler } from './adapters/MetadataUploadHandler'; -import { useCreateEncryptedPostController } from './adapters/useCreateEncryptedPostController'; -import { CreatePostArgs, CreatePostAsyncResult } from './useCreatePost'; - -export type UseCreateEncryptedPostArgs = { - /** - * The encryption configuration. - */ - encryption: EncryptionConfig; - /** - * The publisher profile. - */ - publisher: ProfileOwnedByMe; - /** - * The metadata upload handler. - */ - upload: MetadataUploadHandler; -}; - -export type CreateEncryptedPostArgs = Distribute< - CreatePostArgs, - { - /** - * The criteria that must be met for a user to be able to decrypt the post. - */ - decryptionCriteria: DecryptionCriteria; - } ->; - -export type CreateEncryptedPostOperation = Operation< - CreatePostAsyncResult, - | BroadcastingError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - | FailedUploadError, - [CreateEncryptedPostArgs] ->; - -/** - * @category Publications - * @group Hooks - * @param args - {@link UseCreateEncryptedPostArgs} - */ -export function useCreateEncryptedPost({ - encryption, - publisher, - upload, -}: UseCreateEncryptedPostArgs): CreateEncryptedPostOperation { - const { appId } = useSharedDependencies(); - const createPost = useCreateEncryptedPostController({ encryption, upload }); - - return useOperation( - async ({ - collect = { type: CollectPolicyType.NO_COLLECT }, - reference = { type: ReferencePolicyType.ANYONE }, - ...args - }: CreateEncryptedPostArgs): PromiseResult< - CreatePostAsyncResult, - | BroadcastingError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - | FailedUploadError - > => { - try { - return await createPost({ - kind: TransactionKind.CREATE_POST, - collect, - delegate: publisher.dispatcher !== null, - profileId: publisher.id, - reference, - appId, - offChain: false, // For now, we only support on-chain token-gated comments - ...args, - }); - } catch (err: unknown) { - if (err instanceof FailedUploadError) { - return failure(err); - } - throw err; - } - }, - ); -} diff --git a/packages/react-v1/src/transactions/useCreateMirror.ts b/packages/react-v1/src/transactions/useCreateMirror.ts deleted file mode 100644 index 72de89afd6..0000000000 --- a/packages/react-v1/src/transactions/useCreateMirror.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - Comment, - isDataAvailabilityPublicationId, - Post, - ProfileOwnedByMe, -} from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; - -import { Operation, useOperation } from '../helpers/operations'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { useCreateMirrorController } from './adapters/useCreateMirrorController'; - -export type UseCreateMirrorArgs = { - publisher: ProfileOwnedByMe; -}; - -export type CreateMirrorArgs = { - publication: Post | Comment; -}; - -export type CreateMirrorOperation = Operation< - AsyncTransactionResult, - BroadcastingError | PendingSigningRequestError | UserRejectedError | WalletConnectionError, - [CreateMirrorArgs] ->; - -/** - * @category Publications - * @group Hooks - * @param args - {@link UseCreateMirrorArgs} - */ -export function useCreateMirror({ publisher }: UseCreateMirrorArgs): CreateMirrorOperation { - const createMirror = useCreateMirrorController(); - - return useOperation(async ({ publication }: CreateMirrorArgs) => - createMirror({ - kind: TransactionKind.MIRROR_PUBLICATION, - publicationId: publication.id, - profileId: publisher.id, - delegate: publisher.dispatcher !== null, - offChain: isDataAvailabilityPublicationId(publication.id), - }), - ); -} diff --git a/packages/react-v1/src/transactions/useCreatePost.ts b/packages/react-v1/src/transactions/useCreatePost.ts deleted file mode 100644 index c883836c5a..0000000000 --- a/packages/react-v1/src/transactions/useCreatePost.ts +++ /dev/null @@ -1,275 +0,0 @@ -import { Post, ProfileOwnedByMe } from '@lens-protocol/api-bindings'; -import { - AppId, - PendingSigningRequestError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - CollectPolicyConfig, - CollectPolicyType, - ContentFocus, - ContentWarning, - CreatePostRequest, - Locale, - MediaObject, - MetadataAttribute, - MetadataImage, - ReferencePolicyConfig, - ReferencePolicyType, -} from '@lens-protocol/domain/use-cases/publications'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { failure, PromiseResult, Url } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useSharedDependencies } from '../shared'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { FailedUploadError } from './adapters/IMetadataUploader'; -import { MetadataUploadHandler } from './adapters/MetadataUploadHandler'; -import { useCreatePostController } from './adapters/useCreatePostController'; - -export type UseCreatePostArgs = { - /** - * The post author. - * - * **Poo-tip**: use the profile instance returned by {@link useActiveProfile} to create a post in behalf of the active profile. - */ - publisher: ProfileOwnedByMe; - /** - * The handler that will be used to upload the post metadata. - */ - upload: MetadataUploadHandler; -}; - -/** - * @alpha - */ -export type CreatePostBaseArgs = { - /** - * @deprecated This was exposed by mistake but was never used. See {@link LensConfig} instead. - */ - appId?: AppId; - /** - * The publication collect policy. Determines the criteria that must be met for a user to be able to collect the publication. - */ - collect?: CollectPolicyConfig; - /** - * Specifies a content warning for the publication. - * - * @defaultValue `{ type: CollectPolicyType.NO_COLLECT }` - */ - contentWarning?: ContentWarning; - /** - * The language of the publication. - * - * It's a locale string in the format of `-` or just ``, where: - * - `language-tag` is a two-letter ISO 639-1 language code, e.g. `en` or `it` - * - `region-tag` is a two-letter ISO 3166-1 alpha-2 region code, e.g. `US` or `IT` - * - * You can just pass in the language tag if you do not know the region or don't need to be specific. - */ - locale: Locale; - /** - * The publication reference policy. Determines the criteria that must be met for a user to be able to publication or mirror the publication. - * - * @defaultValue `{ type: ReferencePolicyType.ANYONE }` - */ - reference?: ReferencePolicyConfig; - /** - * A list of tags for the publication. This can be used to categorize the publication. - * - * These are not the same as #hashtag in the publication content. Use these if you don't want to clutter the publication content with tags. - */ - tags?: string[]; - /** - * The name of the collect NFT. - * - * This is the NFT name visible on marketplaces like OpenSea. - */ - name?: string; - /** - * A list of attributes for the collect NFT. - * - * This is the NFT description visible on marketplaces like OpenSea. - */ - attributes?: MetadataAttribute[]; - /** - * The collect NFT image. - * - * This is the NFT image visible on marketplaces like OpenSea. - * - * DO NOT use this as primary storage for publication media. Use the `media` property instead. - * In the case your publication has many media consider to use this field as a static representation - * of the collect NFT. For example if the publication is an album of audio files this could be - * used as album cover image. If the publication is a gallery of images, this could be the gallery - * cover image. - * - * DO NOT use this as media cover image. - * For individual media cover image (e.g. the video thumbnail image) use the `media[n].cover` (see {@link MediaObject}). - */ - image?: MetadataImage; -}; - -export type CreateTextualPostArgs = CreatePostBaseArgs & { - /** - * The publication content as Markdown string. - */ - content: string; - /** - * The publication focus. - */ - contentFocus: ContentFocus.ARTICLE | ContentFocus.LINK | ContentFocus.TEXT_ONLY; - /** - * The publication media. An array of media objects. - */ - media?: MediaObject[]; -}; - -export type CreateMediaPostArgs = CreatePostBaseArgs & { - /** - * Contextual information as Markdown string. - */ - content?: string; - /** - * The publication focus. - */ - contentFocus: ContentFocus.AUDIO | ContentFocus.IMAGE | ContentFocus.VIDEO; - /** - * The publication media. An array of media objects. - */ - media: MediaObject[]; -}; - -export type CreateEmbedPostArgs = CreatePostBaseArgs & { - /** - * A URL to a multi-media attachment for the item. The file extensions GLTF, GLB, WEBM, MP4, M4V, OGV, and OGG are supported. - * It also supports HTML pages, allowing you to build rich experiences and interactive NFTs using JavaScript canvas, - * WebGL, and more. Scripts and relative paths within the HTML page are now supported. However, access to browser extensions is not supported. - */ - animationUrl: Url; - /** - * Contextual information as Markdown string. - */ - content?: string; - /** - * The publication focus. - */ - contentFocus: ContentFocus.EMBED; - /** - * The publication media. An array of media objects. - */ - media?: MediaObject[]; -}; - -export type CreatePostArgs = CreateTextualPostArgs | CreateMediaPostArgs | CreateEmbedPostArgs; - -export type CreatePostAsyncResult = AsyncTransactionResult; - -export type CreatePostOperation = Operation< - CreatePostAsyncResult, - | BroadcastingError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - | FailedUploadError, - [CreatePostArgs] ->; - -/** - * `useCreatePost` hook let you create a new post. - * - * You MUST be authenticated via {@link useWalletLogin} to use this hook. - * - * @category Publications - * @group Hooks - * @param args - {@link UseCreatePostArgs} - * - * @example - * Create a short text-only post - * ```ts - * import { uploadToIpfs } from './myIpfsUploader'; - * import { ContentFocus, ProfileOwnedByMe, useCreatePost } from '@lens-protocol/react-web'; - * - * function PostComposer({ publisher }: { publisher: ProfileOwnedByMe }) { - * const { execute: post, error, isPending } = useCreatePost({ publisher, upload: uploadToIpfs }); - * - * const submit = async (event: React.FormEvent) => { - * event.preventDefault(); - * - * const form = event.currentTarget; - * - * const formData = new FormData(form); - * const content = (formData.get('content') as string | null) ?? never(); - * - * let result = await post({ - * content, - * contentFocus: ContentFocus.TEXT_ONLY, - * locale: 'en', - * }); - * - * if (result.isSuccess()) { - * form.reset(); - * } - * }; - * - * return ( - *
- * - * - * - * - * {error &&
{error.message}
} - *
- * ); - * } - * ``` - */ -export function useCreatePost({ publisher, upload }: UseCreatePostArgs): CreatePostOperation { - const { appId } = useSharedDependencies(); - const createPost = useCreatePostController({ upload }); - - return useOperation( - async ({ - collect = { type: CollectPolicyType.NO_COLLECT }, - reference = { type: ReferencePolicyType.ANYONE }, - ...args - }: CreatePostArgs): PromiseResult< - CreatePostAsyncResult, - | BroadcastingError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - | FailedUploadError - > => { - try { - const request: CreatePostRequest = { - kind: TransactionKind.CREATE_POST, - collect, - delegate: publisher.dispatcher !== null, - profileId: publisher.id, - reference, - appId, - offChain: collect.type === CollectPolicyType.NO_COLLECT, - ...args, - }; - return await createPost(request); - } catch (err: unknown) { - if (err instanceof FailedUploadError) { - return failure(err); - } - throw err; - } - }, - ); -} diff --git a/packages/react-v1/src/transactions/useFollow.ts b/packages/react-v1/src/transactions/useFollow.ts deleted file mode 100644 index 3a891ec945..0000000000 --- a/packages/react-v1/src/transactions/useFollow.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { - ProfileOwnedByMe, - Profile, - isUnfollowTransactionFor, - useHasPendingTransaction, -} from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { FollowPolicyType, FollowRequest } from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { - InsufficientAllowanceError, - InsufficientFundsError, -} from '@lens-protocol/domain/use-cases/wallets'; -import { failure, invariant, InvariantError, PromiseResult } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { useFollowController } from './adapters/useFollowController'; - -export class PrematureFollowError extends Error { - name = 'PrematureFollowError' as const; -} - -function createFollowRequest(followee: Profile, follower: Profile): FollowRequest { - const followPolicy = followee.followPolicy; - switch (followPolicy.type) { - case FollowPolicyType.CHARGE: - return { - fee: { - amount: followPolicy.amount, - contractAddress: followPolicy.contractAddress, - recipient: followPolicy.recipient, - }, - kind: TransactionKind.FOLLOW_PROFILES, - profileId: followee.id, - followerAddress: follower.ownedBy, - }; - case FollowPolicyType.ONLY_PROFILE_OWNERS: - return { - kind: TransactionKind.FOLLOW_PROFILES, - profileId: followee.id, - followerAddress: follower.ownedBy, - followerProfileId: follower.id, - }; - case FollowPolicyType.ANYONE: - return { - kind: TransactionKind.FOLLOW_PROFILES, - profileId: followee.id, - followerAddress: follower.ownedBy, - }; - case FollowPolicyType.NO_ONE: - throw new InvariantError( - `The profile is configured so that nobody can follow it. Check 'profile.followPolicy.type' beforehand.`, - ); - case FollowPolicyType.UNKNOWN: - throw new InvariantError( - `The profile is configured with an unknown follow module. Check 'profile.followPolicy.type' beforehand.`, - ); - } -} - -export type UseFollowArgs = { - /** - * The profile to follow - */ - followee: Profile; - - /** - * The profile that follows - */ - follower: ProfileOwnedByMe; -}; - -export type FollowOperation = Operation< - AsyncTransactionResult, - | BroadcastingError - | InsufficientAllowanceError - | InsufficientFundsError - | PendingSigningRequestError - | PrematureFollowError - | UserRejectedError - | WalletConnectionError ->; - -/** - * `useFollow` is a hook that lets you follow a profile - * - * You MUST be authenticated via {@link useWalletLogin} to use this hook. - * - * The hook `execute` function resolves with a {@link Result} when the corresponding operation is queued. - * You can use the {@link Success.isSuccess | `Result.isSuccess`} (or {@link Failure.isFailure | `Result.isFailure`}) method - * to check if the operation queuing was successful and determine the next step if not. - * - * **Pro-tip**: use the {@link ProfileOwnedByMe} instance from {@link useActiveProfile} (or {@link useProfilesOwnedByMe}) as the `follower` argument. - * - * You can use the {@link FollowStatus | `followee.followStatus`} property to determine the status of the follow request and if you should show the follow button. - * - * @category Profiles - * @group Hooks - * @param args - {@link UseFollowArgs} - * - * @example - * Follow a profile with {@link OpenFollowPolicy} - * ```ts - * import { useFollow, Profile, ProfileOwnedByMe } from '@lens-protocol/react-web'; - * - * function FollowButton({ followee, follower }: { followee: Profile; follower: ProfileOwnedByMe }) { - * const { execute, error, isPending } = useFollow({ followee, follower }); - * - * const follow = async () => { - * const result = await execute(); - * - * if (result.isFailure()) { - * console.error(result.error); - * } - * } - * - * if (followee.followStatus.canFollow === false) { - * return null; - * } - * - * if (followee.followStatus.isFollowedByMe) { - * return ( - *

You are following this profile

- * ) - * } - * - * return ( - * - * ); - * } - * ``` - */ -export function useFollow({ followee, follower }: UseFollowArgs): FollowOperation { - const follow = useFollowController(); - - const hasPendingUnfollowTx = useHasPendingTransaction( - isUnfollowTransactionFor({ profileId: followee.id }), - ); - - return useOperation( - async (): PromiseResult< - AsyncTransactionResult, - | BroadcastingError - | InsufficientAllowanceError - | InsufficientFundsError - | PendingSigningRequestError - | PrematureFollowError - | UserRejectedError - | WalletConnectionError - > => { - if (hasPendingUnfollowTx) { - return failure( - new PrematureFollowError( - `A previous unfollow request for ${followee.handle} is still pending. Make sure you check 'followee.followStatus.canFollow' beforehand.`, - ), - ); - } - - invariant( - followee.followStatus?.canFollow, - "You're already following this profile. Check the `followee.followStatus.canFollow` to determine if you can call `useFollow`.", - ); - - const request = createFollowRequest(followee, follower); - return follow(request); - }, - ); -} diff --git a/packages/react-v1/src/transactions/useRecentPosts.ts b/packages/react-v1/src/transactions/useRecentPosts.ts deleted file mode 100644 index 45c24f5c8d..0000000000 --- a/packages/react-v1/src/transactions/useRecentPosts.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { useReactiveVar } from '@apollo/client'; - -import { recentPosts } from './adapters/responders/CreatePostResponder'; - -/** - * @category Publications - * @group Hooks - */ -export function useRecentPosts() { - return useReactiveVar(recentPosts); -} diff --git a/packages/react-v1/src/transactions/useRecentTransactions.ts b/packages/react-v1/src/transactions/useRecentTransactions.ts deleted file mode 100644 index bbfa563c2a..0000000000 --- a/packages/react-v1/src/transactions/useRecentTransactions.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { useRecentTransactionsVar } from '@lens-protocol/api-bindings'; - -import { useSharedDependencies } from '../shared'; - -export { TxStatus } from '@lens-protocol/api-bindings'; - -export type { - TransactionState, - PendingTransactionState, - BroadcastedTransactionState, -} from '@lens-protocol/api-bindings'; - -/** - * `useRecentTransactions` is a hook that lets you access the recent pending transactions - * - * You can use this hook to show insights about the pending transactions in your app. - * - * You can also use this hook to clear the recent transactions queue. - * - * @category Misc - * @group Hooks - * - * @example - * ```tsx - * import { useRecentTransactions } from '@lens-protocol/react-web'; - * - * function RecentTransactions() { - * const { transactions, clearCompleted } = useRecentTransactions(); - * - * return ( - *
- *

Recent transactions

- *
    - * {transactions.map((transaction) => ( - *
  • - *

    Transaction ID: {transaction.id}

    - *

    Status: {transaction.status}

    - *
  • - * ))} - *
- * - *
- * ); - * } - * ``` - */ -export function useRecentTransactions() { - const { transactionQueue } = useSharedDependencies(); - - const transactions = useRecentTransactionsVar(); - - return { - clearCompleted() { - transactionQueue.clearRecent(); - }, - transactions, - }; -} diff --git a/packages/react-v1/src/transactions/useSelfFundedFallback.ts b/packages/react-v1/src/transactions/useSelfFundedFallback.ts deleted file mode 100644 index 9e29e1a7c4..0000000000 --- a/packages/react-v1/src/transactions/useSelfFundedFallback.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { - InsufficientGasError, - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - BroadcastingError, - ProtocolTransactionRequest, -} from '@lens-protocol/domain/use-cases/transactions'; -import { IEquatableError } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { SelfFundedProtocolTransactionRequest } from './adapters/SelfFundedProtocolTransactionRequest'; -import { usePayTransactionController } from './adapters/usePayTransactionController'; - -/** - * An opaque data structure that encapsulates the data required to make a self-funded protocol call. - * - * @internal - * @privateRemarks Ensure SelfFundedProtocolTransactionRequest is also excluded from the generated docs. - */ -export type SelfFundedOperationRequest = - SelfFundedProtocolTransactionRequest; - -export interface ISelfFundedFallback { - /** - * The fallback request to be executed if the original request fails. - * - * See {@link useSelfFundedFallback} for more information. - */ - fallback: SelfFundedOperationRequest; -} - -/** - * Given a {@link BroadcastingError}, returns true if it implements the {@link ISelfFundedFallback} interface. - * - */ -export function supportsSelfFundedFallback( - error: IEquatableError, -): error is BroadcastingError & ISelfFundedFallback { - return error instanceof BroadcastingError && error.fallback !== undefined; -} - -export type SelfFundedOperation = Operation< - AsyncTransactionResult, - InsufficientGasError | PendingSigningRequestError | UserRejectedError | WalletConnectionError, - [SelfFundedOperationRequest] ->; - -/** - * `useSelfFundedFallback` is an hook that let you retry a failed operation that could be self-funded. - * - * @category Misc - * @group Hooks - * - * @example - * ```tsx - * import { ContentFocus, ProfileOwnedByMe, supportsSelfFundedFallback, useCreatePost, useSelfFundedFallback } from '@lens-protocol/react-web'; - * - * function PostComposer({ publisher }: { publisher: ProfileOwnedByMe }) { - * const { execute: createPost, error, isPending } = useCreatePost({ publisher, upload: uploadToIpfs }); - * const { execute: createPostFromWallet, error: selfFundedError, isPending: selfFundedPending } = useSelfFundedFallback(); - * - * const submit = async (content: string) => { - * const result = await createPost({ - * content, - * contentFocus: ContentFocus.TEXT_ONLY, - * locale: 'en', - * }); - * - * if (result.isFailure()) { - * if (supportsSelfFundedFallback(result.error)) { - * await createPostFromWallet(result.error.fallback) - * } - * } - * - * // ... - * }; - * - * // continues with your UI/form that invokes the submit(content) handler above - * } - * ``` - */ -export function useSelfFundedFallback(): SelfFundedOperation { - const payTransaction = usePayTransactionController(); - - return useOperation(payTransaction); -} diff --git a/packages/react-v1/src/transactions/useUnfollow.ts b/packages/react-v1/src/transactions/useUnfollow.ts deleted file mode 100644 index 8ee8465f67..0000000000 --- a/packages/react-v1/src/transactions/useUnfollow.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { - isFollowTransactionFor, - Profile, - ProfileOwnedByMe, - useHasPendingTransaction, -} from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { failure, PromiseResult } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { useUnfollowController } from './adapters/useUnfollowController'; - -export class PrematureUnfollowError extends Error { - name = 'PrematureUnfollowError' as const; -} - -export type UseUnfollowArgs = { - followee: Profile; - follower: ProfileOwnedByMe; -}; - -export type UnfollowOperation = Operation< - AsyncTransactionResult, - | BroadcastingError - | PendingSigningRequestError - | PrematureUnfollowError - | UserRejectedError - | WalletConnectionError ->; - -/** - * @category Profiles - * @group Hooks - */ -export function useUnfollow({ followee, follower }: UseUnfollowArgs): UnfollowOperation { - const unfollow = useUnfollowController(); - - const hasPendingFollowTx = useHasPendingTransaction( - isFollowTransactionFor({ profileId: followee.id, followerAddress: follower.ownedBy }), - ); - - return useOperation( - async (): PromiseResult< - AsyncTransactionResult, - | BroadcastingError - | PendingSigningRequestError - | PrematureUnfollowError - | UserRejectedError - | WalletConnectionError - > => { - if (hasPendingFollowTx) { - return failure( - new PrematureUnfollowError( - `A previous follow request for ${followee.handle} is still pending. Make sure you check 'followee.followStatus.canUnfollow' beforehand.`, - ), - ); - } - - return unfollow({ - kind: TransactionKind.UNFOLLOW_PROFILE, - profileId: followee.id, - }); - }, - ); -} diff --git a/packages/react-v1/src/transactions/useUpdateDispatcherConfig.ts b/packages/react-v1/src/transactions/useUpdateDispatcherConfig.ts deleted file mode 100644 index acea759650..0000000000 --- a/packages/react-v1/src/transactions/useUpdateDispatcherConfig.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { - ProfileOwnedByMe, - TransactionState, - useHasPendingTransaction, -} from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { UpdateDispatcherConfigRequest } from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; - -import { Operation, useOperation } from '../helpers/operations'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { useUpdateDispatcherConfigController } from './adapters/useUpdateDispatcherConfigController'; - -export type UseUpdateDispatcherConfigArgs = { - profile: ProfileOwnedByMe; -}; - -export type UpdateDispatcherConfigArgs = { - enabled: boolean; -}; - -export type UpdateDispatcherConfigOperation = Operation< - AsyncTransactionResult, - BroadcastingError | PendingSigningRequestError | UserRejectedError | WalletConnectionError, - [UpdateDispatcherConfigArgs] ->; - -/** - * @category Profiles - * @group Hooks - */ -export function useUpdateDispatcherConfig({ - profile, -}: UseUpdateDispatcherConfigArgs): UpdateDispatcherConfigOperation { - // note: this is one of the hooks for which we need to wait for the corresponding tx to be mined - // as it's affecting the way we would handle all tx after this one is done. - const hasPendingUpdateTransaction = useHasPendingTransaction( - (tx): tx is TransactionState => - tx.request.kind === TransactionKind.UPDATE_DISPATCHER_CONFIG && - tx.request.profileId === profile.id, - ); - const update = useUpdateDispatcherConfigController(); - - const { execute, error, isPending } = useOperation( - async ({ enabled }: UpdateDispatcherConfigArgs) => - update({ - kind: TransactionKind.UPDATE_DISPATCHER_CONFIG, - enabled, - profileId: profile.id, - }), - ); - - return { - execute, - error, - isPending: isPending || hasPendingUpdateTransaction, - }; -} diff --git a/packages/react-v1/src/transactions/useUpdateFollowPolicy.ts b/packages/react-v1/src/transactions/useUpdateFollowPolicy.ts deleted file mode 100644 index 58190a48f2..0000000000 --- a/packages/react-v1/src/transactions/useUpdateFollowPolicy.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { ProfileOwnedByMe } from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { ChargeFollowConfig, NoFeeFollowConfig } from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; - -import { Operation, useOperation } from '../helpers/operations'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { useUpdateFollowPolicyController } from './adapters/useUpdateFollowPolicyController'; - -export type UseUpdateFollowPolicyArgs = { - profile: ProfileOwnedByMe; -}; - -export type UpdateFollowPolicyArgs = { - followPolicy: ChargeFollowConfig | NoFeeFollowConfig; -}; - -export type UpdateFollowPolicyOperation = Operation< - AsyncTransactionResult, - BroadcastingError | PendingSigningRequestError | UserRejectedError | WalletConnectionError, - [UpdateFollowPolicyArgs] ->; - -/** - * @category Profiles - * @group Hooks - */ -export function useUpdateFollowPolicy({ - profile, -}: UseUpdateFollowPolicyArgs): UpdateFollowPolicyOperation { - const updateFollowPolicy = useUpdateFollowPolicyController(); - - return useOperation(async ({ followPolicy }: UpdateFollowPolicyArgs) => - updateFollowPolicy({ - profileId: profile.id, - policy: followPolicy, - kind: TransactionKind.UPDATE_FOLLOW_POLICY, - }), - ); -} diff --git a/packages/react-v1/src/transactions/useUpdateProfileDetails.ts b/packages/react-v1/src/transactions/useUpdateProfileDetails.ts deleted file mode 100644 index 25e3018800..0000000000 --- a/packages/react-v1/src/transactions/useUpdateProfileDetails.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { ProfileOwnedByMe } from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { UpdateProfileDetailsRequest } from '@lens-protocol/domain/use-cases/profile'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { failure, PromiseResult } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { FailedUploadError } from './adapters/IMetadataUploader'; -import { MetadataUploadHandler } from './adapters/MetadataUploadHandler'; -import { useUpdateProfileDetailsController } from './adapters/useUpdateProfileDetailsController'; - -export type UseUpdateProfileDetailsArgs = { - profile: ProfileOwnedByMe; - upload: MetadataUploadHandler; -}; - -export type UpdateProfileDetailsArgs = Pick< - UpdateProfileDetailsRequest, - 'attributes' | 'bio' | 'coverPicture' | 'name' ->; - -export type UpdateProfileDetailsOperation = Operation< - AsyncTransactionResult, - | BroadcastingError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - | FailedUploadError, - [UpdateProfileDetailsArgs] ->; - -/** - * @category Profiles - * @group Hooks - */ -export function useUpdateProfileDetails({ - profile, - upload, -}: UseUpdateProfileDetailsArgs): UpdateProfileDetailsOperation { - const update = useUpdateProfileDetailsController({ upload }); - - return useOperation( - async ( - details: UpdateProfileDetailsArgs, - ): PromiseResult< - AsyncTransactionResult, - | BroadcastingError - | PendingSigningRequestError - | UserRejectedError - | WalletConnectionError - | FailedUploadError - > => { - try { - return await update({ - kind: TransactionKind.UPDATE_PROFILE_DETAILS, - delegate: profile.dispatcher !== null, - profileId: profile.id, - ...details, - }); - } catch (err: unknown) { - if (err instanceof FailedUploadError) { - return failure(err); - } - throw err; - } - }, - ); -} diff --git a/packages/react-v1/src/transactions/useUpdateProfileImage.ts b/packages/react-v1/src/transactions/useUpdateProfileImage.ts deleted file mode 100644 index 8fc2b1beed..0000000000 --- a/packages/react-v1/src/transactions/useUpdateProfileImage.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { - PendingSigningRequestError, - TransactionKind, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { BroadcastingError } from '@lens-protocol/domain/use-cases/transactions'; -import { Url } from '@lens-protocol/shared-kernel'; - -import { Operation, useOperation } from '../helpers/operations'; -import { AsyncTransactionResult } from './adapters/AsyncTransactionResult'; -import { useUpdateProfileImageController } from './adapters/useUpdateProfileImageController'; - -export type UseUpdateProfileImageArgs = { - profile: Profile; -}; - -export type UpdateProfileImageOperation = Operation< - AsyncTransactionResult, - BroadcastingError | PendingSigningRequestError | UserRejectedError | WalletConnectionError, - [string] ->; - -/** - * @category Profiles - * @group Hooks - */ -export function useUpdateProfileImage({ - profile, -}: UseUpdateProfileImageArgs): UpdateProfileImageOperation { - const updateImage = useUpdateProfileImageController(); - - return useOperation(async (url: Url) => { - return updateImage({ - kind: TransactionKind.UPDATE_PROFILE_IMAGE, - profileId: profile.id, - url, - delegate: profile.dispatcher !== null, - }); - }); -} diff --git a/packages/react-v1/src/utils.ts b/packages/react-v1/src/utils.ts deleted file mode 100644 index 1cbaee9c2c..0000000000 --- a/packages/react-v1/src/utils.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { AppId, ProfileId, PublicationId } from '@lens-protocol/domain/entities'; - -export const DEFAULT_PAGINATED_QUERY_LIMIT = 10; - -/** - * Ensures that the given value is a valid AppId - * - * @group Helpers - */ -export function appId(value: string): AppId { - // for now just asserts the type, in future it will enforce a format - return value as AppId; -} - -/** - * Ensures that the given value is a valid ProfileId - * - * @group Helpers - */ -export function profileId(id: string): ProfileId { - // for now just asserts the type, in future it will enforce a format - return id as ProfileId; -} - -/** - * Ensures that the given value is a valid PublicationId - * - * @group Helpers - */ -export function publicationId(id: string): PublicationId { - // for now just asserts the type, in future it will enforce a format - return id as PublicationId; -} diff --git a/packages/react-v1/src/wallet/adapters/BalanceGateway.ts b/packages/react-v1/src/wallet/adapters/BalanceGateway.ts deleted file mode 100644 index 9977b9df72..0000000000 --- a/packages/react-v1/src/wallet/adapters/BalanceGateway.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { erc20 } from '@lens-protocol/blockchain-bindings'; -import { Wallet } from '@lens-protocol/domain/entities'; -import { IBalanceGateway } from '@lens-protocol/domain/use-cases/wallets'; -import { Amount, BigDecimal, ChainType, Erc20 } from '@lens-protocol/shared-kernel'; - -import { ProviderFactory } from '../infrastructure/ProviderFactory'; - -export class BalanceGateway implements IBalanceGateway { - constructor(private readonly providerFactory: ProviderFactory) {} - - async getBalanceFor(wallet: Wallet, asset: T): Promise> { - const provider = await this.providerFactory.createProvider({ chainType: ChainType.POLYGON }); - - const contract = erc20(asset.address, provider); - - const balance = await contract.balanceOf(wallet.address); - - return Amount.erc20( - asset, - BigDecimal.rescale(BigDecimal.from(balance.toString()), -asset.decimals), - ); - } -} diff --git a/packages/react-v1/src/wallet/adapters/ConcreteWallet.ts b/packages/react-v1/src/wallet/adapters/ConcreteWallet.ts deleted file mode 100644 index a02f8783ba..0000000000 --- a/packages/react-v1/src/wallet/adapters/ConcreteWallet.ts +++ /dev/null @@ -1,324 +0,0 @@ -import { TypedDataSigner } from '@ethersproject/abstract-signer'; -import { TransactionRequest } from '@ethersproject/providers'; -import { TypedData } from '@lens-protocol/blockchain-bindings'; -import { - InsufficientGasError, - Wallet, - WalletConnectionError, - UserRejectedError, - PendingSigningRequestError, - ISignedProtocolCall, - IUnsignedProtocolCall, - UnsignedTransaction, - NativeTransaction, - ProtocolTransactionRequestModel, - AnyTransactionRequestModel, - Signature, - ISignedVote, - PollId, -} from '@lens-protocol/domain/entities'; -import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; -import { - ChainType, - EthereumAddress, - failure, - invariant, - matic, - PromiseResult, - success, -} from '@lens-protocol/shared-kernel'; -import { errors, Signer } from 'ethers'; -import { getAddress } from 'ethers/lib/utils'; -import { z } from 'zod'; - -import { UnsignedVote } from '../../polls/adapters/SnapshotVoteFactory'; -import { ISnapshotVote } from '../../polls/adapters/SnapshotVoteRelayer'; -import { ITransactionFactory } from '../../transactions/adapters/ITransactionFactory'; -import { SelfFundedProtocolTransactionRequest } from '../../transactions/adapters/SelfFundedProtocolTransactionRequest'; -import { assertErrorObjectWithCode } from './errors'; - -export type RequiredSigner = Signer & TypedDataSigner; - -export type CreateSignerConfig = { - address: EthereumAddress; - chainType?: ChainType; -}; - -export interface ISignerFactory { - createSigner(config: CreateSignerConfig): PromiseResult; -} - -export const WalletDataSchema = z.object({ - address: z.string(), -}); - -export type WalletDataSchema = z.infer; - -export class UnsignedProtocolCall - implements IUnsignedProtocolCall -{ - private constructor( - readonly id: string, - readonly request: T, - readonly typedData: TypedData, - readonly fallback: SelfFundedProtocolTransactionRequest, - ) {} - - get nonce() { - invariant(typeof this.typedData.message.nonce === 'number', 'Nonce is not defined'); - return this.typedData.message.nonce; - } - - static create({ - id, - request, - typedData, - fallback, - }: { - id: string; - request: T; - typedData: TypedData; - fallback: SelfFundedProtocolTransactionRequest; - }): UnsignedProtocolCall { - return new UnsignedProtocolCall(id, request, typedData, fallback); - } -} - -export class SignedProtocolCall - implements ISignedProtocolCall -{ - private constructor( - readonly id: string, - readonly request: T, - readonly signature: Signature, - readonly nonce: number, - readonly fallback: SelfFundedProtocolTransactionRequest, - ) {} - - static create({ - unsignedCall, - signature, - }: { - unsignedCall: UnsignedProtocolCall; - signature: string; - }): SignedProtocolCall { - return new SignedProtocolCall( - unsignedCall.id, - unsignedCall.request, - signature as Signature, - unsignedCall.nonce, - unsignedCall.fallback, - ); - } -} - -export class SignedVote implements ISnapshotVote { - constructor( - readonly pollId: PollId, - readonly signature: Signature, - readonly data: TypedData, - readonly voter: EthereumAddress, - ) {} -} - -export interface ITransactionRequest { - get transactionRequest(): TransactionRequest; -} - -export class ConcreteWallet extends Wallet { - private signingInProgress = false; - - private constructor( - data: WalletDataSchema, - private readonly signerFactory: ISignerFactory, - private readonly transactionFactory: ITransactionFactory, - ) { - super(data.address); - } - - async signProtocolCall( - unsignedCall: UnsignedProtocolCall, - ): PromiseResult< - ISignedProtocolCall, - PendingSigningRequestError | UserRejectedError | WalletConnectionError - > { - const result = await this.signerFactory.createSigner({ - address: this.address, - chainType: ChainType.POLYGON, - }); - - if (result.isFailure()) { - return failure(result.error); - } - - if (this.signingInProgress) { - return failure(new PendingSigningRequestError()); - } - this.signingInProgress = true; - - const signer = result.value; - try { - const signature = await signer._signTypedData( - unsignedCall.typedData.domain, - unsignedCall.typedData.types, - unsignedCall.typedData.message, - ); - - const signedCall = SignedProtocolCall.create({ unsignedCall, signature }); - return success(signedCall); - } catch (err) { - assertErrorObjectWithCode(err); - - if (err.code === errors.ACTION_REJECTED) { - return failure(new UserRejectedError()); - } - - throw err; - } finally { - this.signingInProgress = false; - } - } - - async signMessage( - message: string, - ): PromiseResult< - Signature, - PendingSigningRequestError | WalletConnectionError | UserRejectedError - > { - const result = await this.signerFactory.createSigner({ - address: this.address, - }); - - if (result.isFailure()) { - return failure(result.error); - } - - if (this.signingInProgress) { - return failure(new PendingSigningRequestError()); - } - this.signingInProgress = true; - - const signer = result.value; - try { - const signature = await signer.signMessage(message); - return success(signature as Signature); - } catch (err) { - assertErrorObjectWithCode(err); - - if (err.code === errors.ACTION_REJECTED) { - return failure(new UserRejectedError()); - } - throw err; - } finally { - this.signingInProgress = false; - } - } - - async sendTransaction( - unsignedTransaction: UnsignedTransaction & ITransactionRequest, - ): PromiseResult< - NativeTransaction, - InsufficientGasError | PendingSigningRequestError | UserRejectedError | WalletConnectionError - > { - const result = await this.signerFactory.createSigner({ - address: this.address, - chainType: unsignedTransaction.chainType, - }); - - if (result.isFailure()) { - return failure(result.error); - } - - if (this.signingInProgress) { - return failure(new PendingSigningRequestError()); - } - this.signingInProgress = true; - - const signer = result.value; - try { - const response = await signer.sendTransaction(unsignedTransaction.transactionRequest); - - const transaction = this.transactionFactory.createNativeTransaction({ - chainType: unsignedTransaction.chainType, - id: unsignedTransaction.id, - request: unsignedTransaction.request, - txHash: response.hash, - }); - - return success(transaction); - } catch (err) { - assertErrorObjectWithCode(err); - - switch (err.code) { - case errors.ACTION_REJECTED: - return failure(new UserRejectedError(err.message)); - case errors.INSUFFICIENT_FUNDS: - return failure(new InsufficientGasError(matic())); - } - - throw err; - } finally { - this.signingInProgress = false; - } - } - - async signVote( - unsignedVote: UnsignedVote, - ): PromiseResult< - ISignedVote, - WalletConnectionError | PendingSigningRequestError | UserRejectedError - > { - const result = await this.signerFactory.createSigner({ - address: this.address, - }); - - if (result.isFailure()) { - return failure(result.error); - } - - if (this.signingInProgress) { - return failure(new PendingSigningRequestError()); - } - this.signingInProgress = true; - - const signer = result.value; - try { - const signature = await signer._signTypedData( - unsignedVote.typedData.domain, - unsignedVote.typedData.types, - unsignedVote.typedData.message, - ); - - const signedVote = new SignedVote( - unsignedVote.pollId, - signature as Signature, - unsignedVote.typedData, - getAddress(this.address), - ); - return success(signedVote); - } catch (err) { - assertErrorObjectWithCode(err); - - if (err.code === errors.ACTION_REJECTED) { - return failure(new UserRejectedError()); - } - throw err; - } finally { - this.signingInProgress = false; - } - } - - toWalletData(): WalletDataSchema { - return { - address: this.address, - }; - } - - static create( - data: WalletDataSchema, - signerFactory: ISignerFactory, - transactionFactory: ITransactionFactory, - ) { - return new ConcreteWallet(data, signerFactory, transactionFactory); - } -} diff --git a/packages/react-v1/src/wallet/adapters/Credentials.ts b/packages/react-v1/src/wallet/adapters/Credentials.ts deleted file mode 100644 index 605bd540a5..0000000000 --- a/packages/react-v1/src/wallet/adapters/Credentials.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { ICredentials } from '@lens-protocol/domain/entities'; -import { DateUtils, invariant, InvariantError } from '@lens-protocol/shared-kernel'; -import jwtDecode, { JwtPayload } from 'jwt-decode'; -import isObject from 'lodash/isObject.js'; - -type ParsedJwt = { - id: string; -}; - -function assertIdInJwt(decodedJwt: unknown): asserts decodedJwt is ParsedJwt { - if (isObject(decodedJwt) && !('id' in decodedJwt)) { - throw new InvariantError('Invalid JWT format.'); - } -} - -// Threshold in seconds that will mark token as expired even it's still valid -// Adds some time for all communications that's required to refresh tokens -const TOKEN_EXP_THRESHOLD = DateUtils.secondsToMs(3); - -export class Credentials implements ICredentials { - readonly address: string; - - constructor(readonly accessToken: string | null, readonly refreshToken: string) { - const decodedRefreshToken = jwtDecode(refreshToken); - - assertIdInJwt(decodedRefreshToken); - - this.address = decodedRefreshToken.id; - } - - canRefresh(): boolean { - const now = Date.now(); - const tokenExpDate = this.getTokenExpDate(this.refreshToken); - - return now < tokenExpDate - TOKEN_EXP_THRESHOLD; - } - - isExpired(): boolean { - const accessToken = this.accessToken; - - if (!accessToken) { - return true; - } - - const now = Date.now(); - const tokenExpDate = this.getTokenExpDate(accessToken); - - return now >= tokenExpDate - TOKEN_EXP_THRESHOLD; - } - - getAccessTokenExpDate(): number | null { - const accessToken = this.accessToken; - - if (!accessToken) { - return null; - } - - return this.getTokenExpDate(accessToken); - } - - private getTokenExpDate(token: string) { - const decodedToken = jwtDecode(token); - - invariant(decodedToken.exp, 'Exp date should be provided by JWT token'); - - return DateUtils.secondsToMs(decodedToken.exp); - } -} diff --git a/packages/react-v1/src/wallet/adapters/CredentialsExpiryController.ts b/packages/react-v1/src/wallet/adapters/CredentialsExpiryController.ts deleted file mode 100644 index feb1667d66..0000000000 --- a/packages/react-v1/src/wallet/adapters/CredentialsExpiryController.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { LogoutReason, WalletLogout } from '@lens-protocol/domain/use-cases/wallets'; - -export type Callback = () => void; - -export interface ICredentialsExpiryEmitter { - onExpiry(callback: Callback): void; -} - -export class CredentialsExpiryController { - constructor(readonly walletLogout: WalletLogout) {} - - subscribe(tokenExpiryEmitter: ICredentialsExpiryEmitter) { - tokenExpiryEmitter.onExpiry(() => { - void this.onTokenExpired(); - }); - } - - private async onTokenExpired(): Promise { - await this.walletLogout.logout(LogoutReason.CREDENTIALS_EXPIRED); - } -} diff --git a/packages/react-v1/src/wallet/adapters/CredentialsFactory.ts b/packages/react-v1/src/wallet/adapters/CredentialsFactory.ts deleted file mode 100644 index a65a98d447..0000000000 --- a/packages/react-v1/src/wallet/adapters/CredentialsFactory.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Wallet } from '@lens-protocol/domain/entities'; -import { - CredentialsExpiredError, - ICredentialsRenewer, -} from '@lens-protocol/domain/use-cases/lifecycle'; -import { ICredentialsIssuer, LoginError } from '@lens-protocol/domain/use-cases/wallets'; -import { failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; - -import { Credentials } from './Credentials'; - -export interface IAuthMethods { - generateChallenge(address: string): Promise; - generateCredentials(address: string, signature: string): Promise; - refreshCredentials(refreshToken: string): Promise; -} - -export class CredentialsFactory implements ICredentialsIssuer, ICredentialsRenewer { - constructor(private auth: IAuthMethods) {} - - async renewCredentials( - credentials: Credentials, - ): PromiseResult { - if (!credentials.canRefresh()) { - return failure(new CredentialsExpiredError()); - } - const newCredentials = await this.auth.refreshCredentials(credentials.refreshToken); - return success(newCredentials); - } - - async issueCredentials(wallet: Wallet): PromiseResult { - const challenge = await this.auth.generateChallenge(wallet.address); - const signedChallengeResult = await wallet.signMessage(challenge); - if (signedChallengeResult.isFailure()) { - return failure(signedChallengeResult.error); - } - const credentials = await this.auth.generateCredentials( - wallet.address, - signedChallengeResult.value, - ); - - return success(credentials); - } -} diff --git a/packages/react-v1/src/wallet/adapters/CredentialsGateway.ts b/packages/react-v1/src/wallet/adapters/CredentialsGateway.ts deleted file mode 100644 index 87313216e1..0000000000 --- a/packages/react-v1/src/wallet/adapters/CredentialsGateway.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ICredentialsWriter, ICredentialsReader } from '@lens-protocol/domain/use-cases/wallets'; -import { IStorage } from '@lens-protocol/storage'; - -import { Credentials } from './Credentials'; - -export class CredentialsGateway implements ICredentialsWriter, ICredentialsReader { - constructor(private readonly credentialsStorage: IStorage) {} - - async getCredentials() { - return this.credentialsStorage.get(); - } - - async save(credentials: Credentials) { - await this.credentialsStorage.set(credentials); - } - - async invalidate() { - await this.credentialsStorage.reset(); - } -} diff --git a/packages/react-v1/src/wallet/adapters/IProviderFactory.ts b/packages/react-v1/src/wallet/adapters/IProviderFactory.ts deleted file mode 100644 index 8a6f19b32c..0000000000 --- a/packages/react-v1/src/wallet/adapters/IProviderFactory.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ChainType } from '@lens-protocol/shared-kernel'; -import { providers } from 'ethers'; - -export type CreateProviderConfig = { - chainType: ChainType; -}; - -export interface IProviderFactory { - createProvider(config: CreateProviderConfig): Promise; -} diff --git a/packages/react-v1/src/wallet/adapters/TokenGateway.ts b/packages/react-v1/src/wallet/adapters/TokenGateway.ts deleted file mode 100644 index b469207b03..0000000000 --- a/packages/react-v1/src/wallet/adapters/TokenGateway.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { erc20 } from '@lens-protocol/blockchain-bindings'; -import { Wallet } from '@lens-protocol/domain/entities'; -import { ITokenGateway } from '@lens-protocol/domain/use-cases/wallets'; -import { Erc20, Amount, BigDecimal, ChainType } from '@lens-protocol/shared-kernel'; - -import { ProviderFactory } from '../infrastructure/ProviderFactory'; - -export class TokenGateway implements ITokenGateway { - constructor(private readonly providerFactory: ProviderFactory) {} - - async getTransferAllowanceFor( - asset: T, - owner: Wallet, - spender: string, - ): Promise> { - const provider = await this.providerFactory.createProvider({ chainType: ChainType.POLYGON }); - - const contract = erc20(asset.address, provider); - - const allowance = await contract.allowance(owner.address, spender); - - return Amount.erc20( - asset, - BigDecimal.rescale(BigDecimal.from(allowance.toString()), -asset.decimals), - ); - } -} diff --git a/packages/react-v1/src/wallet/adapters/WalletFactory.ts b/packages/react-v1/src/wallet/adapters/WalletFactory.ts deleted file mode 100644 index a94baf5544..0000000000 --- a/packages/react-v1/src/wallet/adapters/WalletFactory.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; -import { IWalletFactory, WalletLoginRequest } from '@lens-protocol/domain/use-cases/wallets'; - -import { ITransactionFactory } from '../../transactions/adapters/ITransactionFactory'; -import { ConcreteWallet, ISignerFactory, WalletDataSchema } from './ConcreteWallet'; -import { IWalletUnmarshaller } from './WalletGateway'; - -export class WalletFactory implements IWalletUnmarshaller, IWalletFactory { - constructor( - private readonly signerFactory: ISignerFactory, - private readonly transactionFactory: ITransactionFactory, - ) {} - - async create(request: WalletLoginRequest): Promise { - return ConcreteWallet.create(request, this.signerFactory, this.transactionFactory); - } - - rehydrate(data: WalletDataSchema) { - return ConcreteWallet.create(data, this.signerFactory, this.transactionFactory); - } -} diff --git a/packages/react-v1/src/wallet/adapters/WalletGateway.ts b/packages/react-v1/src/wallet/adapters/WalletGateway.ts deleted file mode 100644 index 9a3843fba7..0000000000 --- a/packages/react-v1/src/wallet/adapters/WalletGateway.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { - IReadableWalletGateway, - IResettableWalletGateway, - IWritableWalletGateway, -} from '@lens-protocol/domain/use-cases/wallets'; -import { EthereumAddress, never } from '@lens-protocol/shared-kernel'; -import { IStorage } from '@lens-protocol/storage'; -import { z } from 'zod'; - -import { ConcreteWallet, WalletDataSchema } from './ConcreteWallet'; - -export interface IWalletUnmarshaller { - rehydrate(data: WalletDataSchema): ConcreteWallet; -} - -export const WalletStorageSchema = z.array(WalletDataSchema); - -export type WalletStorageSchema = z.infer; - -export class WalletGateway - implements IReadableWalletGateway, IResettableWalletGateway, IWritableWalletGateway -{ - private inMemoryCache: Record = {}; - - constructor( - private readonly storage: IStorage, - private readonly factory: IWalletUnmarshaller, - ) {} - - async getByAddress(address: EthereumAddress): Promise { - if (this.inMemoryCache[address]) { - return this.inMemoryCache[address] ?? never(); - } - const wallets = await this.getAll(); - const wallet = wallets.find((w) => w.address === address) ?? null; - - if (wallet) { - this.inMemoryCache[address] = wallet; - } - return wallet; - } - - async reset(): Promise { - await this.storage.reset(); - } - - async save(wallet: ConcreteWallet): Promise { - const wallets = await this.getAll(); - - this.inMemoryCache[wallet.address] = wallet; - await this.storage.set(wallets.concat([wallet]).map((w) => w.toWalletData())); - } - - private async getAll(): Promise { - const data = await this.storage.get(); - - if (data === null) { - return []; - } - return data.map((d) => this.factory.rehydrate(d)); - } -} diff --git a/packages/react-v1/src/wallet/adapters/WalletLoginPresenter.ts b/packages/react-v1/src/wallet/adapters/WalletLoginPresenter.ts deleted file mode 100644 index 9f42669c02..0000000000 --- a/packages/react-v1/src/wallet/adapters/WalletLoginPresenter.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { ProfileIdentifier } from '@lens-protocol/domain/use-cases/lifecycle'; -import { IWalletLoginPresenter, LoginError } from '@lens-protocol/domain/use-cases/wallets'; -import { failure, Result, success } from '@lens-protocol/shared-kernel'; - -import { IProfileCacheManager } from '../../transactions/adapters/IProfileCacheManager'; -import { PromiseResultPresenter } from '../../transactions/adapters/PromiseResultPresenter'; - -export class WalletLoginPresenter - extends PromiseResultPresenter - implements IWalletLoginPresenter -{ - constructor(private readonly profileCacheManager: IProfileCacheManager) { - super(); - } - - override async present(result: Result) { - if (result.isSuccess()) { - if (result.value === null) { - return super.present(success(null)); - } - const { id } = result.value; - const profile = await this.profileCacheManager.fetchProfile(id); - - return super.present(success(profile)); - } - - return super.present(failure(result.error)); - } -} diff --git a/packages/react-v1/src/wallet/adapters/__helpers__/mocks.ts b/packages/react-v1/src/wallet/adapters/__helpers__/mocks.ts deleted file mode 100644 index f1331f7ca4..0000000000 --- a/packages/react-v1/src/wallet/adapters/__helpers__/mocks.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { TransactionRequest } from '@ethersproject/providers'; -import { faker } from '@faker-js/faker'; -import { TypedData } from '@lens-protocol/blockchain-bindings'; -import { - ProtocolTransactionRequestModel, - AnyTransactionRequestModel, - UnsignedTransaction, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { - mockSignature, - mockAnyTransactionRequestModel, - mockProtocolTransactionRequestModel, - mockPollId, -} from '@lens-protocol/domain/mocks'; -import { ChainType, EthereumAddress, Result } from '@lens-protocol/shared-kernel'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; -import { providers } from 'ethers'; -import { mock } from 'jest-mock-extended'; -import { when } from 'jest-when'; - -import { ITransactionFactory } from '../../../transactions/adapters/ITransactionFactory'; -import { - mockSelfFundedProtocolTransactionRequest, - mockTypedData, -} from '../../../transactions/adapters/__helpers__/mocks'; -import { - ConcreteWallet, - ISignerFactory, - ITransactionRequest, - SignedProtocolCall, - SignedVote, - UnsignedProtocolCall, -} from '../ConcreteWallet'; -import { Credentials } from '../Credentials'; -import { IProviderFactory } from '../IProviderFactory'; - -type MockedISignerFactoryConfig = { - address: EthereumAddress; - chainType?: ChainType; - signerResult: Result; -}; - -export function mockISignerFactory({ - signerResult, - ...config -}: MockedISignerFactoryConfig): ISignerFactory { - const factory = mock(); - - when(factory.createSigner) - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - .calledWith(expect.objectContaining(config)) - .mockResolvedValue(signerResult); - - return factory; -} - -type MockedIProviderFactoryConfig = { - chainType: ChainType; - provider: providers.JsonRpcProvider; -}; - -export function mockIProviderFactory({ - chainType, - provider, -}: MockedIProviderFactoryConfig): IProviderFactory { - const factory = mock(); - - when(factory.createProvider) - .calledWith( - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - expect.objectContaining({ chainType }), - ) - .mockResolvedValue(provider); - - return factory; -} - -export function mockUnsignedProtocolCall({ - typedData, - request, -}: { - typedData: TypedData; - request: T; -}) { - return UnsignedProtocolCall.create({ - id: faker.datatype.uuid(), - request, - typedData, - fallback: mockSelfFundedProtocolTransactionRequest(), - }); -} - -export function mockSignedProtocolCall() { - return SignedProtocolCall.create({ - unsignedCall: mockUnsignedProtocolCall({ - typedData: mockTypedData(), - request: mockProtocolTransactionRequestModel() as T, - }), - signature: mockSignature(), - }); -} - -class MockedUnsignedTransactionRequest - extends UnsignedTransaction - implements ITransactionRequest -{ - constructor(chainType: ChainType, request: T, readonly transactionRequest: TransactionRequest) { - super(faker.datatype.uuid(), chainType, request); - } -} - -export function mockUnsignedTransactionRequest({ - chainType, - txRequest, -}: { - chainType: ChainType; - txRequest: TransactionRequest; -}) { - return new MockedUnsignedTransactionRequest( - chainType, - mockAnyTransactionRequestModel(), - txRequest, - ); -} - -export function mockConcreteWallet() { - return ConcreteWallet.create( - { address: mockEthereumAddress() }, - mock(), - mock>(), - ); -} - -class ErrorWithCode extends Error { - name = 'ErrorWithCode' as const; - - constructor(readonly code: T) { - super(); - } -} - -export function mockErrorWithCode(code: T) { - return new ErrorWithCode(code); -} - -export function mockCredentials(): Credentials { - return new Credentials( - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjB4YjE5QzI4OTBjZjk0N0FEM2YwYjdkN0U1QTlmZkJjZTM2ZDNmOWJkMiIsInJvbGUiOiJub3JtYWwiLCJpYXQiOjE2Mzc3NTQ2ODEsImV4cCI6MTYzNzc1NDc0MX0.Be1eGBvVuFL4fj4pHHqc0yWDledsgS2GP3Jgonmy-xw', - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjB4YjE5QzI4OTBjZjk0N0FEM2YwYjdkN0U1QTlmZkJjZTM2ZDNmOWJkMiIsInJvbGUiOiJub3JtYWwiLCJpYXQiOjE2Mzc3NTQ2ODEsImV4cCI6MTYzNzc1NDc0MX0.Be1eGBvVuFL4fj4pHHqc0yWDledsgS2GP3Jgonmy-xw', - ); -} - -export function mockSignedVote(): SignedVote { - return new SignedVote(mockPollId(), mockSignature(), mockTypedData(), mockEthereumAddress()); -} diff --git a/packages/react-v1/src/wallet/adapters/__tests__/ConcreteWallet.spec.ts b/packages/react-v1/src/wallet/adapters/__tests__/ConcreteWallet.spec.ts deleted file mode 100644 index 4e5aecc2ac..0000000000 --- a/packages/react-v1/src/wallet/adapters/__tests__/ConcreteWallet.spec.ts +++ /dev/null @@ -1,376 +0,0 @@ -/* - * @jest-environment node - */ - -/* eslint-disable @typescript-eslint/unbound-method */ -import { - NativeTransaction, - UnsignedTransaction, - InsufficientGasError, - WalletConnectionError, - WalletConnectionErrorReason, - UserRejectedError, - PendingSigningRequestError, -} from '@lens-protocol/domain/entities'; -import { mockProtocolTransactionRequestModel, mockSignature } from '@lens-protocol/domain/mocks'; -import { ChainType, failure, success } from '@lens-protocol/shared-kernel'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; -import { MockProvider } from 'ethereum-waffle'; -import { errors, providers, utils, Wallet } from 'ethers'; -import { mock } from 'jest-mock-extended'; -import { when } from 'jest-when'; - -import { UnsignedVote } from '../../../polls/adapters/SnapshotVoteFactory'; -import { mockUnsignedVote } from '../../../polls/adapters/__helpers__/mocks'; -import { - mockITransactionFactory, - mockTypedData, -} from '../../../transactions/adapters/__helpers__/mocks'; -import { - ConcreteWallet, - ISignerFactory, - SignedVote, - UnsignedProtocolCall, -} from '../ConcreteWallet'; -import { - mockErrorWithCode, - mockISignerFactory, - mockUnsignedProtocolCall, - mockUnsignedTransactionRequest, -} from '../__helpers__/mocks'; - -const address = mockEthereumAddress(); -const chainType = ChainType.POLYGON; - -function setupWalletInstance({ signerFactory }: { signerFactory: ISignerFactory }) { - const transactionFactory = mockITransactionFactory(); - return ConcreteWallet.create( - { - address, - }, - signerFactory, - transactionFactory, - ); -} - -describe(`Given an instance of ${ConcreteWallet.name}`, () => { - describe(`when signing an ${UnsignedProtocolCall.name}`, () => { - const typedData = mockTypedData(); - const request = mockProtocolTransactionRequestModel(); - const unsignedCall = mockUnsignedProtocolCall({ typedData, request }); - const signature = mockSignature(); - - it(`should resolve with a ISignedProtocolCall instance`, async () => { - const signer = mock(); - when(signer._signTypedData) - .calledWith(typedData.domain, typedData.types, typedData.message) - .mockResolvedValue(signature); - - const signerFactory = mockISignerFactory({ - address, - chainType: ChainType.POLYGON, - signerResult: success(signer), - }); - - const wallet = setupWalletInstance({ signerFactory }); - const result = await wallet.signProtocolCall(unsignedCall); - - expect(result.unwrap()).toEqual({ - id: unsignedCall.id, - nonce: unsignedCall.nonce, - request, - signature, - fallback: unsignedCall.fallback, - }); - }); - - it(`should fail with ${PendingSigningRequestError.name} in case of existing signing request`, async () => { - const signer = mock(); - when(signer._signTypedData) - .calledWith(typedData.domain, typedData.types, typedData.message) - .mockResolvedValue(signature); - - const signerFactory = mockISignerFactory({ - address, - signerResult: success(signer), - }); - - const wallet = setupWalletInstance({ signerFactory }); - - void wallet.signProtocolCall(unsignedCall); // previous signing request - const result = await wallet.signProtocolCall(unsignedCall); - - expect(() => result.unwrap()).toThrow(PendingSigningRequestError); - }); - - it(`should fail with ${UserRejectedError.name} in case the user refuse the operation`, async () => { - const signer = mock(); - when(signer._signTypedData).mockRejectedValue(mockErrorWithCode(errors.ACTION_REJECTED)); - - const signerFactory = mockISignerFactory({ - address, - signerResult: success(signer), - }); - - const wallet = setupWalletInstance({ signerFactory }); - const result = await wallet.signProtocolCall(unsignedCall); - - expect(() => result.unwrap()).toThrow(UserRejectedError); - }); - - it(`should forward any ${WalletConnectionError.name}`, async () => { - const error = new WalletConnectionError(WalletConnectionErrorReason.INCORRECT_CHAIN); - const signerFactory = mockISignerFactory({ - address, - signerResult: failure(error), - }); - - const wallet = setupWalletInstance({ signerFactory }); - const result = await wallet.signProtocolCall(unsignedCall); - - expect(() => result.unwrap()).toThrow(error); - }); - }); - - describe('when signing a message', () => { - const message = 'Sign this message from backend'; - const signature = mockSignature(); - - it(`should use the user's wallet to sign the message and return the signature`, async () => { - const signer = mock(); - when(signer.signMessage).calledWith(message).mockResolvedValue(signature); - - const signerFactory = mockISignerFactory({ - address, - signerResult: success(signer), - }); - const wallet = setupWalletInstance({ signerFactory }); - - const result = await wallet.signMessage(message); - - expect(signer.signMessage).toHaveBeenCalledWith(message); - expect(result.unwrap()).toBe(signature); - }); - - it(`should fail with ${PendingSigningRequestError.name} in case of existing signing request`, async () => { - const signer = mock(); - when(signer.signMessage).calledWith(message).mockResolvedValue(signature); - - const signerFactory = mockISignerFactory({ - address, - signerResult: success(signer), - }); - const wallet = setupWalletInstance({ signerFactory }); - - void wallet.signMessage(message); // previous signing request - const result = await wallet.signMessage(message); - - expect(() => result.unwrap()).toThrow(PendingSigningRequestError); - }); - - it(`should fail with ${UserRejectedError.name} if the user cancels the challenge message signing`, async () => { - const signer = mock(); - when(signer.signMessage) - .calledWith(message) - .mockRejectedValue(mockErrorWithCode(errors.ACTION_REJECTED)); - - const signerFactory = mockISignerFactory({ - address, - signerResult: success(signer), - }); - const wallet = setupWalletInstance({ signerFactory }); - - const result = await wallet.signMessage(message); - - expect(() => result.unwrap()).toThrow(UserRejectedError); - }); - }); - - describe(`when sending a ${UnsignedTransaction.name}`, () => { - it(`should: - - use the user's wallet to sign and send the transaction - - resolve with with a ${NativeTransaction.name}`, async () => { - const provider = new MockProvider(); - const [sender, receiver] = provider.getWallets() as [Wallet, Wallet]; - const txRequest = await sender.populateTransaction({ - from: sender.address, - to: receiver.address, - value: utils.parseEther('1'), - }); - const signerFactory = mockISignerFactory({ - address, - chainType, - signerResult: success(provider.getSigner()), - }); - const wallet = setupWalletInstance({ signerFactory }); - const receiverBalanceBefore = await receiver.getBalance(); - - const unsignedTransaction = mockUnsignedTransactionRequest({ chainType, txRequest }); - const result = await wallet.sendTransaction(unsignedTransaction); - - const receiverBalanceAfter = await receiver.getBalance(); - expect(receiverBalanceAfter.gt(receiverBalanceBefore)).toBe(true); - - expect(result.unwrap()).toBeInstanceOf(NativeTransaction); - expect(result.unwrap()).toEqual( - expect.objectContaining({ - chainType, - hash: expect.any(String), - id: unsignedTransaction.id, - request: unsignedTransaction.request, - }), - ); - }, 15_000); - - it(`should fail with ${PendingSigningRequestError.name} in case of existing signing request`, async () => { - const provider = new MockProvider(); - const [sender, receiver] = provider.getWallets() as [Wallet, Wallet]; - const txRequest = await sender.populateTransaction({ - from: sender.address, - to: receiver.address, - value: utils.parseEther('1'), - }); - const signerFactory = mockISignerFactory({ - address, - chainType, - signerResult: success(provider.getSigner()), - }); - const wallet = setupWalletInstance({ signerFactory }); - - const unsignedTransaction = mockUnsignedTransactionRequest({ chainType, txRequest }); - void wallet.sendTransaction(unsignedTransaction); // previous signing request - const result = await wallet.sendTransaction(unsignedTransaction); - - expect(() => result.unwrap()).toThrow(PendingSigningRequestError); - }); - - it(`should fail with ${InsufficientGasError.name} in case the wallet does not have enough Matic/Ether`, async () => { - const signer = mock(); - when(signer.sendTransaction).mockRejectedValue(mockErrorWithCode(errors.INSUFFICIENT_FUNDS)); - - const signerFactory = mockISignerFactory({ - address, - chainType, - signerResult: success(signer), - }); - const wallet = setupWalletInstance({ signerFactory }); - - const unsignedTransaction = mockUnsignedTransactionRequest({ chainType, txRequest: {} }); - const result = await wallet.sendTransaction(unsignedTransaction); - - expect(() => result.unwrap()).toThrow(InsufficientGasError); - }); - - it(`should fail with ${UserRejectedError.name} in case the user refuse the operation`, async () => { - const signer = mock(); - - when(signer.sendTransaction).mockRejectedValue(mockErrorWithCode(errors.ACTION_REJECTED)); - - const signerFactory = mockISignerFactory({ - address, - chainType, - signerResult: success(signer), - }); - const wallet = setupWalletInstance({ signerFactory }); - - const unsignedTransaction = mockUnsignedTransactionRequest({ - chainType, - txRequest: {}, - }); - const result = await wallet.sendTransaction(unsignedTransaction); - - expect(() => result.unwrap()).toThrow(UserRejectedError); - }); - - it(`should fail with ${WalletConnectionError.name} in case the ISignerFactory fails with it`, async () => { - const signerFactory = mockISignerFactory({ - address, - chainType, - signerResult: failure( - new WalletConnectionError(WalletConnectionErrorReason.INCORRECT_CHAIN), - ), - }); - const wallet = setupWalletInstance({ signerFactory }); - - const unsignedTransaction = mockUnsignedTransactionRequest({ - chainType, - txRequest: {}, - }); - const result = await wallet.sendTransaction(unsignedTransaction); - - expect(() => result.unwrap()).toThrow(WalletConnectionError); - }); - }); - - describe(`when signing a ${UnsignedVote.name}`, () => { - const typedData = mockTypedData(); - const unsignedVote = mockUnsignedVote({ typedData }); - const signature = mockSignature(); - - it(`should use the user's wallet to sign the message and return the ${SignedVote.name}`, async () => { - const signer = mock(); - when(signer._signTypedData) - .calledWith(typedData.domain, typedData.types, typedData.message) - .mockResolvedValue(signature); - - const signerFactory = mockISignerFactory({ - address, - signerResult: success(signer), - }); - - const wallet = setupWalletInstance({ signerFactory }); - const result = await wallet.signVote(unsignedVote); - - expect(result.unwrap()).toBeInstanceOf(SignedVote); - expect(result.unwrap()).toEqual({ - pollId: unsignedVote.pollId, - data: unsignedVote.typedData, - signature, - voter: address, - }); - }); - - it(`should fail with ${PendingSigningRequestError.name} in case of existing signing request`, async () => { - const signer = mock(); - when(signer._signTypedData).mockResolvedValue(signature); - - const signerFactory = mockISignerFactory({ - address, - signerResult: success(signer), - }); - const wallet = setupWalletInstance({ signerFactory }); - - void wallet.signVote(unsignedVote); - const result = await wallet.signVote(unsignedVote); - - expect(() => result.unwrap()).toThrow(PendingSigningRequestError); - }); - - it(`should fail with ${UserRejectedError.name} if the user cancels the challenge message signing`, async () => { - const signer = mock(); - when(signer._signTypedData).mockRejectedValue(mockErrorWithCode(errors.ACTION_REJECTED)); - - const signerFactory = mockISignerFactory({ - address, - signerResult: success(signer), - }); - const wallet = setupWalletInstance({ signerFactory }); - - const result = await wallet.signVote(unsignedVote); - - expect(() => result.unwrap()).toThrow(UserRejectedError); - }); - - it(`should fail with ${WalletConnectionError.name} in case the ISignerFactory fails with it`, async () => { - const signerFactory = mockISignerFactory({ - address, - signerResult: failure(new WalletConnectionError(WalletConnectionErrorReason.WRONG_ACCOUNT)), - }); - const wallet = setupWalletInstance({ signerFactory }); - - const result = await wallet.signVote(unsignedVote); - - expect(() => result.unwrap()).toThrow(WalletConnectionError); - }); - }); -}); diff --git a/packages/react-v1/src/wallet/adapters/__tests__/Credentials.spec.ts b/packages/react-v1/src/wallet/adapters/__tests__/Credentials.spec.ts deleted file mode 100644 index af0e3d19fa..0000000000 --- a/packages/react-v1/src/wallet/adapters/__tests__/Credentials.spec.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { DateUtils } from '@lens-protocol/shared-kernel'; - -import { Credentials } from '../Credentials'; - -const accessToken = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjB4YjE5QzI4OTBjZjk0N0FEM2YwYjdkN0U1QTlmZkJjZTM2ZDNmOWJkMiIsInJvbGUiOiJub3JtYWwiLCJpYXQiOjE2Mzc3NTQ2ODEsImV4cCI6MTYzNzc1NDc0MX0.Be1eGBvVuFL4fj4pHHqc0yWDledsgS2GP3Jgonmy-xw'; -const accessTokenExp = 1637754741000; -const refreshToken = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjB4YjE5QzI4OTBjZjk0N0FEM2YwYjdkN0U1QTlmZkJjZTM2ZDNmOWJkMiIsInJvbGUiOiJyZWZyZXNoIiwiaWF0IjoxNjM3NzU0NjgxLCJleHAiOjE2Mzc3NTQ5ODF9.3SqgsVMyqFPBcem2W9Iog91SWC8cIAFixXBkDue73Rc'; -const refreshTokenExp = 1637754981000; - -describe('Given the Credentials class', () => { - describe('when "Credentials" constructor is invoked', () => { - it('should get the address from refresh token data', async () => { - const expectedAddress = '0xb19C2890cf947AD3f0b7d7E5A9ffBce36d3f9bd2'; - - const credentials = new Credentials(null, refreshToken); - - expect(credentials.address).toEqual(expectedAddress); - }); - - it('should throw an error if the refresh token is without address', async () => { - const refreshToken = - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicmVmcmVzaCIsImlhdCI6MTYzNzE0MjY3NCwiZXhwIjoxNjM3MjI5MDc0fQ.FIH3KkV0IACt1EpCfpX4L29nCUKjmddlrDhsHhc5N0Q'; - - expect(() => new Credentials(null, refreshToken)).toThrow(); - }); - - it('should throw an error if the refresh token is invalid', async () => { - const refreshToken = 'broken refresh token'; - - expect(() => new Credentials(null, refreshToken)).toThrow(); - }); - }); - - describe('when "canRefresh" is invoked', () => { - it('should return true if refresh token is not yet expired', async () => { - jest.useFakeTimers().setSystemTime(refreshTokenExp - DateUtils.minutesToMs(1)); - - const credentials = new Credentials(null, refreshToken); - - expect(credentials.canRefresh()).toBeTruthy(); - }); - - it('should return false if refresh token is 3 seconds before expiring', async () => { - jest.useFakeTimers().setSystemTime(refreshTokenExp - DateUtils.secondsToMs(3)); - - const credentials = new Credentials(null, refreshToken); - - expect(credentials.canRefresh()).toBeFalsy(); - }); - - it('should return false if refresh token already expired', async () => { - jest.useFakeTimers().setSystemTime(refreshTokenExp + DateUtils.secondsToMs(1)); - - const credentials = new Credentials(null, refreshToken); - - expect(credentials.canRefresh()).toBeFalsy(); - }); - }); - - describe('when "isExpired" is invoked', () => { - it('should return true if there is no access token', async () => { - const credentials = new Credentials(null, refreshToken); - - expect(credentials.isExpired()).toBeTruthy(); - }); - - it('should return true if access token is 3 seconds before expiring', async () => { - jest.useFakeTimers().setSystemTime(accessTokenExp - DateUtils.secondsToMs(3)); - - const credentials = new Credentials(accessToken, refreshToken); - - expect(credentials.isExpired()).toBeTruthy(); - }); - - it('should return true if access token already expired', async () => { - jest.useFakeTimers().setSystemTime(accessTokenExp + DateUtils.secondsToMs(1)); - - const credentials = new Credentials(accessToken, refreshToken); - - expect(credentials.isExpired()).toBeTruthy(); - }); - - it('should return false if access token is not yet expired', async () => { - jest.useFakeTimers().setSystemTime(accessTokenExp - DateUtils.minutesToMs(1)); - - const credentials = new Credentials(accessToken, refreshToken); - - expect(credentials.isExpired()).toBeFalsy(); - }); - }); -}); diff --git a/packages/react-v1/src/wallet/adapters/__tests__/CredentialsFactory.spec.ts b/packages/react-v1/src/wallet/adapters/__tests__/CredentialsFactory.spec.ts deleted file mode 100644 index 6668b8c509..0000000000 --- a/packages/react-v1/src/wallet/adapters/__tests__/CredentialsFactory.spec.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, - WalletConnectionErrorReason, -} from '@lens-protocol/domain/entities'; -import { mockSignature, mockWallet } from '@lens-protocol/domain/mocks'; -import { CredentialsExpiredError } from '@lens-protocol/domain/use-cases/lifecycle'; -import { failure, success } from '@lens-protocol/shared-kernel'; -import { mock } from 'jest-mock-extended'; -import { when } from 'jest-when'; - -import { Credentials } from '../Credentials'; -import { CredentialsFactory, IAuthMethods } from '../CredentialsFactory'; - -const challenge = 'Challenge to sign from backend'; -const signedChallenge = mockSignature(); - -const setupFactory = () => { - const authApi = mock(); - const credentialsFactory = new CredentialsFactory(authApi); - const wallet = mockWallet(); - const credentials = mock({ - canRefresh: () => true, - address: wallet.address, - }); - return { - authApi, - credentialsFactory, - wallet, - credentials, - }; -}; - -describe(`Given an instance of the ${CredentialsFactory.name} class`, () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe(`when ${CredentialsFactory.prototype.issueCredentials.name} method is called`, () => { - it('should return new credentials for a certain wallet', async () => { - const { credentialsFactory, wallet, authApi, credentials } = setupFactory(); - when(authApi.generateChallenge).calledWith(wallet.address).mockResolvedValue(challenge); - when(wallet.signMessage).calledWith(challenge).mockResolvedValue(success(signedChallenge)); - when(authApi.generateCredentials) - .calledWith(wallet.address, signedChallenge) - .mockResolvedValue(credentials); - - const result = await credentialsFactory.issueCredentials(wallet); - expect(result.unwrap()).toEqual(credentials); - }); - it.each([ - { - ErrorCtor: UserRejectedError, - error: new UserRejectedError(), - }, - { - ErrorCtor: WalletConnectionError, - error: new WalletConnectionError(WalletConnectionErrorReason.WRONG_ACCOUNT), - }, - { - ErrorCtor: PendingSigningRequestError, - error: new PendingSigningRequestError(), - }, - ])( - `should fail with $ErrorCtor.name if the challenge signing fails with it`, - async ({ ErrorCtor, error }) => { - const { credentialsFactory, wallet, authApi } = setupFactory(); - when(authApi.generateChallenge).calledWith(wallet.address).mockResolvedValue(challenge); - when(wallet.signMessage).calledWith(challenge).mockResolvedValue(failure(error)); - - const result = await credentialsFactory.issueCredentials(wallet); - expect(() => result.unwrap()).toThrow(ErrorCtor); - }, - ); - }); - - describe(`when ${CredentialsFactory.prototype.renewCredentials.name} method is called`, () => { - it(`should fail with ${CredentialsExpiredError.name} if the credentials cant be refreshed`, async () => { - const { credentialsFactory } = setupFactory(); - const credentials = mock({ - canRefresh: () => false, - }); - - const result = await credentialsFactory.renewCredentials(credentials); - expect(() => result.unwrap()).toThrow(CredentialsExpiredError); - }); - it('should return the new credentials if the credentials can be refreshed', async () => { - const { credentialsFactory, credentials, authApi } = setupFactory(); - const newCredentials = mock(); - when(authApi.refreshCredentials) - .calledWith(credentials.refreshToken) - .mockResolvedValue(newCredentials); - - const result = await credentialsFactory.renewCredentials(credentials); - expect(result.unwrap()).toEqual(newCredentials); - }); - }); -}); diff --git a/packages/react-v1/src/wallet/adapters/__tests__/CredentialsGateway.spec.ts b/packages/react-v1/src/wallet/adapters/__tests__/CredentialsGateway.spec.ts deleted file mode 100644 index 4ba50e03f5..0000000000 --- a/packages/react-v1/src/wallet/adapters/__tests__/CredentialsGateway.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { mockStorage } from '@lens-protocol/storage/mocks'; - -import { Credentials } from '../Credentials'; -import { CredentialsGateway } from '../CredentialsGateway'; -import { mockCredentials } from '../__helpers__/mocks'; - -const credentials = mockCredentials(); - -const setupGateway = () => { - const storage = mockStorage(); - return new CredentialsGateway(storage); -}; - -describe(`Given an instance of the ${CredentialsGateway.name}`, () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe(`when "${CredentialsGateway.prototype.save.name}" method is invoked`, () => { - it('should store the credentials in the underlying storage so they can be retrieve later on', async () => { - const gateway = setupGateway(); - - await gateway.save(credentials); - - const result = await gateway.getCredentials(); - expect(result).toEqual(credentials); - }); - }); - - describe(`when "${CredentialsGateway.prototype.invalidate.name}" method is invoked`, () => { - it(`should clear the credentials in the underlying storage`, async () => { - const gateway = setupGateway(); - - await gateway.save(credentials); - await gateway.invalidate(); - - const result = await gateway.getCredentials(); - expect(result).toBe(null); - }); - }); -}); diff --git a/packages/react-v1/src/wallet/adapters/__tests__/WalletGateway.spec.ts b/packages/react-v1/src/wallet/adapters/__tests__/WalletGateway.spec.ts deleted file mode 100644 index 44ba892e17..0000000000 --- a/packages/react-v1/src/wallet/adapters/__tests__/WalletGateway.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Wallet } from '@lens-protocol/domain/entities'; -import { IStorage } from '@lens-protocol/storage'; -import { mockStorage } from '@lens-protocol/storage/mocks'; -import { mock } from 'jest-mock-extended'; - -import { mockITransactionFactory } from '../../../transactions/adapters/__helpers__/mocks'; -import { ISignerFactory } from '../ConcreteWallet'; -import { WalletFactory } from '../WalletFactory'; -import { WalletGateway, WalletStorageSchema } from '../WalletGateway'; -import { mockConcreteWallet } from '../__helpers__/mocks'; - -function setupWalletGateway({ storage }: { storage: IStorage }) { - const signerFactory = mock(); - const transactionFactory = mockITransactionFactory(); - const walletFactory = new WalletFactory(signerFactory, transactionFactory); - return new WalletGateway(storage, walletFactory); -} - -describe(`Given an instance of the ${WalletGateway.name}`, () => { - describe(`when "${WalletGateway.prototype.getByAddress.name}" method is invoked`, () => { - it(`should retrieve the ${Wallet.name} instance by address`, async () => { - const wallet1 = mockConcreteWallet(); - const wallet2 = mockConcreteWallet(); - const storage = mockStorage([wallet1, wallet2]); - - const gateway = setupWalletGateway({ storage }); - - const actual = await gateway.getByAddress(wallet2.address); - - expect(actual).toBeInstanceOf(Wallet); - expect(actual?.address).toEqual(wallet2.address); - }); - - it(`should cache the ${Wallet.name} instance in an in-memory cache for subsequent calls`, async () => { - const wallet1 = mockConcreteWallet(); - const wallet2 = mockConcreteWallet(); - const storage = mockStorage([wallet1, wallet2]); - - const gateway = setupWalletGateway({ storage }); - - expect(await gateway.getByAddress(wallet2.address)).toBe( - await gateway.getByAddress(wallet2.address), - ); - }); - }); - - describe(`when "${WalletGateway.prototype.reset.name}" method is invoked`, () => { - it(`should remove all the ${Wallet.name} entities from the underlying storage provider`, async () => { - const wallet1 = mockConcreteWallet(); - const wallet2 = mockConcreteWallet(); - const storage = mockStorage([wallet1, wallet2]); - - const gateway = setupWalletGateway({ storage }); - - await gateway.reset(); - - expect(await gateway.getByAddress(wallet1.address)).toBeNull(); - expect(await gateway.getByAddress(wallet2.address)).toBeNull(); - }); - }); - - describe(`when "${WalletGateway.prototype.save.name}" method is invoked`, () => { - it(`should cache the ${Wallet.name} instance in an in-memory cache to support subsequent reads`, async () => { - const newWallet = mockConcreteWallet(); - const storage = mockStorage([]); - - const gateway = setupWalletGateway({ storage }); - - await gateway.save(newWallet); - - expect(await gateway.getByAddress(newWallet.address)).toBe(newWallet); - }); - }); -}); diff --git a/packages/react-v1/src/wallet/adapters/__tests__/WalletLoginPresenter.spec.ts b/packages/react-v1/src/wallet/adapters/__tests__/WalletLoginPresenter.spec.ts deleted file mode 100644 index 97c13c087d..0000000000 --- a/packages/react-v1/src/wallet/adapters/__tests__/WalletLoginPresenter.spec.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { mockProfileFragment } from '@lens-protocol/api-bindings/mocks'; -import { WalletConnectionError, WalletConnectionErrorReason } from '@lens-protocol/domain/entities'; -import { mockProfileIdentifier } from '@lens-protocol/domain/mocks'; -import { failure, success } from '@lens-protocol/shared-kernel'; - -import { mockIProfileCacheManager } from '../../../transactions/adapters/__helpers__/mocks'; -import { WalletLoginPresenter } from '../WalletLoginPresenter'; - -type SetupTestScenarioArgs = { - profile: Profile; -}; - -function setupTestScenario({ profile }: SetupTestScenarioArgs) { - const profileCacheManager = mockIProfileCacheManager(profile); - return new WalletLoginPresenter(profileCacheManager); -} - -describe(`Given an instance of the ${WalletLoginPresenter.name}`, () => { - const profile = mockProfileFragment(); - const expectations = { __typename: 'Profile', id: profile.id }; - - describe(`when "${WalletLoginPresenter.prototype.present.name}" method is invoked with a ProfileIdentifier`, () => { - it(`should resolve the "${WalletLoginPresenter.prototype.asResult.name}" promise with a success(Profile)`, async () => { - const identifier = mockProfileIdentifier(profile); - const presenter = setupTestScenario({ profile }); - - const promise = presenter.asResult(); - void presenter.present(success(identifier)); - const result = await promise; - - expect(result.unwrap()).toMatchObject(expectations); - }); - }); - - describe(`when "${WalletLoginPresenter.prototype.present.name}" method is invoked with an error`, () => { - it(`should resolve the "${WalletLoginPresenter.prototype.asResult.name}" promise with a failure(LoginError)`, async () => { - const presenter = setupTestScenario({ profile }); - - const promise = presenter.asResult(); - const err = new WalletConnectionError(WalletConnectionErrorReason.INCORRECT_CHAIN); - void presenter.present(failure(err)); - const result = await promise; - - expect(() => result.unwrap()).toThrow(WalletConnectionError); - }); - }); -}); diff --git a/packages/react-v1/src/wallet/adapters/errors.ts b/packages/react-v1/src/wallet/adapters/errors.ts deleted file mode 100644 index 07b4af8931..0000000000 --- a/packages/react-v1/src/wallet/adapters/errors.ts +++ /dev/null @@ -1,11 +0,0 @@ -type ErrorShape = { - code: T; - message: string; - stack: string; -}; - -export function assertErrorObjectWithCode(error: unknown): asserts error is ErrorShape { - if (!Object.prototype.hasOwnProperty.call(error, 'code')) { - throw error; - } -} diff --git a/packages/react-v1/src/wallet/adapters/useWalletLoginController.ts b/packages/react-v1/src/wallet/adapters/useWalletLoginController.ts deleted file mode 100644 index c92d6e000c..0000000000 --- a/packages/react-v1/src/wallet/adapters/useWalletLoginController.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { ActiveProfileLoader } from '@lens-protocol/domain/use-cases/profile'; -import { WalletLogin, WalletLoginRequest } from '@lens-protocol/domain/use-cases/wallets'; - -import { useSharedDependencies } from '../../shared'; -import { WalletLoginPresenter } from './WalletLoginPresenter'; - -export function useWalletLoginController() { - const { - activeProfileGateway, - credentialsFactory, - credentialsGateway, - profileCacheManager, - profileGateway, - walletFactory, - walletGateway, - sessionPresenter, - } = useSharedDependencies(); - - return async (request: WalletLoginRequest) => { - const loginPresenter = new WalletLoginPresenter(profileCacheManager); - const activeProfileLoader = new ActiveProfileLoader(profileGateway, activeProfileGateway); - const walletLogin = new WalletLogin( - walletFactory, - walletGateway, - credentialsFactory, - credentialsGateway, - loginPresenter, - activeProfileLoader, - sessionPresenter, - ); - - await walletLogin.login(request); - - return loginPresenter.asResult(); - }; -} diff --git a/packages/react-v1/src/wallet/adapters/useWalletLogoutController.ts b/packages/react-v1/src/wallet/adapters/useWalletLogoutController.ts deleted file mode 100644 index 6a6eef7ae7..0000000000 --- a/packages/react-v1/src/wallet/adapters/useWalletLogoutController.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { LogoutReason } from '@lens-protocol/domain/use-cases/wallets'; -import { PromiseResult, success } from '@lens-protocol/shared-kernel'; - -import { useSharedDependencies } from '../../shared'; - -export function useWalletLogoutController() { - const { walletLogout } = useSharedDependencies(); - - return async (reason: LogoutReason): PromiseResult => { - await walletLogout.logout(reason); - - return success(); - }; -} diff --git a/packages/react-v1/src/wallet/index.ts b/packages/react-v1/src/wallet/index.ts deleted file mode 100644 index b1f80bcb58..0000000000 --- a/packages/react-v1/src/wallet/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './useActiveWallet'; -export * from './useActiveWalletSigner'; -export * from './useWalletLogin'; -export * from './useWalletLogout'; - -export type { LogoutData } from '@lens-protocol/domain/use-cases/lifecycle'; - -export { LogoutReason } from '@lens-protocol/domain/use-cases/wallets'; -export type { RequiredSigner } from './adapters/ConcreteWallet'; -export type { Wallet } from '@lens-protocol/api-bindings'; diff --git a/packages/react-v1/src/wallet/infrastructure/AccessTokenStorage.ts b/packages/react-v1/src/wallet/infrastructure/AccessTokenStorage.ts deleted file mode 100644 index 81b828e7e8..0000000000 --- a/packages/react-v1/src/wallet/infrastructure/AccessTokenStorage.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { IAccessTokenStorage } from '@lens-protocol/api-bindings'; -import { CredentialsExpiredError } from '@lens-protocol/domain/use-cases/lifecycle'; -import { Deferred } from '@lens-protocol/shared-kernel'; - -import { Credentials } from '../adapters/Credentials'; -import { Callback, ICredentialsExpiryEmitter } from '../adapters/CredentialsExpiryController'; -import { AuthApi } from './AuthApi'; -import { CredentialsStorage } from './CredentialsStorage'; - -export class AccessTokenStorage implements IAccessTokenStorage, ICredentialsExpiryEmitter { - private isRefreshing = false; - private pendingRequests: Deferred[] = []; - - private listeners: Set = new Set(); - - constructor( - private readonly authApi: AuthApi, - private readonly credentialsStorage: CredentialsStorage, - ) {} - - onExpiry(callback: Callback) { - this.listeners.add(callback); - return () => this.listeners.delete(callback); - } - - getAccessToken(): string | null { - return this.credentialsStorage.getAccessToken(); - } - - async refreshToken(): Promise { - if (this.isRefreshing) { - const deferredPromise = new Deferred(); - this.pendingRequests.push(deferredPromise); - return deferredPromise.promise; - } - - this.isRefreshing = true; - const credentials = await this.credentialsStorage.get(); - - if (credentials && credentials.canRefresh()) { - await this.refreshCredentials(credentials); - this.isRefreshing = false; - return; - } - - this.rejectPendingRequests(); - this.isRefreshing = false; - this.emitExpiryEvent(); - throw new CredentialsExpiredError(); - } - - private async refreshCredentials(credentials: Credentials) { - const newCredentials = await this.authApi.refreshCredentials(credentials.refreshToken); - await this.credentialsStorage.set(newCredentials); - this.pendingRequests.map((request) => request.resolve()); - this.pendingRequests = []; - } - - private rejectPendingRequests() { - this.pendingRequests.map((request) => request.reject(new CredentialsExpiredError())); - this.pendingRequests = []; - } - - private emitExpiryEvent() { - this.listeners.forEach((callback) => callback()); - } -} diff --git a/packages/react-v1/src/wallet/infrastructure/AuthApi.ts b/packages/react-v1/src/wallet/infrastructure/AuthApi.ts deleted file mode 100644 index 12d672a153..0000000000 --- a/packages/react-v1/src/wallet/infrastructure/AuthApi.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - AuthAuthenticateDocument, - AuthAuthenticateData, - AuthAuthenticateVariables, - AuthChallengeDocument, - AuthChallengeData, - AuthChallengeVariables, - AuthRefreshDocument, - AuthRefreshData, - AuthRefreshVariables, - SafeApolloClient, -} from '@lens-protocol/api-bindings'; - -import { Credentials } from '../adapters/Credentials'; - -export class AuthApi { - constructor(private apolloClient: SafeApolloClient) {} - - async generateChallenge(address: string): Promise { - const result = await this.apolloClient.query({ - query: AuthChallengeDocument, - variables: { address }, - // challenge to sign should be always a new one - fetchPolicy: 'network-only', - }); - - return result.data.result.text; - } - - async generateCredentials(address: string, signature: string): Promise { - const result = await this.apolloClient.mutate({ - mutation: AuthAuthenticateDocument, - variables: { address, signature }, - }); - - const { accessToken, refreshToken } = result.data.result; - - return new Credentials(accessToken, refreshToken); - } - - async refreshCredentials(refreshToken: string): Promise { - const result = await this.apolloClient.mutate({ - mutation: AuthRefreshDocument, - variables: { refreshToken }, - }); - - const { accessToken: newAccessToken, refreshToken: newRefreshToken } = result.data.result; - - return new Credentials(newAccessToken, newRefreshToken); - } -} diff --git a/packages/react-v1/src/wallet/infrastructure/CredentialsStorage.ts b/packages/react-v1/src/wallet/infrastructure/CredentialsStorage.ts deleted file mode 100644 index 4b6cde605a..0000000000 --- a/packages/react-v1/src/wallet/infrastructure/CredentialsStorage.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { - BaseStorageSchema, - IStorage, - IStorageProvider, - Storage, - StorageSubscriber, - StorageSubscription, -} from '@lens-protocol/storage'; -import { z } from 'zod'; - -import { Credentials } from '../adapters/Credentials'; - -const AuthData = z.object({ - refreshToken: z.string(), -}); - -type AuthData = z.infer; - -/** - * Stores auth credentials. - * Access token is kept in memory. - * Refresh token is persisted permanently. - */ -export class CredentialsStorage implements IStorage { - refreshTokenStorage: IStorage; - accessToken: string | null = null; - - constructor(storageProvider: IStorageProvider, namespace: string) { - const authStorageSchema = new BaseStorageSchema(`lens.${namespace}.credentials`, AuthData); - this.refreshTokenStorage = Storage.createForSchema(authStorageSchema, storageProvider); - } - - async set({ accessToken, refreshToken }: Credentials): Promise { - this.accessToken = accessToken; - - await this.refreshTokenStorage.set({ refreshToken }); - } - - async get(): Promise { - const refreshToken = await this.getRefreshToken(); - - if (!refreshToken) { - return null; - } - - const accessToken = this.getAccessToken(); - - return new Credentials(accessToken, refreshToken); - } - - async reset(): Promise { - this.accessToken = null; - await this.refreshTokenStorage.reset(); - } - - subscribe(_: StorageSubscriber): StorageSubscription { - throw new Error('Method not implemented.'); - } - - getAccessToken(): string | null { - return this.accessToken; - } - - private async getRefreshToken(): Promise { - const result = await this.refreshTokenStorage.get(); - - return result?.refreshToken ?? null; - } -} diff --git a/packages/react-v1/src/wallet/infrastructure/NotificationStorage.ts b/packages/react-v1/src/wallet/infrastructure/NotificationStorage.ts deleted file mode 100644 index 02ad379f03..0000000000 --- a/packages/react-v1/src/wallet/infrastructure/NotificationStorage.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { BaseStorageSchema, IStorageProvider, Storage } from '@lens-protocol/storage'; -import { z } from 'zod'; - -export const UnreadNotificationsData = z.object({ - totalReadNotificationsCount: z.number().nullable(), -}); - -export type UnreadNotificationsData = z.infer; - -export function createNotificationStorage(storageProvider: IStorageProvider, namespace: string) { - const notificationStorageDataSchema = new BaseStorageSchema( - `lens.${namespace}.notifications`, - UnreadNotificationsData, - ); - return Storage.createForSchema(notificationStorageDataSchema, storageProvider); -} diff --git a/packages/react-v1/src/wallet/infrastructure/ProviderFactory.ts b/packages/react-v1/src/wallet/infrastructure/ProviderFactory.ts deleted file mode 100644 index ab45116891..0000000000 --- a/packages/react-v1/src/wallet/infrastructure/ProviderFactory.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ChainType, invariant, never } from '@lens-protocol/shared-kernel'; -import { providers } from 'ethers'; - -import { ChainConfigRegistry } from '../../chains'; -import { IProviderFactory } from '../adapters/IProviderFactory'; - -export type GetProvider = (config: { chainId: number }) => Promise; - -export interface IProviderBinding { - getProvider: GetProvider; -} - -export class ProviderFactory implements IProviderFactory { - constructor( - private readonly bindings: IProviderBinding, - private readonly chains: ChainConfigRegistry, - ) {} - - async createProvider(config: { chainType: ChainType }): Promise { - const chainId = this.chains[config.chainType]?.chainId ?? never('Unable to determine chainId'); - const provider = await this.bindings.getProvider({ chainId }); - - const network = await provider.getNetwork(); - - invariant( - network.chainId === chainId, - `Invalid chainId. Expected ${chainId} but got ${network.chainId}`, - ); - - return provider; - } -} diff --git a/packages/react-v1/src/wallet/infrastructure/SignerFactory.ts b/packages/react-v1/src/wallet/infrastructure/SignerFactory.ts deleted file mode 100644 index 4e407dcc65..0000000000 --- a/packages/react-v1/src/wallet/infrastructure/SignerFactory.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { JsonRpcProvider } from '@ethersproject/providers'; -import { AddEthereumChainParameter, isTheSameAddress } from '@lens-protocol/blockchain-bindings'; -import { WalletConnectionError, WalletConnectionErrorReason } from '@lens-protocol/domain/entities'; -import { ChainType, failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; -import { errors, utils } from 'ethers'; - -import { ChainConfigRegistry } from '../../chains'; -import { CreateSignerConfig, ISignerFactory, RequiredSigner } from '../adapters/ConcreteWallet'; -import { assertErrorObjectWithCode } from '../adapters/errors'; - -export type GetSigner = (config: { chainId?: number }) => Promise; - -export interface ISignerBinding { - getSigner: GetSigner; -} - -export type SignerFactoryConfig = { - getSigner: GetSigner; - chains: ChainConfigRegistry; -}; - -export class SignerFactory implements ISignerFactory { - constructor( - private readonly bindings: ISignerBinding, - private readonly chains: ChainConfigRegistry, - ) {} - - async createSigner({ - address, - chainType, - }: CreateSignerConfig): PromiseResult { - const chainId = chainType ? this.chains[chainType].chainId : undefined; - const signer = await this.bindings.getSigner({ chainId }); - - const signerAddress = await signer.getAddress(); - - if (!isTheSameAddress(address, signerAddress)) { - return failure(new WalletConnectionError(WalletConnectionErrorReason.WRONG_ACCOUNT)); - } - - if (chainType) { - try { - const signerChainId = await signer.getChainId(); - if (signerChainId !== chainId) { - const chainConfig = this.createAddEthereumChainParameter(chainType); - - await this.addChain(signer, chainConfig); - - const result = await this.switchChain(signer, chainConfig); - - if (result.isFailure()) { - return failure(result.error); - } - } - } catch (err) { - assertErrorObjectWithCode(err); - - if (err.code === errors.UNSUPPORTED_OPERATION) { - return failure(new WalletConnectionError(WalletConnectionErrorReason.INCORRECT_CHAIN)); - } - } - } - return success(signer); - } - - private createAddEthereumChainParameter(chainType: ChainType): AddEthereumChainParameter { - const chainConfig = this.chains[chainType]; - return { - chainId: utils.hexValue(chainConfig.chainId), - chainName: chainConfig.name, - nativeCurrency: { - name: chainConfig.nativeCurrency.name, - symbol: chainConfig.nativeCurrency.symbol, - decimals: chainConfig.nativeCurrency.decimals, - }, - rpcUrls: [chainConfig.rpcUrl], - blockExplorerUrls: [chainConfig.blockExplorer], - }; - } - - private async addChain(signer: RequiredSigner, chainConfig: AddEthereumChainParameter) { - try { - if (signer.provider && signer.provider instanceof JsonRpcProvider) { - await signer.provider.send('wallet_addEthereumChain', [chainConfig]); - } - } catch { - // noop - } - } - - private async switchChain( - signer: RequiredSigner, - chainConfig: AddEthereumChainParameter, - ): PromiseResult { - try { - if (signer.provider && signer.provider instanceof JsonRpcProvider) { - await signer.provider.send('wallet_switchEthereumChain', [ - { chainId: utils.hexValue(chainConfig.chainId) }, - ]); - - return success(); - } - } catch { - // noop - } - - return failure(new WalletConnectionError(WalletConnectionErrorReason.INCORRECT_CHAIN)); - } -} diff --git a/packages/react-v1/src/wallet/infrastructure/WalletStorage.ts b/packages/react-v1/src/wallet/infrastructure/WalletStorage.ts deleted file mode 100644 index f6eccc75ea..0000000000 --- a/packages/react-v1/src/wallet/infrastructure/WalletStorage.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BaseStorageSchema, IStorageProvider, Storage } from '@lens-protocol/storage'; - -import { WalletStorageSchema } from '../adapters/WalletGateway'; - -export function createWalletStorage(storageProvider: IStorageProvider, namespace: string) { - const walletStorageDataSchema = new BaseStorageSchema( - `lens.${namespace}.wallets`, - WalletStorageSchema, - ); - return Storage.createForSchema(walletStorageDataSchema, storageProvider); -} diff --git a/packages/react-v1/src/wallet/infrastructure/__helpers__/mocks.ts b/packages/react-v1/src/wallet/infrastructure/__helpers__/mocks.ts deleted file mode 100644 index 864f88c792..0000000000 --- a/packages/react-v1/src/wallet/infrastructure/__helpers__/mocks.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Networkish } from '@ethersproject/providers'; -import { ChainType } from '@lens-protocol/shared-kernel'; -import { providers } from 'ethers'; -import { mock } from 'jest-mock-extended'; -import { when } from 'jest-when'; - -import { production } from '../../../environments'; -import { RequiredSigner } from '../../adapters/ConcreteWallet'; -import { ISignerBinding } from '../SignerFactory'; - -export class VoidJsonRpcProvider extends providers.JsonRpcProvider { - constructor(network: Networkish) { - super('', network); - this.send = jest.fn(); - } -} - -export function mockISignerBinding({ - chainType, - signer, -}: { - chainType?: ChainType; - signer: RequiredSigner; -}): ISignerBinding { - const bindings = mock(); - - if (chainType) { - when(bindings.getSigner) - .calledWith({ chainId: production.chains[chainType].chainId }) - .mockResolvedValue(signer); - } else { - when(bindings.getSigner).mockResolvedValue(signer); - } - - return bindings; -} diff --git a/packages/react-v1/src/wallet/infrastructure/__tests__/ProviderFactory.spec.ts b/packages/react-v1/src/wallet/infrastructure/__tests__/ProviderFactory.spec.ts deleted file mode 100644 index 174bdcf476..0000000000 --- a/packages/react-v1/src/wallet/infrastructure/__tests__/ProviderFactory.spec.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { ChainType, InvariantError } from '@lens-protocol/shared-kernel'; -import { providers, utils } from 'ethers'; -import { mock } from 'jest-mock-extended'; -import { when } from 'jest-when'; - -import { production } from '../../../environments'; -import { IProviderBinding, ProviderFactory } from '../ProviderFactory'; -import { VoidJsonRpcProvider } from '../__helpers__/mocks'; - -function setupTestScenario({ - provider, - chainType, -}: { - provider: providers.JsonRpcProvider; - chainType: ChainType; -}) { - const bindings = mock(); - - when(bindings.getProvider) - .calledWith({ chainId: production.chains[chainType].chainId }) - .mockResolvedValue(provider); - - const providerFactory = new ProviderFactory(bindings, production.chains); - - return { providerFactory }; -} - -describe(`Given an instance of the ${ProviderFactory.name}`, () => { - describe(`when invoking the ${ProviderFactory.prototype.createProvider.name} method`, () => { - const chainType = ChainType.POLYGON; - - it('should retrieve the signer via the ISignerBinding', async () => { - const provider = new VoidJsonRpcProvider('matic'); - const { providerFactory } = setupTestScenario({ provider, chainType }); - - when(provider.send) - .calledWith('eth_chainId', []) - .mockResolvedValue(utils.hexlify(production.chains[chainType].chainId)); - - const result = await providerFactory.createProvider({ chainType }); - - expect(result).toBe(provider); - }); - - it(`should throw an ${InvariantError.name} in case the provider is not connected to the desired chain`, async () => { - const provider = new VoidJsonRpcProvider('homestead'); - const { providerFactory } = setupTestScenario({ provider, chainType }); - - when(provider.send) - .calledWith('eth_chainId', []) - .mockResolvedValue(utils.hexlify(production.chains[ChainType.ETHEREUM].chainId)); - - await expect(providerFactory.createProvider({ chainType })).rejects.toThrowError( - InvariantError, - ); - }); - }); -}); diff --git a/packages/react-v1/src/wallet/infrastructure/__tests__/SignerFactory.spec.ts b/packages/react-v1/src/wallet/infrastructure/__tests__/SignerFactory.spec.ts deleted file mode 100644 index 3b8a2c64d7..0000000000 --- a/packages/react-v1/src/wallet/infrastructure/__tests__/SignerFactory.spec.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { WalletConnectionError, WalletConnectionErrorReason } from '@lens-protocol/domain/entities'; -import { ChainType } from '@lens-protocol/shared-kernel'; -import { mockEthereumAddress } from '@lens-protocol/shared-kernel/mocks'; -import { errors, Wallet, logger, providers, utils, VoidSigner } from 'ethers'; -import { when } from 'jest-when'; - -import { production } from '../../../environments'; -import { RequiredSigner } from '../../adapters/ConcreteWallet'; -import { SignerFactory } from '../SignerFactory'; -import { mockISignerBinding, VoidJsonRpcProvider } from '../__helpers__/mocks'; - -const address = mockEthereumAddress(); - -function setupTestScenario({ - signer, - chainType, -}: { - signer: RequiredSigner; - chainType?: ChainType; -}) { - const bindings = mockISignerBinding({ chainType, signer }); - - const signerFactory = new SignerFactory(bindings, production.chains); - - return { signerFactory }; -} - -class VoidSignerWithJsonRpcProvider extends VoidSigner implements RequiredSigner { - declare provider: providers.JsonRpcProvider; - - constructor( - address: string, - provider: providers.JsonRpcProvider = new VoidJsonRpcProvider('homestead'), - ) { - super(address, provider); - } -} - -describe(`Given an instance of the ${SignerFactory.name}`, () => { - describe(`when invoking the ${SignerFactory.prototype.createSigner.name} method`, () => { - it('should retrieve the signer via the ISignerBinding', async () => { - const signer = new VoidSignerWithJsonRpcProvider(address); - const { signerFactory } = setupTestScenario({ signer }); - - const result = await signerFactory.createSigner({ address }); - - expect(result.unwrap()).toBe(signer); - }); - - it(`should fail with ${WalletConnectionError.name}(${WalletConnectionErrorReason.WRONG_ACCOUNT}) in case of address mismatch`, async () => { - const signer = new VoidSignerWithJsonRpcProvider(mockEthereumAddress()); - const { signerFactory } = setupTestScenario({ signer }); - - const result = await signerFactory.createSigner({ address }); - - const error = new WalletConnectionError(WalletConnectionErrorReason.WRONG_ACCOUNT); - expect(() => result.unwrap()).toThrowError(error); - }); - - describe('with a specified chain', () => { - const chainType = ChainType.POLYGON; - - it('should add the desired chain configuration in a best effort fashion', async () => { - const provider = new VoidJsonRpcProvider('homestead'); - const signer = new VoidSignerWithJsonRpcProvider(address, provider); - const { signerFactory } = setupTestScenario({ signer, chainType }); - - when(provider.send) - .calledWith('eth_chainId', []) - .mockResolvedValue(utils.hexlify(production.chains[ChainType.ETHEREUM].chainId)) - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - .calledWith('wallet_addEthereumChain', expect.anything()) - .mockRejectedValue(logger.makeError('Not implemented', errors.NOT_IMPLEMENTED, {})); - - await signerFactory.createSigner({ address, chainType }); - - expect(provider.send).toBeCalledWith('wallet_addEthereumChain', [ - expect.objectContaining({ - chainId: utils.hexlify(production.chains[chainType].chainId), - }), - ]); - }); - - it('should switch to the desired chain', async () => { - const provider = new VoidJsonRpcProvider('homestead'); - const signer = new VoidSignerWithJsonRpcProvider(address, provider); - const { signerFactory } = setupTestScenario({ signer, chainType }); - - when(provider.send) - .calledWith('eth_chainId', []) - .mockResolvedValue(utils.hexlify(production.chains[ChainType.ETHEREUM].chainId)); - - await signerFactory.createSigner({ address, chainType }); - - expect(provider.send).toBeCalledWith('wallet_switchEthereumChain', [ - { - chainId: utils.hexlify(production.chains[chainType].chainId), - }, - ]); - }); - - it(`should fail with ${WalletConnectionError.name}(${WalletConnectionErrorReason.INCORRECT_CHAIN}) in case it fails to switch to the desired chain`, async () => { - const provider = new VoidJsonRpcProvider('homestead'); - const signer = new VoidSignerWithJsonRpcProvider(address, provider); - const { signerFactory } = setupTestScenario({ signer, chainType }); - - when(provider.send) - .calledWith('eth_chainId', []) - .mockResolvedValue(utils.hexlify(production.chains[ChainType.ETHEREUM].chainId)) - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - .calledWith('wallet_switchEthereumChain', expect.anything()) - .mockRejectedValue(logger.makeError('Not implemented', errors.NOT_IMPLEMENTED, {})); - - const result = await signerFactory.createSigner({ address, chainType }); - - const error = new WalletConnectionError(WalletConnectionErrorReason.INCORRECT_CHAIN); - expect(() => result.unwrap()).toThrowError(error); - }); - }); - - describe('with a wallet', () => { - // This is the private key of the `@jsisthebest.test` profile - // It's a public private key so anyone can modify the profile - // For your own convenience change to the private key of a new wallet - const testWalletPrivateKey = - '6c434da5e5c0e3a8e0db5cf835d23e04c7592037854f0700c26836be7581c68c'; - - it('should retrieve the signer', async () => { - const wallet = new Wallet(testWalletPrivateKey); - - const { signerFactory } = setupTestScenario({ signer: wallet }); - - const result = await signerFactory.createSigner({ address: wallet.address }); - - expect(result.unwrap()).toBe(wallet); - }); - - it(`should fail with ${WalletConnectionError.name}(${WalletConnectionErrorReason.INCORRECT_CHAIN}) since it cannot switch chains`, async () => { - const wallet = new Wallet(testWalletPrivateKey); - - const { signerFactory } = setupTestScenario({ - signer: wallet, - chainType: ChainType.POLYGON, - }); - - const result = await signerFactory.createSigner({ - address: wallet.address, - chainType: ChainType.POLYGON, - }); - - const error = new WalletConnectionError(WalletConnectionErrorReason.INCORRECT_CHAIN); - expect(() => result.unwrap()).toThrowError(error); - }); - }); - }); -}); diff --git a/packages/react-v1/src/wallet/useActiveWallet.ts b/packages/react-v1/src/wallet/useActiveWallet.ts deleted file mode 100644 index 748fba3d93..0000000000 --- a/packages/react-v1/src/wallet/useActiveWallet.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { useSessionVar } from '@lens-protocol/api-bindings'; -import { WalletData } from '@lens-protocol/domain/use-cases/lifecycle'; - -import { ReadResult } from '../helpers/reads'; - -export type { WalletData }; - -/** - * `useActiveWallet` returns the active wallet, if any. Use this to determine if the user is logged in or not. - * - * @category Wallet - * @group Hooks - * - * @example - * ```tsx - * import { useActiveWallet } from '@lens-protocol/react-web'; - * - * function WalletStatus() { - * const { data: wallet, loading } = useActiveWallet(); - * - * if (loading) return

Loading...

; - * - * if (!wallet) return

Not logged in

; - * - * return

Logged in as {wallet.address}

; - * } - * ``` - */ -export function useActiveWallet(): ReadResult { - const session = useSessionVar(); - - if (session === null) { - return { - data: undefined, - loading: true, - }; - } - - if (session.isNotAuthenticated()) { - return { - data: null, - loading: false, - }; - } - - return { - data: session.wallet, - loading: false, - }; -} diff --git a/packages/react-v1/src/wallet/useActiveWalletSigner.ts b/packages/react-v1/src/wallet/useActiveWalletSigner.ts deleted file mode 100644 index c14b7babaa..0000000000 --- a/packages/react-v1/src/wallet/useActiveWalletSigner.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { useCallback, useEffect, useState } from 'react'; - -import { ReadResult } from '../helpers/reads'; -import { useSharedDependencies } from '../shared'; -import { RequiredSigner } from './adapters/ConcreteWallet'; -import { useActiveWallet } from './useActiveWallet'; - -/** - * @category Wallet - * @group Hooks - * @internal - */ -export function useActiveWalletSigner(): ReadResult { - const [{ signer, signerLoading }, setSigner] = useState<{ - signer: RequiredSigner | null; - signerLoading: boolean; - }>({ - signer: null, - signerLoading: false, - }); - const { bindings } = useSharedDependencies(); - const { data: wallet, loading: walletLoading } = useActiveWallet(); - - const retrieveSigner = useCallback(async () => { - setSigner({ - signer: null, - signerLoading: true, - }); - - try { - setSigner({ - signer: await bindings.getSigner({}), - signerLoading: false, - }); - } catch { - setSigner({ - signer: null, - signerLoading: true, - }); - } - }, [bindings]); - - useEffect(() => { - if (wallet) { - void retrieveSigner(); - } - }, [wallet, retrieveSigner]); - - if (walletLoading || signerLoading) { - return { - data: undefined, - loading: true, - }; - } - - return { - data: signer, - loading: false, - }; -} diff --git a/packages/react-v1/src/wallet/useWalletLogin.ts b/packages/react-v1/src/wallet/useWalletLogin.ts deleted file mode 100644 index 94c33efb42..0000000000 --- a/packages/react-v1/src/wallet/useWalletLogin.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Profile } from '@lens-protocol/api-bindings'; -import { LoginError } from '@lens-protocol/domain/use-cases/wallets'; -import { Result } from '@lens-protocol/shared-kernel'; -import { Signer } from 'ethers'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useWalletLoginController } from './adapters/useWalletLoginController'; - -export type UseWalletLoginArgs = { - /** - * The address of the wallet to login with. - * This will be used to retrieve the correct signer via the `{@link LensConfig#bindings}` provided. - */ - address: string; - /** - * The Profile handle to use as Active Profile once logged-in. - * If the wallet owns more than one profile, the handle can be used to select the profile to use. - */ - handle?: string; -}; - -export type WalletLoginResult = Profile | null; - -export type { LoginError }; - -export type WalletLoginOperation = Operation< - WalletLoginResult, - LoginError, - [Signer, string?] | [UseWalletLoginArgs] ->; - -/** - * `useWalletLogin` is a React Hook that allows you to login with a wallet. - * - * Works in conjunction with the `` component and the `{@link LensConfig#bindings}` config. - * - * @category Wallet - * @group Hooks - * - * @example - * ```tsx - * import { EthereumAddress, useWalletLogin } from '@lens-protocol/react-web'; - * - * function LoginButton({ address }: { address: EthereumAddress }) { - * const { execute, isPending } = useWalletLogin(); - * - * const login = async () => { - * const result = await execute({ address }); - * - * if (result.isSuccess()) { - * alert( - * result.value !== null - * ? `Welcome ${result.value.handle}` - * : 'Welcome!' - * ); - * } else { - * alert(result.error.message); - * } - * }; - * - * return ( - * - * ); - * } - * ``` - */ -export function useWalletLogin(): WalletLoginOperation { - const loginWallet = useWalletLoginController(); - - return useOperation( - async ( - walletLoginArgs: Signer | UseWalletLoginArgs, - handle?: string, - ): Promise> => { - if ('address' in walletLoginArgs) { - return loginWallet({ - address: walletLoginArgs.address, - handle: walletLoginArgs.handle, - }); - } - return loginWallet({ - address: await walletLoginArgs.getAddress(), - handle, - }); - }, - ); -} diff --git a/packages/react-v1/src/wallet/useWalletLogout.ts b/packages/react-v1/src/wallet/useWalletLogout.ts deleted file mode 100644 index aa6fa02854..0000000000 --- a/packages/react-v1/src/wallet/useWalletLogout.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { LogoutReason } from '@lens-protocol/domain/use-cases/wallets'; - -import { Operation, useOperation } from '../helpers/operations'; -import { useWalletLogoutController } from './adapters/useWalletLogoutController'; - -export type WalletLogoutOperation = Operation; - -/** - * `useWalletLogout` is an hook logs out the user and clears all local data. - * - * @category Wallet - * @group Hooks - * - * @example - * ```tsx - * function LogoutButton() { - * const { execute: logout, isPending } = useWalletLogout(); - * - * return ( - * - * ); - * } - * ``` - */ -export function useWalletLogout() { - const logout = useWalletLogoutController(); - return useOperation(async () => logout(LogoutReason.USER_INITIATED)); -} diff --git a/packages/react-v1/tsconfig.json b/packages/react-v1/tsconfig.json deleted file mode 100644 index edb77575a3..0000000000 --- a/packages/react-v1/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "@lens-protocol/tsconfig/base.json", - "compilerOptions": { - "jsx": "react-jsx", - "lib": ["DOM", "ESNext"], - "module": "ESNext", - "outDir": "dist" - }, - "include": ["./src"] -} diff --git a/packages/react-v1/tsdoc.json b/packages/react-v1/tsdoc.json deleted file mode 100644 index b89839ca22..0000000000 --- a/packages/react-v1/tsdoc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", - "extends": ["typedoc/tsdoc.json"] -} diff --git a/packages/react-web-v1/.eslintignore b/packages/react-web-v1/.eslintignore deleted file mode 100644 index 45161a327c..0000000000 --- a/packages/react-web-v1/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -dist -*.cjs diff --git a/packages/react-web-v1/.eslintrc.cjs b/packages/react-web-v1/.eslintrc.cjs deleted file mode 100644 index 68deb39c3e..0000000000 --- a/packages/react-web-v1/.eslintrc.cjs +++ /dev/null @@ -1,48 +0,0 @@ -module.exports = { - root: true, - extends: [ - '@lens-protocol/eslint-config', - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', - 'plugin:react/jsx-runtime', - ], - plugins: ['react', 'react-hooks'], - settings: { - react: { - version: 'detect', - }, - }, - rules: { - 'react/prop-types': 'off', - 'react/no-unescaped-entities': 'off', - 'react/jsx-curly-brace-presence': [ - 'error', - { props: 'never', children: 'never', propElementValues: 'always' }, - ], - 'no-restricted-imports': [ - 'error', - { - paths: [ - { - name: 'lodash', - message: 'Please use lodash submodules imports.', - }, - { - name: 'lodash/fp', - message: 'Please use lodash submodules imports.', - }, - { - name: '@apollo/client/testing', - importNames: ['createMockClient'], - message: 'Please import "mockLensApolloClient" from @lens-protocol/api-bindings/mocks.', - }, - { - name: '@apollo/client', - importNames: ['ApolloClient'], - message: 'Please use "createApolloClient" from @lens-protocol/api-bindings.', - }, - ], - }, - ], - }, -}; diff --git a/packages/react-web-v1/.prettierignore b/packages/react-web-v1/.prettierignore deleted file mode 100644 index 3f6fff7b2b..0000000000 --- a/packages/react-web-v1/.prettierignore +++ /dev/null @@ -1,2 +0,0 @@ -dist -coverage \ No newline at end of file diff --git a/packages/react-web-v1/CHANGELOG.md b/packages/react-web-v1/CHANGELOG.md deleted file mode 100644 index 66ccd23ffe..0000000000 --- a/packages/react-web-v1/CHANGELOG.md +++ /dev/null @@ -1,624 +0,0 @@ -# @lens-protocol/react-web - -## 1.3.1 - -### Patch Changes - -- ace02d32: **Fixes** support for ERC1155 gated content -- 5f251069: **Fixed** `usePublications` to refetch on `publicationIds` change -- dfb15e1a: **Fixed** 1.3.1-next.0 release packages bundles -- ebc2e7e5: **Added** `publicationsId` to `usePublications` args -- Updated dependencies [ace02d32] -- Updated dependencies [5f251069] -- Updated dependencies [dfb15e1a] -- Updated dependencies [ebc2e7e5] -- Updated dependencies [48dd0860] - - @lens-protocol/gated-content@0.3.3 - - @lens-protocol/react@1.3.1 - - @lens-protocol/api-bindings@0.10.1 - - @lens-protocol/domain@0.10.1 - -## 1.3.1-next.4 - -### Patch Changes - -- Updated dependencies [48dd0860] - - @lens-protocol/domain@0.10.1-next.0 - - @lens-protocol/react@1.3.1-next.4 - - @lens-protocol/api-bindings@0.10.1-next.3 - - @lens-protocol/gated-content@0.3.3-next.4 - -## 1.3.1-next.3 - -### Patch Changes - -- ace02d32: **Fixes** support for ERC1155 gated content -- Updated dependencies [ace02d32] - - @lens-protocol/gated-content@0.3.3-next.3 - - @lens-protocol/react@1.3.1-next.3 - -## 1.3.1-next.2 - -### Patch Changes - -- 5f251069: **Fixed** `usePublications` to refetch on `publicationIds` change -- Updated dependencies [5f251069] - - @lens-protocol/api-bindings@0.10.1-next.2 - - @lens-protocol/react@1.3.1-next.2 - - @lens-protocol/gated-content@0.3.3-next.2 - -## 1.3.1-next.1 - -### Patch Changes - -- dfb15e1a: **Fixed** 1.3.1-next.0 release packages bundles -- Updated dependencies [dfb15e1a] - - @lens-protocol/api-bindings@0.10.1-next.1 - - @lens-protocol/react@1.3.1-next.1 - - @lens-protocol/gated-content@0.3.3-next.1 - -## 1.3.1-next.0 - -### Patch Changes - -- ebc2e7e5: **Added** `publicationsId` to `usePublications` args -- Updated dependencies [ebc2e7e5] - - @lens-protocol/react@1.3.1-next.0 - - @lens-protocol/api-bindings@0.10.1-next.0 - - @lens-protocol/gated-content@0.3.3-next.0 - -## 1.3.0 - -### Minor Changes - -- 40fce6ff: **Added** support for bookmarks: list, add, and remove from a Profile private list of publications -- ad797714: **Added** `useNotInterested` hook -- c2a91ef4: **Added** `Profile.invitedBy` field -- 636ff014: **Added** `profileIds` to `usePublications` hook -- cfe0d51e: **Added** `highSignalFilter` to `useNotifications` hook -- 3ffab7b9: **Added** newly created `Profile` to `useCreateProfile` result -- 19ed489e: **Added** `beforeCount` to all paginated hooks and refetch data on re-render of `usePublication` and `useProfile` hooks. -- 0f75f79d: **Added** experimental `useCurrentSession` hook - **Fixed** issue with `Profile` entity being leaked by the `useWalletLogin` hook - **Fixed** bug preventing logout on expired credentials detected at startup type -- 773c2ed8: **Added** ability to override `sources` in `useExplorePublications` hook and support to `noRandomize` param. -- 773c2ed8: **Added** `name` support to non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` -- 6eaaaf22: **Added** `Profile.followNftAddress` field -- 433760f3: **Added** ability to specify profile picture and follow policy when creating a new profile" -- fc31f146: **Added** experimental hooks that integrate with @xmtp/react-sdk -- 9428efeb: **Added** support for `attributes` and `image` for non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` -- 3b67207b: **Added** `appId` to `Comment` and `Post` -- 4c4505d2: **Added** support for Profile Guardian -- bdbc71d5: **Added** ability to await newly created post in `useCreatePost` hook - -### Patch Changes - -- 09206763: **Fixed** issue with `useWalletLogin` never settling -- 773c2ed8: **Fixes** issues with `profileIds` not used to evaluate cache hits. Affecting `usePublications` and `useProfiles`. -- b7609fcb: **Fixed** `useNotification` to include `highSignalFilter` filter -- 773c2ed8: **Added** missing `commentsOfOrdering` and `commentsRankingFilter` to `useComments` hook -- 125ec30c: **Fixed** `usePollDetails` to be robust to flagged or misconfigured Snapshot Proposals -- 28094a84: **Fixed** XMTP dep is optional until chat features are requested via `@lens-protocol/react-web/inbox` entrypoint -- Updated dependencies [de401a59] -- Updated dependencies [a5cf2198] -- Updated dependencies [c8426cb3] -- Updated dependencies [09206763] -- Updated dependencies [df70461c] -- Updated dependencies [40fce6ff] -- Updated dependencies [ad797714] -- Updated dependencies [773c2ed8] -- Updated dependencies [c2a91ef4] -- Updated dependencies [b7609fcb] -- Updated dependencies [636ff014] -- Updated dependencies [773c2ed8] -- Updated dependencies [cfe0d51e] -- Updated dependencies [3ffab7b9] -- Updated dependencies [19ed489e] -- Updated dependencies [0f75f79d] -- Updated dependencies [847a9db3] -- Updated dependencies [d5efd895] -- Updated dependencies [773c2ed8] -- Updated dependencies [773c2ed8] -- Updated dependencies [125ec30c] -- Updated dependencies [28094a84] -- Updated dependencies [1d13a3ab] -- Updated dependencies [6eaaaf22] -- Updated dependencies [433760f3] -- Updated dependencies [fc31f146] -- Updated dependencies [9428efeb] -- Updated dependencies [e8dc3cd8] -- Updated dependencies [3b67207b] -- Updated dependencies [4c4505d2] -- Updated dependencies [bdbc71d5] -- Updated dependencies [5943a0f0] - - @lens-protocol/api-bindings@0.10.0 - - @lens-protocol/react@1.3.0 - - @lens-protocol/gated-content@0.3.2 - - @lens-protocol/domain@0.10.0 - - @lens-protocol/shared-kernel@0.10.0 - - @lens-protocol/storage@0.7.4 - -## 1.3.0-next.11 - -### Patch Changes - -- 09206763: **Fixed** issue with `useWalletLogin` never settling -- Updated dependencies [09206763] - - @lens-protocol/react@1.3.0-next.11 - -## 1.3.0-next.10 - -### Minor Changes - -- bdbc71d5: **Added** ability to await newly created post in `useCreatePost` hook - -### Patch Changes - -- Updated dependencies [bdbc71d5] - - @lens-protocol/react@1.3.0-next.10 - - @lens-protocol/shared-kernel@0.10.0-next.2 - - @lens-protocol/domain@0.10.0-next.7 - - @lens-protocol/api-bindings@0.10.0-next.8 - - @lens-protocol/gated-content@0.3.2-next.8 - - @lens-protocol/storage@0.7.4-next.2 - -## 1.3.0-next.9 - -### Patch Changes - -- Updated dependencies - - @lens-protocol/shared-kernel@0.10.0-next.1 - - @lens-protocol/api-bindings@0.10.0-next.7 - - @lens-protocol/domain@0.10.0-next.6 - - @lens-protocol/gated-content@0.3.2-next.7 - - @lens-protocol/react@1.3.0-next.9 - - @lens-protocol/storage@0.7.4-next.1 - -## 1.3.0-next.8 - -### Minor Changes - -- 773c2ed8: **Added** ability to override `sources` in `useExplorePublications` hook and support to `noRandomize` param. -- 773c2ed8: **Added** `name` support to non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` - -### Patch Changes - -- 773c2ed8: **Fixes** issues with `profileIds` not used to evaluate cache hits. Affecting `usePublications` and `useProfiles`. -- 773c2ed8: **Added** missing `commentsOfOrdering` and `commentsRankingFilter` to `useComments` hook -- Updated dependencies [773c2ed8] -- Updated dependencies [773c2ed8] -- Updated dependencies [773c2ed8] -- Updated dependencies [773c2ed8] - - @lens-protocol/api-bindings@0.10.0-next.6 - - @lens-protocol/react@1.3.0-next.8 - - @lens-protocol/domain@0.10.0-next.5 - - @lens-protocol/gated-content@0.3.2-next.6 - -## 1.3.0-next.7 - -### Patch Changes - -- 28094a84: **Fixed** XMTP dep is optional until chat features are requested via `@lens-protocol/react-web/inbox` entrypoint -- Updated dependencies [28094a84] - - @lens-protocol/react@1.3.0-next.7 - -## 1.3.0-next.6 - -### Minor Changes - -- 3ffab7b9: **Added** newly created `Profile` to `useCreateProfile` result -- 19ed489e: **Added** `beforeCount` to all paginated hooks and refetch data on re-render of `usePublication` and `useProfile` hooks. -- 6eaaaf22: **Added** `Profile.followNftAddress` field - -### Patch Changes - -- Updated dependencies [3ffab7b9] -- Updated dependencies [19ed489e] -- Updated dependencies [6eaaaf22] - - @lens-protocol/react@1.3.0-next.6 - - @lens-protocol/domain@0.10.0-next.4 - - @lens-protocol/api-bindings@0.10.0-next.5 - - @lens-protocol/gated-content@0.3.2-next.5 - -## 1.3.0-next.5 - -### Minor Changes - -- 433760f3: **Added** ability to specify profile picture and follow policy when creating a new profile" -- fc31f146: **Added** experimental hooks that integrate with @xmtp/react-sdk - -### Patch Changes - -- b7609fcb: **Fixed** `useNotification` to include `highSignalFilter` filter -- Updated dependencies [b7609fcb] -- Updated dependencies [433760f3] -- Updated dependencies [fc31f146] -- Updated dependencies [e8dc3cd8] - - @lens-protocol/api-bindings@0.10.0-next.4 - - @lens-protocol/react@1.3.0-next.5 - - @lens-protocol/domain@0.10.0-next.3 - - @lens-protocol/shared-kernel@0.10.0-next.0 - - @lens-protocol/gated-content@0.3.2-next.4 - - @lens-protocol/storage@0.7.4-next.0 - -## 1.3.0-next.4 - -### Minor Changes - -- 9428efeb: **Added** support for `attributes` and `image` for non-collectable publications. Affects `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` - -### Patch Changes - -- Updated dependencies [9428efeb] - - @lens-protocol/react@1.3.0-next.4 - - @lens-protocol/api-bindings@0.10.0-next.3 - - @lens-protocol/gated-content@0.3.2-next.3 - -## 1.3.0-next.3 - -### Minor Changes - -- 40fce6ff: **Added** support for bookmarks: list, add, and remove from a Profile private list of publications -- ad797714: **Added** `useNotInterested` hook -- 636ff014: **Added** `profileIds` to `usePublications` hook -- 3b67207b: **Added** `appId` to `Comment` and `Post` - -### Patch Changes - -- 125ec30c: **Fixed** `usePollDetails` to be robust to flagged or misconfigured Snapshot Proposals -- Updated dependencies [de401a59] -- Updated dependencies [a5cf2198] -- Updated dependencies [40fce6ff] -- Updated dependencies [ad797714] -- Updated dependencies [636ff014] -- Updated dependencies [125ec30c] -- Updated dependencies [3b67207b] - - @lens-protocol/api-bindings@0.10.0-next.2 - - @lens-protocol/react@1.3.0-next.3 - - @lens-protocol/gated-content@0.3.2-next.2 - -## 1.3.0-next.2 - -### Patch Changes - -- Updated dependencies [df70461c] -- Updated dependencies [1d13a3ab] - - @lens-protocol/react@1.3.0-next.2 - -## 1.3.0-next.1 - -### Patch Changes - -- Updated dependencies [d5efd895] - - @lens-protocol/api-bindings@0.9.2-next.1 - - @lens-protocol/gated-content@0.3.2-next.1 - - @lens-protocol/react@1.3.0-next.1 - -## 1.2.2 - -### Patch Changes - -- Updated dependencies [06a30a2c] - - @lens-protocol/api-bindings@0.9.1 - - @lens-protocol/gated-content@0.3.1 - - @lens-protocol/react@1.2.2 - -## 1.3.0-next.0 - -### Minor Changes - -- c2a91ef4: **Added** `Profile.invitedBy` field -- cfe0d51e: **Added** `highSignalFilter` to `useNotifications` hook -- 0f75f79d: **Added** experimental `useCurrentSession` hook - **Fixed** issue with `Profile` entity being leaked by the `useWalletLogin` hook - **Fixed** bug preventing logout on expired credentials detected at startup type -- 4c4505d2: **Added** support for Profile Guardian - -### Patch Changes - -- Updated dependencies [c8426cb3] -- Updated dependencies [c2a91ef4] -- Updated dependencies [cfe0d51e] -- Updated dependencies [0f75f79d] -- Updated dependencies [847a9db3] -- Updated dependencies [4c4505d2] - - @lens-protocol/react@1.3.0-next.0 - - @lens-protocol/api-bindings@0.9.1-next.0 - - @lens-protocol/gated-content@0.3.1-next.0 - -## 1.2.1 - -### Patch Changes - -- Updated dependencies [6be8cfb6] - - @lens-protocol/react@1.2.1 - -## 1.2.0 - -### Minor Changes - -- cb5b900d: **Added** sandbox environment support -- 225f0fa7: **Added** `usePollDetail` and `usePollVote` hooks - -### Patch Changes - -- Updated dependencies [cb5b900d] -- Updated dependencies [af4b1133] -- Updated dependencies [55211083] -- Updated dependencies [3025d56a] -- Updated dependencies [422c627e] -- Updated dependencies [1d99413a] -- Updated dependencies [225f0fa7] -- Updated dependencies [ea0b40e3] -- Updated dependencies [a899553c] -- Updated dependencies [422c627e] -- Updated dependencies [2dbe0035] -- Updated dependencies [148e9636] -- Updated dependencies [e4be6c07] -- Updated dependencies [97ecba69] - - @lens-protocol/gated-content@0.3.0 - - @lens-protocol/react@1.2.0 - - @lens-protocol/api-bindings@0.9.0 - - @lens-protocol/shared-kernel@0.9.0 - - @lens-protocol/storage@0.7.3 - -## 1.2.0-next.4 - -### Patch Changes - -- Updated dependencies [ea0b40e3] -- Updated dependencies [a899553c] - - @lens-protocol/react@1.2.0-next.4 - - @lens-protocol/api-bindings@0.9.0-next.2 - - @lens-protocol/gated-content@0.3.0-next.4 - -## 1.1.1 - -### Patch Changes - -- Updated dependencies [58217985] - - @lens-protocol/api-bindings@0.8.1 - - @lens-protocol/gated-content@0.2.3 - - @lens-protocol/react@1.1.1 - -## 1.2.0-next.3 - -### Patch Changes - -- Updated dependencies [2dbe0035] - - @lens-protocol/gated-content@0.3.0-next.3 - - @lens-protocol/react@1.2.0-next.3 - -## 1.2.0-next.2 - -### Minor Changes - -- 225f0fa7: **Added** `usePollDetail` and `usePollVote` hooks - -### Patch Changes - -- Updated dependencies [3025d56a] -- Updated dependencies [422c627e] -- Updated dependencies [225f0fa7] -- Updated dependencies [422c627e] -- Updated dependencies [97ecba69] - - @lens-protocol/api-bindings@0.9.0-next.1 - - @lens-protocol/react@1.2.0-next.2 - - @lens-protocol/shared-kernel@0.9.0-next.0 - - @lens-protocol/gated-content@0.3.0-next.2 - - @lens-protocol/storage@0.7.3-next.0 - -## 1.2.0-next.1 - -### Patch Changes - -- Updated dependencies [55211083] -- Updated dependencies [148e9636] - - @lens-protocol/react@1.2.0-next.1 - - @lens-protocol/gated-content@0.3.0-next.1 - - @lens-protocol/api-bindings@0.8.1-next.0 - -## 1.2.0-next.0 - -### Minor Changes - -- cb5b900d: **Added** sandbox environment support - -### Patch Changes - -- Updated dependencies [cb5b900d] -- Updated dependencies [af4b1133] - - @lens-protocol/gated-content@0.3.0-next.0 - - @lens-protocol/react@1.2.0-next.0 - -## 1.1.0 - -### Minor Changes - -- cf4a420: **Added** support for cover and `altTag` in publication media attributes - -### Patch Changes - -- 72becec: **Fixed** documentation for `useuseActiveProfileSwitch` and `useProfilesOwnedByMe` hooks -- b738abb: **Fixed** `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` callback argument -- Updated dependencies [1d5cf31] -- Updated dependencies [03a8ad5] -- Updated dependencies [37bf8e8] -- Updated dependencies [72becec] -- Updated dependencies [ca9b8cb] -- Updated dependencies [513373d] -- Updated dependencies [98c6547] -- Updated dependencies [04647bb] -- Updated dependencies [c416a2e] -- Updated dependencies [cf4a420] -- Updated dependencies [ef1d7e2] -- Updated dependencies [b738abb] -- Updated dependencies [5c5bfb2] -- Updated dependencies [71196cf] -- Updated dependencies [c4e6fcf] - - @lens-protocol/react@1.1.0 - - @lens-protocol/api-bindings@0.8.0 - - @lens-protocol/shared-kernel@0.8.0 - - @lens-protocol/gated-content@0.2.2 - - @lens-protocol/storage@0.7.2 - -## 1.1.0-next.5 - -### Patch Changes - -- Updated dependencies [37bf8e8] - - @lens-protocol/api-bindings@0.8.0-next.4 - - @lens-protocol/gated-content@0.2.2-next.4 - - @lens-protocol/react@1.1.0-next.5 - -## 1.1.0-next.4 - -### Patch Changes - -- b738abb: Fixed `useCreatePost`, `useCreateComment`, `useCreateEncryptedPost`, and `useCreateEncryptedComment` callback argument -- Updated dependencies [b738abb] -- Updated dependencies [5c5bfb2] - - @lens-protocol/shared-kernel@0.8.0-next.1 - - @lens-protocol/react@1.1.0-next.4 - - @lens-protocol/api-bindings@0.8.0-next.3 - - @lens-protocol/gated-content@0.2.2-next.3 - - @lens-protocol/storage@0.7.2-next.1 - -## 1.1.0-next.3 - -### Patch Changes - -- Updated dependencies [1d5cf31] - - @lens-protocol/react@1.1.0-next.3 - -## 1.1.0-next.2 - -### Patch Changes - -- Updated dependencies [ef1d7e2] - - @lens-protocol/api-bindings@0.8.0-next.2 - - @lens-protocol/react@1.1.0-next.2 - - @lens-protocol/gated-content@0.2.2-next.2 - -## 1.1.0-next.1 - -### Patch Changes - -- Updated dependencies [03a8ad5] -- Updated dependencies [ca9b8cb] -- Updated dependencies [71196cf] - - @lens-protocol/api-bindings@0.8.0-next.1 - - @lens-protocol/react@1.1.0-next.1 - - @lens-protocol/gated-content@0.2.2-next.1 - -## 1.1.0-next.0 - -### Minor Changes - -- cf4a4201: Added support for cover and `altTag` in publication media attributes - -### Patch Changes - -- 72becec0: **Fixed** documentation for `useuseActiveProfileSwitch` and `useProfilesOwnedByMe` hooks -- Updated dependencies [72becec0] -- Updated dependencies [513373d3] -- Updated dependencies [04647bbe] -- Updated dependencies [c416a2ea] -- Updated dependencies [cf4a4201] -- Updated dependencies [c4e6fcfc] - - @lens-protocol/react@1.1.0-next.0 - - @lens-protocol/api-bindings@0.8.0-next.0 - - @lens-protocol/shared-kernel@0.8.0-next.0 - - @lens-protocol/gated-content@0.2.2-next.0 - - @lens-protocol/storage@0.7.2-next.0 - -## 1.0.1 - -### Patch Changes - -- 425daba: **Fixed** 1.0.0 release packages bundles -- Updated dependencies [425daba] - - @lens-protocol/api-bindings@0.7.1 - - @lens-protocol/gated-content@0.2.1 - - @lens-protocol/react@1.0.1 - - @lens-protocol/shared-kernel@0.7.1 - - @lens-protocol/storage@0.7.1 - -## 1.0.0 - -### Minor Changes - -- 37eaf8a: Added TSDoc, use shared tsconfig, better types - -### Patch Changes - -- 520a7c1: Changed GQL generated types so that Fragment suffix is no longer necessary - - Added several missing TS type definitions - - Added TSDoc comments to several APIs -- 0f20b5a: Changed storage keys so use environment name as namespace -- 0f20b5a: Changed env config variables to be `development` and `production` -- Updated dependencies [fce5b18] -- Updated dependencies [520a7c1] -- Updated dependencies [6ae90ef] -- Updated dependencies [c5dd99b] -- Updated dependencies [0f20b5a] -- Updated dependencies [006aff5] -- Updated dependencies [37eaf8a] -- Updated dependencies [0f20b5a] -- Updated dependencies [a4e9500] - - @lens-protocol/react@1.0.0 - - @lens-protocol/api-bindings@0.7.0 - - @lens-protocol/gated-content@0.2.0 - - @lens-protocol/shared-kernel@0.7.0 - - @lens-protocol/storage@0.7.0 - -## 1.0.0-beta.1 - -### Patch Changes - -- 0f20b5a: Changed storage keys so use environment name as namespace -- 0f20b5a: Changed env config variables to be `development` and `production` -- Updated dependencies [0f20b5a] -- Updated dependencies [0f20b5a] - - @lens-protocol/gated-content@0.2.0-beta.1 - - @lens-protocol/react@1.0.0-beta.1 - -## 1.0.0-beta.0 - -### Minor Changes - -- dc1350d: Added TSDoc, use shared tsconfig, better types - -### Patch Changes - -- 520a7c1: Changed GQL generated types so that `Fragment` suffix is no longer necessary - Added several missing TS type definitions - Added TSDoc comments to several APIs -- Updated dependencies [fce5b18] -- Updated dependencies [520a7c1] -- Updated dependencies [6ae90ef] -- Updated dependencies [c5dd99b] -- Updated dependencies [006aff5] -- Updated dependencies [dc1350d] -- Updated dependencies [a4e9500] - - @lens-protocol/react@1.0.0-beta.0 - - @lens-protocol/api-bindings@0.7.0-beta.0 - - @lens-protocol/gated-content@0.2.0-beta.0 - - @lens-protocol/shared-kernel@0.7.0-beta.0 - - @lens-protocol/storage@0.7.0-beta.0 - -## 0.6.0 - -### Minor changes - -- 6be7f14: Added this package out of `@lens-protocol/react` as the canonical integration in the Rect web apps. Includes support for token-gated via WebCrypto API. - -### Patch Changes - -- Updated dependencies -- Updated dependencies [4475a27] - - @lens-protocol/react@0.6.0 - - @lens-protocol/api-bindings@0.6.0 - - @lens-protocol/gated-content@0.0.2 - - @lens-protocol/storage@0.6.0 - - @lens-protocol/shared-kernel@0.6.0 diff --git a/packages/react-web-v1/README.md b/packages/react-web-v1/README.md deleted file mode 100644 index 7f4ff2eea2..0000000000 --- a/packages/react-web-v1/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# `@lens-protocol/react-web` V1 - -The official Lens Protocol React bindings for web applications. - -This package enables you to build web applications on top of the Lens Protocol using React. - -## Documentation - -- [GitHub monorepo](https://github.com/lens-protocol/lens-sdk) -- [Getting Started](https://docs.lens.xyz/docs/sdk-react-getting-started) -- [SDK Reference](https://lens-protocol.github.io/lens-sdk/) diff --git a/packages/react-web-v1/inbox/package.json b/packages/react-web-v1/inbox/package.json deleted file mode 100644 index e4b5d403c3..0000000000 --- a/packages/react-web-v1/inbox/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "dist/lens-protocol-react-web-inbox.cjs.js", - "module": "dist/lens-protocol-react-web-inbox.esm.js" -} diff --git a/packages/react-web-v1/jest.config.ts b/packages/react-web-v1/jest.config.ts deleted file mode 100644 index 23d07751a0..0000000000 --- a/packages/react-web-v1/jest.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -// eslint-disable-next-line import/no-default-export -export default { - preset: 'ts-jest/presets/js-with-ts', - setupFilesAfterEnv: ['./src/__helpers__/jest.setup.ts'], - testEnvironment: 'jsdom', - testRegex: '/__tests__/.*|(\\.|/)spec\\.tsx?$', - testPathIgnorePatterns: ['/node_modules/', '/dist/'], -}; diff --git a/packages/react-web-v1/package.json b/packages/react-web-v1/package.json deleted file mode 100644 index ac1ba1ba30..0000000000 --- a/packages/react-web-v1/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "react-web-v1", - "version": "1.3.1", - "private": true, - "description": "Lens Protocol SDK for React web applications", - "main": "dist/lens-protocol-react-web.cjs.js", - "module": "dist/lens-protocol-react-web.esm.js", - "exports": { - ".": { - "module": "./dist/lens-protocol-react-web.esm.js", - "default": "./dist/lens-protocol-react-web.cjs.js" - }, - "./inbox": { - "module": "./inbox/dist/lens-protocol-react-web-inbox.esm.js", - "default": "./inbox/dist/lens-protocol-react-web-inbox.cjs.js" - }, - "./package.json": "./package.json" - }, - "repository": { - "directory": "packages/react-web", - "type": "git", - "url": "git://github.com/lens-protocol/lens-sdk.git" - }, - "sideEffects": false, - "files": [ - "dist", - "inbox" - ], - "scripts": { - "eslint:fix": "pnpm run eslint --fix", - "eslint": "eslint src", - "lint:fix": "pnpm run prettier:fix && pnpm run eslint:fix && pnpm run tsc", - "prettier:fix": "prettier --write .", - "prettier": "prettier --check .", - "test:watch": "jest --watch", - "tsc": "tsc --noEmit" - }, - "license": "MIT", - "dependencies": {}, - "devDependencies": {}, - "prettier": "@lens-protocol/prettier-config", - "babel": { - "presets": [ - "@babel/preset-env", - [ - "@babel/preset-react", - { - "runtime": "automatic" - } - ], - "@babel/preset-typescript" - ] - }, - "preconstruct": { - "entrypoints": [ - "index.ts", - "inbox/index.ts" - ], - "exports": true - }, - "typedoc": { - "entryPoint": "./src/index.ts", - "tsconfig": "./tsconfig.json" - } -} diff --git a/packages/react-web-v1/src/LensProvider.tsx b/packages/react-web-v1/src/LensProvider.tsx deleted file mode 100644 index 461c0f549b..0000000000 --- a/packages/react-web-v1/src/LensProvider.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { - AppId, - EnvironmentConfig, - ErrorHandler, - FailedTransactionError, - IBindings, - LensProvider as LensProviderBase, - LogoutHandler, -} from '@lens-protocol/react'; -import type { LensConfig as LensConfigBase } from '@lens-protocol/react'; -import { ILogger } from '@lens-protocol/shared-kernel'; -import { ReactNode, useState } from 'react'; - -import { localStorage } from './storage'; - -/** - * `` configuration - */ -export type LensConfig = { - /** - * Provides integration with the ethers.js Signer and Provider - */ - bindings: IBindings; - /** - * The environment to use. See {@link production}, {@link development}, and {@link sandbox}. - */ - environment: EnvironmentConfig; - /** - * The logger interface to use when something worth logging happens - * - * @defaultValue `ConsoleLogger`, an internal implementation of {@link ILogger} that logs to the console - */ - logger?: ILogger; - /** - * The `sources` determines the sources of posts and comments that will be fetched - * - * It also determines some Profile related statistics, such as the number of posts and comments - * - * @defaultValue any sources, not restricted. - */ - sources?: AppId[]; - /** - * The `appId` identifies post and comment created from the SDK - * - * The `appId`, if provided, MUST be included in the `sources` array. - * - * @defaultValue not set - * - * @see {@link appId} helper - */ - appId?: AppId; -}; - -/** - * props - */ -export type LensProviderProps = { - /** - * The children to render - */ - children: ReactNode; - /** - * The configuration for the Lens SDK - */ - config: LensConfig; - /** - * A callback that is called when the user logs out - * - * @defaultValue no-op - */ - onLogout?: LogoutHandler; - /** - * A callback that is called when a transaction fails - * - * @defaultValue no-op - */ - onError?: ErrorHandler; -}; - -const storage = localStorage(); - -/** - * Manages the lifecycle and internal state of the Lens SDK - * - * @group Components - * @param props - {@link LensProviderProps} - * - * @example - * ```tsx - * import { LensProvider, staging } from '@lens-protocol/react-web'; - * import { bindings as wagmiBindings } from '@lens-protocol/wagmi'; - * - * const lensConfig: LensConfig = { - * bindings: wagmiBindings(), - * environment: staging, - * }; - * - * function App() { - * return ( - * - * // ... - * - * ); - * } - * ``` - */ -export function LensProvider({ config, ...props }: LensProviderProps) { - const [resolvedConfig] = useState(() => ({ - ...config, - storage, - })); - - return ; -} diff --git a/packages/react-web-v1/src/__helpers__/jest.setup.ts b/packages/react-web-v1/src/__helpers__/jest.setup.ts deleted file mode 100644 index 4138d923be..0000000000 --- a/packages/react-web-v1/src/__helpers__/jest.setup.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Blob } from 'buffer'; -import crypto from 'crypto'; -import { TextEncoder, TextDecoder } from 'util'; - -Object.defineProperty(global, 'crypto', { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - value: Object.setPrototypeOf({ subtle: crypto.subtle }, crypto), -}); - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -global.Blob = Blob; - -// until https://github.com/jsdom/jsdom/issues/2524 is resolved -global.TextEncoder = TextEncoder; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -global.TextDecoder = TextDecoder; diff --git a/packages/react-web-v1/src/__tests__/storage.spec.ts b/packages/react-web-v1/src/__tests__/storage.spec.ts deleted file mode 100644 index ee5630c501..0000000000 --- a/packages/react-web-v1/src/__tests__/storage.spec.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { waitFor } from '@testing-library/react'; - -import { localStorage } from '../storage'; - -const key = 'key'; -const data = 'value'; - -function setupTestScenario() { - const provider = localStorage(); - - const subscriber = jest.fn(); - const subscription = provider.subscribe(key, subscriber); - - return { - subscriber, - - subscription, - - waitForUpdate: async () => { - await waitFor(() => { - expect(subscriber).toHaveBeenCalled(); - }); - }, - - dispatchStorageEvent: (init: StorageEventInit) => { - const event = new StorageEvent('storage', init); - window.dispatchEvent(event); - }, - }; -} - -describe(`Given an instance of IStorageProvider created via the "${localStorage.name}" factory`, () => { - describe('and a storage subscription for a given key', () => { - describe(`when a Web Storage API ${StorageEvent.name} is fired`, () => { - describe(`for a key different from the one of the subscription`, () => { - it('should not invoke the subscriber ', async () => { - const { subscriber, dispatchStorageEvent } = setupTestScenario(); - dispatchStorageEvent({ - key: 'otherKey', - storageArea: window.localStorage, - }); - - await Promise.resolve(); // give it a chance to execute - - expect(subscriber).not.toHaveBeenCalled(); - }); - }); - - describe(`for a ${Storage.name} area other than ${localStorage.name}`, () => { - it('should not invoke the subscriber', async () => { - const { subscriber, dispatchStorageEvent } = setupTestScenario(); - dispatchStorageEvent({ - key, - storageArea: window.sessionStorage, - }); - - await Promise.resolve(); // give it a chance to execute - - expect(subscriber).not.toHaveBeenCalled(); - }); - }); - - describe(`with 'event.oldValue = null' and new data in the 'event.newValue'`, () => { - it(`should invoke the subscribers with new data and 'null' as old data`, async () => { - const { dispatchStorageEvent, waitForUpdate, subscriber } = setupTestScenario(); - - dispatchStorageEvent({ - key, - storageArea: window.localStorage, - newValue: data, - oldValue: null, - }); - - await waitForUpdate(); - expect(subscriber).toHaveBeenCalledWith(data, null); - }); - }); - - describe(`with 'event.newValue = null'`, () => { - it(`should invoke the subscribers with 'null' and old data`, async () => { - const { dispatchStorageEvent, waitForUpdate, subscriber } = setupTestScenario(); - - dispatchStorageEvent({ - key, - storageArea: window.localStorage, - newValue: null, - oldValue: data, - }); - - await waitForUpdate(); - expect(subscriber).toHaveBeenCalledWith(null, data); - }); - }); - }); - - describe(`when unsubscribing`, () => { - it('should no longer invoke the subscriber', async () => { - const { dispatchStorageEvent, subscriber, subscription } = setupTestScenario(); - - subscription.unsubscribe(); - - dispatchStorageEvent({ - key, - storageArea: window.localStorage, - newValue: null, - oldValue: data, - }); - - await waitFor(() => { - expect(subscriber).not.toHaveBeenCalled(); - }); - }); - }); - }); -}); diff --git a/packages/react-web-v1/src/globals.ts b/packages/react-web-v1/src/globals.ts deleted file mode 100644 index 52e803fc8b..0000000000 --- a/packages/react-web-v1/src/globals.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import { maybe, never } from '@lens-protocol/shared-kernel'; - -const safeGlobal = (maybe(() => globalThis) ?? - maybe(() => window) ?? - maybe(() => self) ?? - maybe(() => global) ?? - never('Cannot resolve a global object.')) as typeof globalThis & Window; - -export const window = maybe(() => safeGlobal.window) ?? null; diff --git a/packages/react-web-v1/src/inbox/adapters/SignerAdapter.ts b/packages/react-web-v1/src/inbox/adapters/SignerAdapter.ts deleted file mode 100644 index 3bf23bdd7d..0000000000 --- a/packages/react-web-v1/src/inbox/adapters/SignerAdapter.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { - PendingSigningRequestError, - Signature, - UserRejectedError, - WalletConnectionError, -} from '@lens-protocol/domain/entities'; -import { SignArbitraryMessage } from '@lens-protocol/domain/use-cases/inbox'; -import type { ActiveWallet } from '@lens-protocol/domain/use-cases/wallets'; -import { IEquatableError } from '@lens-protocol/react'; -import { Deferred, Result } from '@lens-protocol/shared-kernel'; -import { Signer } from '@xmtp/react-sdk'; - -class PromiseResultPresenter { - private deferredResult = new Deferred>(); - - present(result: Result): void { - this.deferredResult.resolve(result); - } - - asResult(): Promise> { - return this.deferredResult.promise; - } -} - -export class SignerAdapter implements Signer { - constructor(private activeWallet: ActiveWallet) {} - - async getAddress() { - const wallet = await this.activeWallet.requireActiveWallet(); - - return wallet.address; - } - - async signMessage(request: string) { - const presenter = new PromiseResultPresenter< - Signature, - PendingSigningRequestError | UserRejectedError | WalletConnectionError - >(); - - const useCase = new SignArbitraryMessage(this.activeWallet, presenter); - - await useCase.execute(request); - - const result = await presenter.asResult(); - - return result.unwrap(); - } -} diff --git a/packages/react-web-v1/src/inbox/helpers/__tests__/conversationIdUtils.spec.ts b/packages/react-web-v1/src/inbox/helpers/__tests__/conversationIdUtils.spec.ts deleted file mode 100644 index 0c8ae2fbf2..0000000000 --- a/packages/react-web-v1/src/inbox/helpers/__tests__/conversationIdUtils.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { buildConversationId, extractPeerProfileId } from '../conversationIdUtils'; - -describe('Given a collection of inbox helper functions', () => { - describe(`when calling ${buildConversationId.name}`, () => { - it('should build the same conversationId for provided two profiles, no matter the order', () => { - const result1 = buildConversationId('0x15', '0x18'); - const result2 = buildConversationId('0x18', '0x15'); - - expect(result1).toEqual(result2); - }); - }); - - describe(`when calling ${extractPeerProfileId.name}`, () => { - it('should return undefined if not a lens conversation', () => { - const result1 = extractPeerProfileId('not-lens-conversation', '0x15'); - - expect(result1).toBe(undefined); - }); - - it('should return peer profileId for a lens conversation', () => { - const conversationId = buildConversationId('0x15', '0x18'); - - const result1 = extractPeerProfileId(conversationId, '0x15'); - const result2 = extractPeerProfileId(conversationId, '0x18'); - - expect(result1).toBe('0x18'); - expect(result2).toBe('0x15'); - }); - }); -}); diff --git a/packages/react-web-v1/src/inbox/helpers/conversationIdUtils.ts b/packages/react-web-v1/src/inbox/helpers/conversationIdUtils.ts deleted file mode 100644 index f6f1199acd..0000000000 --- a/packages/react-web-v1/src/inbox/helpers/conversationIdUtils.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { ProfileId, profileId as brandProfileId } from '@lens-protocol/react'; -import { invariant } from '@lens-protocol/shared-kernel'; - -const CONVERSATION_ID_PREFIX = 'lens.dev/dm'; - -export function buildConversationId(profileIdA: string, profileIdB: string) { - const profileIdAParsed = parseInt(profileIdA, 16); - const profileIdBParsed = parseInt(profileIdB, 16); - return profileIdAParsed < profileIdBParsed - ? `${CONVERSATION_ID_PREFIX}/${profileIdA}-${profileIdB}` - : `${CONVERSATION_ID_PREFIX}/${profileIdB}-${profileIdA}`; -} - -function parseConversationId(conversationId: string): [string, string] { - const conversationIdWithoutPrefix = conversationId.replace(`${CONVERSATION_ID_PREFIX}/`, ''); - const [profileIdA, profileIdB] = conversationIdWithoutPrefix.split('-'); - - invariant(profileIdA && profileIdB, 'Invalid conversation id'); - - return [profileIdA, profileIdB]; -} - -function isLensConversation( - activeProfileId: string, - conversationId?: string, -): conversationId is string { - if (conversationId && conversationId.includes(activeProfileId)) { - return true; - } - return false; -} - -export function extractPeerProfileId( - conversationId: string | undefined, - activeProfileId: string, -): ProfileId | undefined { - if (isLensConversation(activeProfileId, conversationId)) { - const [profileIdA, profileIdB] = parseConversationId(conversationId); - const result = profileIdA === activeProfileId ? profileIdB : profileIdA; - - return brandProfileId(result); - } - return undefined; -} diff --git a/packages/react-web-v1/src/inbox/helpers/createUniqueConversationId.ts b/packages/react-web-v1/src/inbox/helpers/createUniqueConversationId.ts deleted file mode 100644 index 8e40a5df20..0000000000 --- a/packages/react-web-v1/src/inbox/helpers/createUniqueConversationId.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Conversation } from '@xmtp/react-sdk'; - -/** - * Create a unique conversation ID based on sender/receiver addresses and - * context values - */ -export const createUniqueConversationId = (conversation: Conversation): string => - [conversation.clientAddress, conversation.peerAddress, conversation.context?.conversationId] - .filter((v) => Boolean(v)) - .join('/'); diff --git a/packages/react-web-v1/src/inbox/helpers/index.ts b/packages/react-web-v1/src/inbox/helpers/index.ts deleted file mode 100644 index 08345f6d37..0000000000 --- a/packages/react-web-v1/src/inbox/helpers/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './conversationIdUtils'; -export * from './createUniqueConversationId'; -export * from './notEmpty'; diff --git a/packages/react-web-v1/src/inbox/helpers/notEmpty.ts b/packages/react-web-v1/src/inbox/helpers/notEmpty.ts deleted file mode 100644 index 4be5afb840..0000000000 --- a/packages/react-web-v1/src/inbox/helpers/notEmpty.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function notEmpty(value: TValue | null | undefined): value is TValue { - return value !== null && value !== undefined; -} diff --git a/packages/react-web-v1/src/inbox/index.ts b/packages/react-web-v1/src/inbox/index.ts deleted file mode 100644 index 7a9e11141d..0000000000 --- a/packages/react-web-v1/src/inbox/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './types'; -export * from './useEnhanceConversation'; -export * from './useEnhanceConversations'; -export * from './useStartLensConversation'; -export * from './useXmtpClient'; diff --git a/packages/react-web-v1/src/inbox/types.ts b/packages/react-web-v1/src/inbox/types.ts deleted file mode 100644 index 2ead901ff0..0000000000 --- a/packages/react-web-v1/src/inbox/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Profile } from '@lens-protocol/react'; -import { Conversation } from '@xmtp/react-sdk'; - -export type EnhancedConversation = Conversation & { - peerProfile?: Profile; -}; diff --git a/packages/react-web-v1/src/inbox/useEnhanceConversation.ts b/packages/react-web-v1/src/inbox/useEnhanceConversation.ts deleted file mode 100644 index 268b1549bd..0000000000 --- a/packages/react-web-v1/src/inbox/useEnhanceConversation.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { ProfileId, ProfileOwnedByMe, ReadResult, useProfile } from '@lens-protocol/react'; -import { Conversation } from '@xmtp/react-sdk'; -import { useMemo } from 'react'; - -import { extractPeerProfileId } from './helpers'; -import { EnhancedConversation } from './types'; - -/** - * @experimental - */ -export type EnhanceConversationRequest = { - profile: ProfileOwnedByMe; - conversation: Conversation; -}; - -/** - * Enhance XMTP conversation with a profile of the conversation's peer - * - * @category Inbox - * @group Hooks - * @experimental - * - * @param args - {@link EnhanceConversationRequest} - */ -export function useEnhanceConversation({ - profile, - conversation, -}: EnhanceConversationRequest): ReadResult { - const peerProfileId = useMemo( - (): ProfileId | undefined => - extractPeerProfileId(conversation.context?.conversationId, profile.id), - [conversation, profile], - ); - - const skip = peerProfileId === undefined; - - const { data: peerProfile, loading } = useProfile( - skip - ? { - skip: true, - } - : { - profileId: peerProfileId, - }, - ); - - const enhancedConversation = useMemo((): EnhancedConversation => { - if (peerProfile) { - // Clone the xmtp Conversation instance with all its methods and add peerProfile - // eslint-disable-next-line - return Object.assign(Object.create(Object.getPrototypeOf(conversation)), conversation, { - peerProfile, - }); - } - return conversation; - }, [conversation, peerProfile]); - - if (skip) { - return { - data: conversation, - loading: false, - }; - } - - if (loading) { - return { - data: undefined, - loading: true, - }; - } - - return { - data: enhancedConversation, - loading: false, - }; -} diff --git a/packages/react-web-v1/src/inbox/useEnhanceConversations.ts b/packages/react-web-v1/src/inbox/useEnhanceConversations.ts deleted file mode 100644 index 26742a7f08..0000000000 --- a/packages/react-web-v1/src/inbox/useEnhanceConversations.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { - ProfileId, - ProfileOwnedByMe, - ReadResult, - UnspecifiedError, - useProfiles, -} from '@lens-protocol/react'; -import { assertError } from '@lens-protocol/shared-kernel'; -import { useConversations } from '@xmtp/react-sdk'; -import { useMemo } from 'react'; - -import { extractPeerProfileId, createUniqueConversationId, notEmpty } from './helpers'; -import { EnhancedConversation } from './types'; - -/** - * @experimental - */ -export type EnhanceConversationsRequest = { - profile: ProfileOwnedByMe; -}; - -/** - * Enhance XMTP conversations with profiles of the conversations' peers, - * if conversation is between two Lens profiles. - * - * @category Inbox - * @group Hooks - * @experimental - * - * @param args - {@link EnhanceConversationsRequest} - */ -export function useEnhanceConversations( - useConversationsResult: ReturnType, - { profile }: EnhanceConversationsRequest, -): ReadResult { - const { conversations, error: resultError, isLoading: resultLoading } = useConversationsResult; - - const conversationToProfileIdMap: Record = useMemo(() => { - return conversations.reduce((acc, c) => { - const peerProfileId = extractPeerProfileId(c.context?.conversationId, profile.id); - - return { - ...acc, - [createUniqueConversationId(c)]: peerProfileId, - }; - }, {}); - }, [conversations, profile.id]); - - const uniqueProfileIds: ProfileId[] = useMemo(() => { - const ids = Object.values(conversationToProfileIdMap).filter(notEmpty); - return [...new Set(ids)]; - }, [conversationToProfileIdMap]); - - const skip = uniqueProfileIds.length === 0; - - const { - data: profiles = [], - error, - loading, - } = useProfiles( - skip - ? { - skip: true, - } - : { - profileIds: uniqueProfileIds, - }, - ); - - const enhancedConversations = useMemo((): EnhancedConversation[] => { - if (profiles.length > 0 && conversations.length > 0) { - const eConversations = conversations.map((c): EnhancedConversation => { - const id = createUniqueConversationId(c); - - const peerProfile = profiles.find((p) => p.id === conversationToProfileIdMap[id]); - - if (!peerProfile) { - return c; - } - - // Clone the xmtp Conversation instance with all its methods and add peerProfile - // eslint-disable-next-line - return Object.assign(Object.create(Object.getPrototypeOf(c)), c, { peerProfile }); - }); - - return eConversations; - } - return conversations; - }, [profiles, conversationToProfileIdMap, conversations]); - - if (skip) { - return { - data: conversations, - error: undefined, - loading: false, - }; - } - - if (loading || resultLoading) { - return { - data: undefined, - error: undefined, - loading: true, - }; - } - - if (resultError) { - assertError(resultError); - return { - data: undefined, - error: resultError, - loading: false, - }; - } - - if (error) { - return { - data: undefined, - error, - loading: false, - }; - } - - return { - data: enhancedConversations, - error: undefined, - loading: false, - }; -} diff --git a/packages/react-web-v1/src/inbox/useStartLensConversation.ts b/packages/react-web-v1/src/inbox/useStartLensConversation.ts deleted file mode 100644 index af904829e3..0000000000 --- a/packages/react-web-v1/src/inbox/useStartLensConversation.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Profile, ProfileOwnedByMe } from '@lens-protocol/react'; -import { useStartConversation } from '@xmtp/react-sdk'; - -import { buildConversationId } from './helpers'; - -/** - * @experimental - */ -export type StartLensConversationRequest = { - ownedProfile: ProfileOwnedByMe; - peerProfile: Profile; -}; - -/** - * @experimental - */ -export type UseStartLensConversationResult = ReturnType; - -/** - * Start a new XMTP conversation between two Lens profiles - * - * @category Inbox - * @group Hooks - * @experimental - * - * @param args - {@link StartLensConversationRequest} - */ -export function useStartLensConversation({ - ownedProfile, - peerProfile, -}: StartLensConversationRequest): UseStartLensConversationResult { - return useStartConversation({ - conversationId: buildConversationId(ownedProfile.id, peerProfile.id), - metadata: {}, - }); -} diff --git a/packages/react-web-v1/src/inbox/useXmtpClient.ts b/packages/react-web-v1/src/inbox/useXmtpClient.ts deleted file mode 100644 index e20bfbcef9..0000000000 --- a/packages/react-web-v1/src/inbox/useXmtpClient.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { - PendingSigningRequestError, - UserRejectedError, - WalletConnectionError, - useSharedDependencies, -} from '@lens-protocol/react'; -import { assertError } from '@lens-protocol/shared-kernel'; -import { IStorage } from '@lens-protocol/storage'; -import { Client, ClientOptions, useClient } from '@xmtp/react-sdk'; -import { useCallback, useState } from 'react'; - -import { SignerAdapter } from './adapters/SignerAdapter'; - -async function storeKeys(storage: IStorage, keys: Uint8Array) { - await storage.set(Uint8Array.from(keys).toString()); -} - -async function loadKeys(storage: IStorage): Promise { - const val = await storage.get(); - return val ? Uint8Array.from(val.split(',').map((c) => parseInt(c))) : null; -} - -/** - * @experimental - */ -export type InitXmtpClientOptions = Partial>; - -/** - * @experimental - */ -export type UseXmtpClientResult = { - client: Client | undefined; - disconnect: () => void; - error: PendingSigningRequestError | UserRejectedError | WalletConnectionError | Error | undefined; - initialize: (options?: InitXmtpClientOptions) => Promise; - isLoading: boolean; -}; - -const defaultOptions: InitXmtpClientOptions = { - persistConversations: true, -}; - -/** - * Initialize XMTP client using the same Signer as the one provided with {@link LensConfig}. - * Store XMTP user's decryption key in storage to improve UX. - * Be aware that XMTP user's key must be stored safely. - * - * @category Inbox - * @group Hooks - * @experimental - * - * @param args - {@link StartLensConversationRequest} - */ -export function useXmtpClient(): UseXmtpClientResult { - const { client, disconnect, isLoading: clientIsLoading, initialize } = useClient(); - const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(); - - const { activeWallet, inboxKeyStorage: storage } = useSharedDependencies(); - - const initializeWithLens = useCallback( - async (options: InitXmtpClientOptions = defaultOptions) => { - setIsLoading(true); - setError(undefined); - - try { - const existingKeys = await loadKeys(storage); - const signer = new SignerAdapter(activeWallet); - - if (existingKeys) { - const newClient = await initialize({ - keys: existingKeys, - signer, - options, - }); - - return newClient; - } - - const newClient = await initialize({ - signer, - options, - }); - - const newKeys = await Client.getKeys(signer); - await storeKeys(storage, newKeys); - - return newClient; - } catch (e) { - assertError(e); - setError(e); - - return undefined; - } finally { - setIsLoading(false); - } - }, - [activeWallet, initialize, storage], - ); - - return { - client, - disconnect, - isLoading: isLoading || clientIsLoading, - error, - initialize: initializeWithLens, - }; -} diff --git a/packages/react-web-v1/src/index.ts b/packages/react-web-v1/src/index.ts deleted file mode 100644 index ffe2d39703..0000000000 --- a/packages/react-web-v1/src/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { LensConfig, LensProvider, LensProviderProps } from './LensProvider'; -import { - UseCreateEncryptedCommentArgs, - useCreateEncryptedComment, -} from './useCreateEncryptedComment'; -import { UseCreateEncryptedPostArgs, useCreateEncryptedPost } from './useCreateEncryptedPost'; -import { UseEncryptedPublicationArgs, useEncryptedPublication } from './useEncryptedPublication'; - -export * from '@lens-protocol/react'; - -// NOTE: local exports takes priority over package exports, basically overriding the hooks with same names from @lens-protocol/react -// see https://github.com/systemjs/systemjs/issues/1031#issuecomment-171262430 -export { LensProvider, useCreateEncryptedPost, useCreateEncryptedComment, useEncryptedPublication }; -export type { - LensConfig, - LensProviderProps, - UseCreateEncryptedPostArgs, - UseCreateEncryptedCommentArgs, - UseEncryptedPublicationArgs, -}; - -// Shadows the types from @lens-protocol/react so that they cannot be used nor surfaced in reference docs for @lens-protocol/react-web -export type EncryptionConfig = never; -export type IStorageProvider = never; -export type IObservableStorageProvider = never; diff --git a/packages/react-web-v1/src/storage.ts b/packages/react-web-v1/src/storage.ts deleted file mode 100644 index 46469ac001..0000000000 --- a/packages/react-web-v1/src/storage.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { IObservableStorageProvider, StorageProviderSubscriber } from '@lens-protocol/storage'; - -import { window } from './globals'; - -class LocalStorageProvider implements IObservableStorageProvider { - private subscribers = new Map(); - - getItem(key: string) { - return window?.localStorage.getItem(key) ?? null; - } - - setItem(key: string, value: string) { - window?.localStorage.setItem(key, value); - } - - removeItem(key: string) { - window?.localStorage.removeItem(key); - } - - subscribe(key: string, subscriber: StorageProviderSubscriber) { - if (this.subscribers.has(key)) { - this.subscribers.get(key)?.push(subscriber); - } else { - this.subscribers.set(key, [subscriber]); - } - - if (this.subscribers.size === 1) { - this.listenToStorageEvent(); - } - - return { - unsubscribe: () => { - const subscribers = this.subscribers.get(key) ?? []; - - const index = subscribers.indexOf(subscriber); - - if (index > -1) { - subscribers.splice(index, 1); - } - - if (subscribers.length === 0) { - this.subscribers.delete(key); - } - - if (this.subscribers.size === 0) { - this.stopListeningToStorageEvent(); - } - }, - }; - } - - private onStorageEvent = (event: StorageEvent) => { - if (event.storageArea !== window?.localStorage) { - return; - } - - if (event.key && this.subscribers.has(event.key)) { - const subscribers = this.subscribers.get(event.key) ?? []; - subscribers.forEach((subscriber) => subscriber(event.newValue, event.oldValue)); - } - }; - - private listenToStorageEvent() { - window?.addEventListener('storage', this.onStorageEvent); - } - - private stopListeningToStorageEvent() { - window?.removeEventListener('storage', this.onStorageEvent); - } -} - -export function localStorage(): IObservableStorageProvider { - return new LocalStorageProvider(); -} diff --git a/packages/react-web-v1/src/useBrowserEncryptionConfig.ts b/packages/react-web-v1/src/useBrowserEncryptionConfig.ts deleted file mode 100644 index 00ec0987d8..0000000000 --- a/packages/react-web-v1/src/useBrowserEncryptionConfig.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { webCryptoProvider } from '@lens-protocol/gated-content/web'; -import { EncryptionConfig } from '@lens-protocol/react'; -import { useState } from 'react'; - -export function useBrowserEncryptionConfig(): EncryptionConfig { - const [encryption] = useState(() => ({ - authentication: { - domain: location.host, - uri: location.href, - }, - provider: webCryptoProvider(), - })); - - return encryption; -} diff --git a/packages/react-web-v1/src/useCreateEncryptedComment.ts b/packages/react-web-v1/src/useCreateEncryptedComment.ts deleted file mode 100644 index d2ff9770a3..0000000000 --- a/packages/react-web-v1/src/useCreateEncryptedComment.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { - useCreateEncryptedComment as useCreateEncryptedCommentBase, - ProfileOwnedByMe, - MetadataUploadHandler, -} from '@lens-protocol/react'; - -import { useBrowserEncryptionConfig } from './useBrowserEncryptionConfig'; - -export type UseCreateEncryptedCommentArgs = { - publisher: ProfileOwnedByMe; - upload: MetadataUploadHandler; -}; - -/** - * @category Publications - * @group Hooks - * @param args - {@link UseCreateEncryptedCommentArgs} - */ -export function useCreateEncryptedComment(args: UseCreateEncryptedCommentArgs) { - return useCreateEncryptedCommentBase({ - ...args, - encryption: useBrowserEncryptionConfig(), - }); -} diff --git a/packages/react-web-v1/src/useCreateEncryptedPost.ts b/packages/react-web-v1/src/useCreateEncryptedPost.ts deleted file mode 100644 index 592db983f5..0000000000 --- a/packages/react-web-v1/src/useCreateEncryptedPost.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { - MetadataUploadHandler, - ProfileOwnedByMe, - useCreateEncryptedPost as useCreateEncryptedPostBase, -} from '@lens-protocol/react'; - -import { useBrowserEncryptionConfig } from './useBrowserEncryptionConfig'; - -export type UseCreateEncryptedPostArgs = { - publisher: ProfileOwnedByMe; - upload: MetadataUploadHandler; -}; - -/** - * @category Publications - * @group Hooks - * @param args - {@link UseCreateEncryptedPostArgs} - */ -export function useCreateEncryptedPost(args: UseCreateEncryptedPostArgs) { - return useCreateEncryptedPostBase({ - ...args, - encryption: useBrowserEncryptionConfig(), - }); -} diff --git a/packages/react-web-v1/src/useEncryptedPublication.ts b/packages/react-web-v1/src/useEncryptedPublication.ts deleted file mode 100644 index 151d285713..0000000000 --- a/packages/react-web-v1/src/useEncryptedPublication.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { ContentPublication } from '@lens-protocol/api-bindings'; -import { useEncryptedPublication as useEncryptedPublicationBase } from '@lens-protocol/react'; - -import { useBrowserEncryptionConfig } from './useBrowserEncryptionConfig'; - -export type UseEncryptedPublicationArgs = { - publication: T; -}; - -/** - * @category Publications - * @group Hooks - */ -export function useEncryptedPublication( - args: UseEncryptedPublicationArgs, -) { - return useEncryptedPublicationBase({ - ...args, - encryption: useBrowserEncryptionConfig(), - }); -} diff --git a/packages/react-web-v1/tsconfig.json b/packages/react-web-v1/tsconfig.json deleted file mode 100644 index b71b6e132c..0000000000 --- a/packages/react-web-v1/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@lens-protocol/tsconfig/base.json", - "compilerOptions": { - "jsx": "react-jsx", - "lib": ["DOM", "ESNext"], - "outDir": "dist" - }, - "include": ["src", "./jest.config.ts"] -} diff --git a/packages/react-web-v1/tsdoc.json b/packages/react-web-v1/tsdoc.json deleted file mode 100644 index b89839ca22..0000000000 --- a/packages/react-web-v1/tsdoc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", - "extends": ["typedoc/tsdoc.json"] -} diff --git a/packages/react/src/authentication/adapters/AccessTokenStorage.ts b/packages/react/src/authentication/adapters/AccessTokenStorage.ts index 2e89629f7a..86e1ecfc29 100644 --- a/packages/react/src/authentication/adapters/AccessTokenStorage.ts +++ b/packages/react/src/authentication/adapters/AccessTokenStorage.ts @@ -3,9 +3,9 @@ import { CredentialsExpiredError } from '@lens-protocol/domain/use-cases/authent import { PromiseResult, failure, invariant, success } from '@lens-protocol/shared-kernel'; import { AuthApi } from './AuthApi'; -import { Credentials } from './Credentials'; import { Callback, ICredentialsExpiryEmitter } from './CredentialsExpiryController'; import { CredentialsStorage } from './CredentialsStorage'; +import { JwtCredentials } from './JwtCredentials'; export class AccessTokenStorage implements IAccessTokenStorage, ICredentialsExpiryEmitter { private isRefreshing = false; @@ -41,7 +41,7 @@ export class AccessTokenStorage implements IAccessTokenStorage, ICredentialsExpi return failure(new CredentialsExpiredError()); } - private async refreshCredentials(credentials: Credentials) { + private async refreshCredentials(credentials: JwtCredentials) { const newCredentials = await this.authApi.refreshCredentials(credentials.refreshToken); await this.credentialsStorage.set(newCredentials); } diff --git a/packages/react/src/authentication/adapters/AuthApi.ts b/packages/react/src/authentication/adapters/AuthApi.ts index 3286088d39..175c4b6211 100644 --- a/packages/react/src/authentication/adapters/AuthApi.ts +++ b/packages/react/src/authentication/adapters/AuthApi.ts @@ -1,19 +1,19 @@ import { - AuthAuthenticateDocument, AuthAuthenticateData, + AuthAuthenticateDocument, AuthAuthenticateVariables, - AuthChallengeDocument, AuthChallengeData, + AuthChallengeDocument, AuthChallengeVariables, - AuthRefreshDocument, AuthRefreshData, + AuthRefreshDocument, AuthRefreshVariables, - SafeApolloClient, ChallengeRequest, + SafeApolloClient, SignedAuthChallenge, } from '@lens-protocol/api-bindings'; -import { Credentials } from './Credentials'; +import { JwtCredentials } from './JwtCredentials'; export type AuthChallenge = { id: string; @@ -37,7 +37,7 @@ export class AuthApi { }; } - async generateCredentials(request: SignedAuthChallenge): Promise { + async generateCredentials(request: SignedAuthChallenge): Promise { const result = await this.apolloClient.mutate({ mutation: AuthAuthenticateDocument, variables: { request }, @@ -45,10 +45,10 @@ export class AuthApi { const { accessToken, refreshToken } = result.data.result; - return new Credentials(accessToken, refreshToken); + return new JwtCredentials(accessToken, refreshToken); } - async refreshCredentials(refreshToken: string): Promise { + async refreshCredentials(refreshToken: string): Promise { const result = await this.apolloClient.mutate({ mutation: AuthRefreshDocument, variables: { request: { refreshToken } }, @@ -56,6 +56,6 @@ export class AuthApi { const { accessToken: newAccessToken, refreshToken: newRefreshToken } = result.data.result; - return new Credentials(newAccessToken, newRefreshToken); + return new JwtCredentials(newAccessToken, newRefreshToken); } } diff --git a/packages/react/src/authentication/adapters/CredentialsFactory.ts b/packages/react/src/authentication/adapters/CredentialsFactory.ts index 431bc022e1..bd2184f80c 100644 --- a/packages/react/src/authentication/adapters/CredentialsFactory.ts +++ b/packages/react/src/authentication/adapters/CredentialsFactory.ts @@ -1,21 +1,21 @@ import { ProfileId, Wallet } from '@lens-protocol/domain/entities'; import { - ICredentialsIssuer, - LoginError, CredentialsExpiredError, + ICredentialsIssuer, ICredentialsRenewer, + LoginError, } from '@lens-protocol/domain/use-cases/authentication'; -import { failure, PromiseResult, success } from '@lens-protocol/shared-kernel'; +import { PromiseResult, failure, success } from '@lens-protocol/shared-kernel'; import { AuthApi } from './AuthApi'; -import { Credentials } from './Credentials'; +import { JwtCredentials } from './JwtCredentials'; export class CredentialsFactory implements ICredentialsIssuer, ICredentialsRenewer { constructor(private auth: AuthApi) {} async renewCredentials( - credentials: Credentials, - ): PromiseResult { + credentials: JwtCredentials, + ): PromiseResult { if (!credentials.canRefresh()) { return failure(new CredentialsExpiredError()); } @@ -30,7 +30,7 @@ export class CredentialsFactory implements ICredentialsIssuer, ICredentialsRenew async issueCredentials( signer: Wallet, using?: ProfileId, - ): PromiseResult { + ): PromiseResult { const challenge = await this.auth.generateChallenge({ for: using, signedBy: signer.address, diff --git a/packages/react/src/authentication/adapters/CredentialsGateway.ts b/packages/react/src/authentication/adapters/CredentialsGateway.ts index f79574c5b2..209237a9ef 100644 --- a/packages/react/src/authentication/adapters/CredentialsGateway.ts +++ b/packages/react/src/authentication/adapters/CredentialsGateway.ts @@ -5,15 +5,15 @@ import { SafeApolloClient, } from '@lens-protocol/api-bindings'; import { - ICredentialsWriter, ICredentialsReader, + ICredentialsWriter, IResettableCredentialsGateway, LogoutReason, } from '@lens-protocol/domain/use-cases/authentication'; import { never } from '@lens-protocol/shared-kernel'; import { IStorage } from '@lens-protocol/storage'; -import { Credentials } from './Credentials'; +import { JwtCredentials } from './JwtCredentials'; type RevokeSessionRequest = { authorizationId: string; @@ -23,7 +23,7 @@ export class CredentialsGateway implements ICredentialsWriter, ICredentialsReader, IResettableCredentialsGateway { constructor( - private readonly credentialsStorage: IStorage, + private readonly credentialsStorage: IStorage, private apolloClient: SafeApolloClient, ) {} @@ -31,7 +31,7 @@ export class CredentialsGateway return this.credentialsStorage.get(); } - async save(credentials: Credentials) { + async save(credentials: JwtCredentials) { await this.credentialsStorage.set(credentials); } diff --git a/packages/react/src/authentication/adapters/CredentialsStorage.ts b/packages/react/src/authentication/adapters/CredentialsStorage.ts index 49bc1d41e3..fb3eef67a9 100644 --- a/packages/react/src/authentication/adapters/CredentialsStorage.ts +++ b/packages/react/src/authentication/adapters/CredentialsStorage.ts @@ -1,21 +1,21 @@ import { + CredentialsStorageSchema, IStorage, IStorageProvider, + PersistedCredentials, Storage, StorageSubscriber, StorageSubscription, - CredentialsStorageSchema, - PersistedCredentials, } from '@lens-protocol/storage'; -import { Credentials } from './Credentials'; +import { JwtCredentials } from './JwtCredentials'; /** * Stores auth credentials. * Access token is kept in memory. * Refresh token is persisted permanently. */ -export class CredentialsStorage implements IStorage { +export class CredentialsStorage implements IStorage { refreshTokenStorage: IStorage; accessToken: string | null = null; @@ -24,13 +24,13 @@ export class CredentialsStorage implements IStorage { this.refreshTokenStorage = Storage.createForSchema(authStorageSchema, storageProvider); } - async set({ accessToken, refreshToken }: Credentials): Promise { + async set({ accessToken, refreshToken }: JwtCredentials): Promise { this.accessToken = accessToken; await this.refreshTokenStorage.set({ refreshToken }); } - async get(): Promise { + async get(): Promise { const refreshToken = await this.getRefreshToken(); if (!refreshToken) { @@ -39,7 +39,7 @@ export class CredentialsStorage implements IStorage { const accessToken = this.getAccessToken(); - return new Credentials(accessToken, refreshToken); + return new JwtCredentials(accessToken, refreshToken); } async reset(): Promise { @@ -47,7 +47,7 @@ export class CredentialsStorage implements IStorage { await this.refreshTokenStorage.reset(); } - subscribe(_: StorageSubscriber): StorageSubscription { + subscribe(_: StorageSubscriber): StorageSubscription { throw new Error('Method not implemented.'); } diff --git a/packages/react/src/authentication/adapters/CredentialsUpgrader.ts b/packages/react/src/authentication/adapters/CredentialsUpgrader.ts index 57baca0878..604d255678 100644 --- a/packages/react/src/authentication/adapters/CredentialsUpgrader.ts +++ b/packages/react/src/authentication/adapters/CredentialsUpgrader.ts @@ -7,12 +7,12 @@ import { import { ProfileId } from '@lens-protocol/domain/entities'; import { ICredentialsUpgrader } from '@lens-protocol/domain/use-cases/authentication'; -import { Credentials } from './Credentials'; +import { JwtCredentials } from './JwtCredentials'; export class CredentialsUpgrader implements ICredentialsUpgrader { constructor(private apolloClient: SafeApolloClient) {} - async upgradeCredentials(profileId: ProfileId): Promise { + async upgradeCredentials(profileId: ProfileId): Promise { const result = await this.apolloClient.mutate< WalletAuthenticationToProfileAuthenticationData, WalletAuthenticationToProfileAuthenticationVariables @@ -27,6 +27,6 @@ export class CredentialsUpgrader implements ICredentialsUpgrader { const { accessToken, refreshToken } = result.data.result; - return new Credentials(accessToken, refreshToken); + return new JwtCredentials(accessToken, refreshToken); } } diff --git a/packages/react/src/authentication/adapters/Credentials.ts b/packages/react/src/authentication/adapters/JwtCredentials.ts similarity index 84% rename from packages/react/src/authentication/adapters/Credentials.ts rename to packages/react/src/authentication/adapters/JwtCredentials.ts index 8cf065fb13..19e5383816 100644 --- a/packages/react/src/authentication/adapters/Credentials.ts +++ b/packages/react/src/authentication/adapters/JwtCredentials.ts @@ -1,4 +1,4 @@ -import { ICredentials, ProfileId } from '@lens-protocol/domain/entities'; +import { Credentials, ProfileId } from '@lens-protocol/domain/entities'; import { DateUtils, EvmAddress, invariant, never } from '@lens-protocol/shared-kernel'; import jwtDecode from 'jwt-decode'; import isObject from 'lodash/isObject'; @@ -32,7 +32,7 @@ function isProfileJwtContent(decodedJwt: unknown): decodedJwt is ProfileJwtPaylo // Adds some time for all communications that's required to refresh tokens const TOKEN_EXP_THRESHOLD = DateUtils.secondsToMs(3); -export class Credentials implements ICredentials { +export class JwtCredentials implements Credentials { readonly address: EvmAddress; readonly profileId?: ProfileId; readonly authorizationId: string; @@ -63,19 +63,6 @@ export class Credentials implements ICredentials { return now < tokenExpDate - TOKEN_EXP_THRESHOLD; } - isExpired(): boolean { - const accessToken = this.accessToken; - - if (!accessToken) { - return true; - } - - const now = Date.now(); - const tokenExpDate = this.getTokenExpDate(accessToken); - - return now >= tokenExpDate - TOKEN_EXP_THRESHOLD; - } - private getTokenExpDate(token: string) { const decodedToken = jwtDecode(token); diff --git a/packages/react/src/authentication/adapters/__helpers__/mocks.ts b/packages/react/src/authentication/adapters/__helpers__/mocks.ts index 531757dc6b..bdf1394eee 100644 --- a/packages/react/src/authentication/adapters/__helpers__/mocks.ts +++ b/packages/react/src/authentication/adapters/__helpers__/mocks.ts @@ -1,7 +1,7 @@ -import { Credentials } from '../Credentials'; +import { JwtCredentials } from '../JwtCredentials'; -export function mockCredentials(): Credentials { - return new Credentials( +export function mockJwtCredentials(): JwtCredentials { + return new JwtCredentials( 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjB4NTYiLCJldm1BZGRyZXNzIjoiMHgzZkM0N2NkRGNGZDU5ZGNlMjA2OTRiNTc1QUZjMUQ5NDE4Njc3NWIwIiwicm9sZSI6InByb2ZpbGUiLCJhdXRob3JpemF0aW9uSWQiOiIwNDVjNjdiNi1iMzUxLTQ1YzktYTVhNS1jNGFkOTg4OWQ2MmMiLCJpYXQiOjE3MDEzNTMwOTYsImV4cCI6MTcwMTM1NDg5Nn0.O_pQ386uVIU_Pi1aex8K4E9rWxkqXcTELE1HTaD4gwI', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjB4NTYiLCJldm1BZGRyZXNzIjoiMHgzZkM0N2NkRGNGZDU5ZGNlMjA2OTRiNTc1QUZjMUQ5NDE4Njc3NWIwIiwicm9sZSI6InByb2ZpbGVfcmVmcmVzaCIsImF1dGhvcml6YXRpb25JZCI6IjA0NWM2N2I2LWIzNTEtNDVjOS1hNWE1LWM0YWQ5ODg5ZDYyYyIsImlhdCI6MTcwMTM1MzA5NiwiZXhwIjoxNzAxOTU3ODk2fQ.i2kzT4I6VBTuZvjly0TEdGN_YsuBaTDopMQU4_398kA', ); diff --git a/packages/react/src/authentication/adapters/__tests__/CredentialsFactory.spec.ts b/packages/react/src/authentication/adapters/__tests__/CredentialsFactory.spec.ts index 48b9883f0a..2e957950ae 100644 --- a/packages/react/src/authentication/adapters/__tests__/CredentialsFactory.spec.ts +++ b/packages/react/src/authentication/adapters/__tests__/CredentialsFactory.spec.ts @@ -13,14 +13,14 @@ import { when } from 'jest-when'; import { AuthApi, AuthChallenge } from '../AuthApi'; import { CredentialsFactory } from '../CredentialsFactory'; -import { mockCredentials } from '../__helpers__/mocks'; +import { mockJwtCredentials } from '../__helpers__/mocks'; const challenge: AuthChallenge = { id: faker.datatype.uuid(), text: 'Challenge to sign from backend', }; const signature = mockSignature(); -const credentials = mockCredentials(); +const credentials = mockJwtCredentials(); function setupTestScenario() { const wallet = mockWallet(); @@ -87,7 +87,7 @@ describe(`Given an instance of the ${CredentialsFactory.name} class`, () => { jest.useFakeTimers({ now: new Date(0), }); - const newCredentials = mockCredentials(); + const newCredentials = mockJwtCredentials(); const { credentialsFactory, authApi } = setupTestScenario(); when(authApi.refreshCredentials) diff --git a/packages/react/src/authentication/adapters/__tests__/CredentialsGateway.spec.ts b/packages/react/src/authentication/adapters/__tests__/CredentialsGateway.spec.ts index 91c92e04ba..2e597bc3df 100644 --- a/packages/react/src/authentication/adapters/__tests__/CredentialsGateway.spec.ts +++ b/packages/react/src/authentication/adapters/__tests__/CredentialsGateway.spec.ts @@ -5,14 +5,14 @@ import { import { mockStorage } from '@lens-protocol/storage/mocks'; import { LogoutReason } from '../../useSession'; -import { Credentials } from '../Credentials'; import { CredentialsGateway } from '../CredentialsGateway'; -import { mockCredentials } from '../__helpers__/mocks'; +import { JwtCredentials } from '../JwtCredentials'; +import { mockJwtCredentials } from '../__helpers__/mocks'; -const credentials = mockCredentials(); +const credentials = mockJwtCredentials(); const setupGateway = () => { - const storage = mockStorage(); + const storage = mockStorage(); const authorizationId = credentials.authorizationId; const apolloClient = mockLensApolloClient([ mockRevokeAuthenticationResponse({ diff --git a/packages/react/src/authentication/adapters/useLoginController.ts b/packages/react/src/authentication/adapters/useLoginController.ts index 04f590ff2b..d2d3e4631e 100644 --- a/packages/react/src/authentication/adapters/useLoginController.ts +++ b/packages/react/src/authentication/adapters/useLoginController.ts @@ -4,23 +4,12 @@ import { useSharedDependencies } from '../../shared'; import { LoginPresenter } from './LoginPresenter'; export function useLoginController() { - const { - credentialsFactory, - credentialsGateway, - profileCacheManager, - walletFactory, - walletGateway, - } = useSharedDependencies(); + const { credentialsFactory, credentialsGateway, profileCacheManager, walletGateway } = + useSharedDependencies(); return async (request: LoginRequest) => { const presenter = new LoginPresenter(profileCacheManager); - const login = new Login( - walletFactory, - walletGateway, - credentialsFactory, - credentialsGateway, - presenter, - ); + const login = new Login(walletGateway, credentialsFactory, credentialsGateway, presenter); await login.execute(request); diff --git a/packages/react/src/shared.tsx b/packages/react/src/shared.tsx index 2bcc234026..9927726472 100644 --- a/packages/react/src/shared.tsx +++ b/packages/react/src/shared.tsx @@ -49,11 +49,9 @@ import { createTransactionStorage } from './transactions/infrastructure/Transact import { BalanceGateway } from './wallet/adapters/BalanceGateway'; import { IProviderFactory } from './wallet/adapters/IProviderFactory'; import { TokenGateway } from './wallet/adapters/TokenGateway'; -import { WalletFactory } from './wallet/adapters/WalletFactory'; import { WalletGateway } from './wallet/adapters/WalletGateway'; import { ProviderFactory } from './wallet/infrastructure/ProviderFactory'; import { SignerFactory } from './wallet/infrastructure/SignerFactory'; -import { createWalletStorage } from './wallet/infrastructure/WalletStorage'; /** * @internal @@ -76,7 +74,6 @@ export function createSharedDependencies(userConfig: LensConfig): SharedDependen // storages const credentialsStorage = new CredentialsStorage(config.storage, config.environment.name); const accessTokenStorage = new AccessTokenStorage(authApi, credentialsStorage); - const walletStorage = createWalletStorage(config.storage, config.environment.name); const transactionStorage = createTransactionStorage(config.storage, config.environment.name); const inboxKeyStorage = createInboxKeyStorage(config.storage, config.environment.name); @@ -104,8 +101,7 @@ export function createSharedDependencies(userConfig: LensConfig): SharedDependen const credentialsGateway = new CredentialsGateway(credentialsStorage, apolloClient); const profileCacheManager = new ProfileCacheManager(apolloClient); const publicationCacheManager = new PublicationCacheManager(apolloClient); - const walletFactory = new WalletFactory(signerFactory, transactionFactory); - const walletGateway = new WalletGateway(walletStorage, walletFactory); + const walletGateway = new WalletGateway(signerFactory, transactionFactory); const transactionGateway = new PendingTransactionGateway(transactionStorage, transactionFactory); const onChainRelayer = new OnChainRelayer(apolloClient, transactionFactory, config.logger); const momokaRelayer = new MomokaRelayer(apolloClient, transactionFactory, config.logger); @@ -152,7 +148,6 @@ export function createSharedDependencies(userConfig: LensConfig): SharedDependen // logout const logoutPresenter = new LogoutPresenter(); const logout = new Logout( - walletGateway, credentialsGateway, transactionGateway, conversationsGateway, @@ -181,7 +176,6 @@ export function createSharedDependencies(userConfig: LensConfig): SharedDependen transactionFactory, transactionGateway, transactionQueue, - walletFactory, walletGateway, }; } @@ -207,7 +201,6 @@ export type SharedDependencies = { transactionFactory: ITransactionFactory; transactionGateway: PendingTransactionGateway; transactionQueue: TransactionQueue; - walletFactory: WalletFactory; walletGateway: WalletGateway; }; diff --git a/packages/react/src/transactions/adapters/useCreateProfileController.ts b/packages/react/src/transactions/adapters/useCreateProfileController.ts index 1a99e270c4..6730ae3885 100644 --- a/packages/react/src/transactions/adapters/useCreateProfileController.ts +++ b/packages/react/src/transactions/adapters/useCreateProfileController.ts @@ -20,7 +20,7 @@ export function useCreateProfileController() { profileCacheManager, providerFactory, transactionQueue, - walletFactory, + walletGateway, } = useSharedDependencies(); return async ( @@ -39,7 +39,7 @@ export function useCreateProfileController() { config.environment.handleResolver, ); - const createProfile = new CreateProfile(walletFactory, gateway, presenter, transactionQueue); + const createProfile = new CreateProfile(walletGateway, gateway, presenter, transactionQueue); await createProfile.execute(request); diff --git a/packages/react/src/wallet/adapters/WalletFactory.ts b/packages/react/src/wallet/adapters/WalletFactory.ts deleted file mode 100644 index cb9e36ada5..0000000000 --- a/packages/react/src/wallet/adapters/WalletFactory.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; -import { IWalletFactory } from '@lens-protocol/domain/use-cases/wallets'; -import { EvmAddress } from '@lens-protocol/shared-kernel'; - -import { ITransactionFactory } from '../../transactions/adapters/ITransactionFactory'; -import { ConcreteWallet, ISignerFactory, WalletDataSchema } from './ConcreteWallet'; -import { IWalletUnmarshaller } from './WalletGateway'; - -export class WalletFactory implements IWalletUnmarshaller, IWalletFactory { - constructor( - private readonly signerFactory: ISignerFactory, - private readonly transactionFactory: ITransactionFactory, - ) {} - - async create(address: EvmAddress): Promise { - return ConcreteWallet.create(address, this.signerFactory, this.transactionFactory); - } - - rehydrate(data: WalletDataSchema) { - return ConcreteWallet.create(data.address, this.signerFactory, this.transactionFactory); - } -} diff --git a/packages/react/src/wallet/adapters/WalletGateway.ts b/packages/react/src/wallet/adapters/WalletGateway.ts index 865ed90157..cae6bfbe54 100644 --- a/packages/react/src/wallet/adapters/WalletGateway.ts +++ b/packages/react/src/wallet/adapters/WalletGateway.ts @@ -1,62 +1,34 @@ -import { - IReadableWalletGateway, - IWritableWalletGateway, - IResettableWalletGateway, -} from '@lens-protocol/domain/use-cases/authentication'; +import { AnyTransactionRequest } from '@lens-protocol/domain/use-cases/transactions'; +import { IWalletGateway } from '@lens-protocol/domain/use-cases/wallets'; import { EvmAddress, never } from '@lens-protocol/shared-kernel'; -import { IStorage } from '@lens-protocol/storage'; import { z } from 'zod'; -import { ConcreteWallet, WalletDataSchema } from './ConcreteWallet'; - -export interface IWalletUnmarshaller { - rehydrate(data: WalletDataSchema): ConcreteWallet; -} +import { ITransactionFactory } from '../../transactions/adapters/ITransactionFactory'; +import { ConcreteWallet, ISignerFactory, WalletDataSchema } from './ConcreteWallet'; export const WalletStorageSchema = z.array(WalletDataSchema); export type WalletStorageSchema = z.infer; -export class WalletGateway - implements IReadableWalletGateway, IResettableWalletGateway, IWritableWalletGateway -{ +export class WalletGateway implements IWalletGateway { private inMemoryCache: Record = {}; constructor( - private readonly storage: IStorage, - private readonly factory: IWalletUnmarshaller, + private readonly signerFactory: ISignerFactory, + private readonly transactionFactory: ITransactionFactory, ) {} - async getByAddress(address: EvmAddress): Promise { - if (this.inMemoryCache[address]) { - return this.inMemoryCache[address] ?? never(); - } - const wallets = await this.getAll(); - const wallet = wallets.find((w) => w.address.toLowerCase() === address.toLowerCase()) ?? null; + async getByAddress(address: EvmAddress): Promise { + const key = address.toLowerCase(); - if (wallet) { - this.inMemoryCache[address] = wallet; + if (this.inMemoryCache[key]) { + return this.inMemoryCache[key] ?? never(); } - return wallet; - } - async reset(): Promise { - await this.storage.reset(); - } + const wallet = ConcreteWallet.create(address, this.signerFactory, this.transactionFactory); - async save(wallet: ConcreteWallet): Promise { - const wallets = await this.getAll(); + this.inMemoryCache[key] = wallet; - this.inMemoryCache[wallet.address] = wallet; - await this.storage.set(wallets.concat([wallet]).map((w) => w.toWalletData())); - } - - private async getAll(): Promise { - const data = await this.storage.get(); - - if (data === null) { - return []; - } - return data.map((d) => this.factory.rehydrate(d)); + return wallet; } } diff --git a/packages/react/src/wallet/adapters/__helpers__/mocks.ts b/packages/react/src/wallet/adapters/__helpers__/mocks.ts index 699175d5bc..47155f7d10 100644 --- a/packages/react/src/wallet/adapters/__helpers__/mocks.ts +++ b/packages/react/src/wallet/adapters/__helpers__/mocks.ts @@ -1,4 +1,4 @@ -import { TransactionRequest, JsonRpcProvider, JsonRpcSigner } from '@ethersproject/providers'; +import { JsonRpcProvider, JsonRpcSigner, TransactionRequest } from '@ethersproject/providers'; import { faker } from '@faker-js/faker'; import { TypedData } from '@lens-protocol/blockchain-bindings'; import { @@ -18,10 +18,8 @@ import { mockEvmAddress } from '@lens-protocol/shared-kernel/mocks'; import { mock } from 'jest-mock-extended'; import { when } from 'jest-when'; -import { ITransactionFactory } from '../../../transactions/adapters/ITransactionFactory'; import { mockTypedData } from '../../../transactions/adapters/__helpers__/mocks'; import { - ConcreteWallet, ISignerFactory, ITransactionRequest, SignedProtocolCall, @@ -30,14 +28,6 @@ import { } from '../ConcreteWallet'; import { IProviderFactory } from '../IProviderFactory'; -export function mockConcreteWallet() { - return ConcreteWallet.create( - mockEvmAddress(), - mock(), - mock>(), - ); -} - class ErrorWithCode extends Error { name = 'ErrorWithCode' as const; diff --git a/packages/react/src/wallet/adapters/__tests__/WalletGateway.spec.ts b/packages/react/src/wallet/adapters/__tests__/WalletGateway.spec.ts index 7805354e70..f7a11eeb11 100644 --- a/packages/react/src/wallet/adapters/__tests__/WalletGateway.spec.ts +++ b/packages/react/src/wallet/adapters/__tests__/WalletGateway.spec.ts @@ -1,85 +1,46 @@ import { Wallet } from '@lens-protocol/domain/entities'; -import { IStorage } from '@lens-protocol/storage'; -import { mockStorage } from '@lens-protocol/storage/mocks'; +import { mockEvmAddress } from '@lens-protocol/shared-kernel/mocks'; import { mock } from 'jest-mock-extended'; import { mockITransactionFactory } from '../../../transactions/adapters/__helpers__/mocks'; import { ISignerFactory } from '../ConcreteWallet'; -import { WalletFactory } from '../WalletFactory'; -import { WalletGateway, WalletStorageSchema } from '../WalletGateway'; -import { mockConcreteWallet } from '../__helpers__/mocks'; +import { WalletGateway } from '../WalletGateway'; -function setupWalletGateway({ storage }: { storage: IStorage }) { +function setupWalletGateway() { const signerFactory = mock(); const transactionFactory = mockITransactionFactory(); - const walletFactory = new WalletFactory(signerFactory, transactionFactory); - return new WalletGateway(storage, walletFactory); + return new WalletGateway(signerFactory, transactionFactory); } +const address = mockEvmAddress(); + describe(`Given an instance of the ${WalletGateway.name}`, () => { describe(`when "${WalletGateway.prototype.getByAddress.name}" method is invoked`, () => { it(`should retrieve the ${Wallet.name} instance by address`, async () => { - const wallet1 = mockConcreteWallet(); - const wallet2 = mockConcreteWallet(); - const storage = mockStorage([wallet1, wallet2]); - - const gateway = setupWalletGateway({ storage }); + const gateway = setupWalletGateway(); - const actual = await gateway.getByAddress(wallet2.address); + const wallet = await gateway.getByAddress(address); - expect(actual).toBeInstanceOf(Wallet); - expect(actual?.address).toEqual(wallet2.address); + expect(wallet).toBeInstanceOf(Wallet); + expect(wallet.address).toEqual(address); }); it(`should cache the ${Wallet.name} instance in an in-memory cache for subsequent calls`, async () => { - const wallet1 = mockConcreteWallet(); - const wallet2 = mockConcreteWallet(); - const storage = mockStorage([wallet1, wallet2]); - - const gateway = setupWalletGateway({ storage }); - - expect(await gateway.getByAddress(wallet2.address)).toBe( - await gateway.getByAddress(wallet2.address), - ); - }); - - it(`should retrieve the ${Wallet.name} instance even if address is in a different format`, async () => { - const wallet1 = mockConcreteWallet(); - const storage = mockStorage([wallet1]); + const gateway = setupWalletGateway(); - const gateway = setupWalletGateway({ storage }); + const wallet1 = await gateway.getByAddress(address); + const wallet2 = await gateway.getByAddress(address); - const retrievedWallet = await gateway.getByAddress(wallet1.address.toUpperCase()); - - expect(retrievedWallet?.address).toEqual(wallet1.address); + expect(wallet1).toBe(wallet2); }); - }); - - describe(`when "${WalletGateway.prototype.reset.name}" method is invoked`, () => { - it(`should remove all the ${Wallet.name} entities from the underlying storage provider`, async () => { - const wallet1 = mockConcreteWallet(); - const wallet2 = mockConcreteWallet(); - const storage = mockStorage([wallet1, wallet2]); - - const gateway = setupWalletGateway({ storage }); - - await gateway.reset(); - - expect(await gateway.getByAddress(wallet1.address)).toBeNull(); - expect(await gateway.getByAddress(wallet2.address)).toBeNull(); - }); - }); - - describe(`when "${WalletGateway.prototype.save.name}" method is invoked`, () => { - it(`should cache the ${Wallet.name} instance in an in-memory cache to support subsequent reads`, async () => { - const newWallet = mockConcreteWallet(); - const storage = mockStorage([]); - const gateway = setupWalletGateway({ storage }); + it(`should retrieve the ${Wallet.name} instance by address in a case-insensitive manner`, async () => { + const gateway = setupWalletGateway(); - await gateway.save(newWallet); + const wallet1 = await gateway.getByAddress(address); + const wallet2 = await gateway.getByAddress(address.toUpperCase()); - expect(await gateway.getByAddress(newWallet.address)).toBe(newWallet); + expect(wallet1).toBe(wallet2); }); }); }); diff --git a/packages/react/src/wallet/infrastructure/WalletStorage.ts b/packages/react/src/wallet/infrastructure/WalletStorage.ts deleted file mode 100644 index f6eccc75ea..0000000000 --- a/packages/react/src/wallet/infrastructure/WalletStorage.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BaseStorageSchema, IStorageProvider, Storage } from '@lens-protocol/storage'; - -import { WalletStorageSchema } from '../adapters/WalletGateway'; - -export function createWalletStorage(storageProvider: IStorageProvider, namespace: string) { - const walletStorageDataSchema = new BaseStorageSchema( - `lens.${namespace}.wallets`, - WalletStorageSchema, - ); - return Storage.createForSchema(walletStorageDataSchema, storageProvider); -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d3f8479cec..4795ac9a7d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -334,103 +334,6 @@ importers: specifier: 5.2.2 version: 5.2.2 - packages/api-bindings-v1: - dependencies: - '@apollo/client': - specifier: ^3.8.7 - version: 3.8.10(graphql@16.8.1)(react-dom@18.2.0)(react@18.2.0) - '@lens-protocol/domain': - specifier: workspace:* - version: link:../domain - '@lens-protocol/shared-kernel': - specifier: workspace:* - version: link:../shared-kernel - graphql: - specifier: ^16.8.1 - version: 16.8.1 - graphql-tag: - specifier: ^2.12.6 - version: 2.12.6(graphql@16.8.1) - tslib: - specifier: ^2.6.2 - version: 2.6.2 - devDependencies: - '@babel/core': - specifier: ^7.23.3 - version: 7.23.3 - '@babel/preset-env': - specifier: ^7.23.3 - version: 7.23.3(@babel/core@7.23.3) - '@babel/preset-typescript': - specifier: ^7.23.3 - version: 7.23.3(@babel/core@7.23.3) - '@faker-js/faker': - specifier: ^7.6.0 - version: 7.6.0 - '@graphql-codegen/add': - specifier: ^4.0.1 - version: 4.0.1(graphql@16.8.1) - '@graphql-codegen/cli': - specifier: ^3.3.1 - version: 3.3.1(@babel/core@7.23.3)(@types/node@18.18.12)(graphql@16.8.1) - '@graphql-codegen/fragment-matcher': - specifier: ^4.0.1 - version: 4.0.1(graphql@16.8.1) - '@graphql-codegen/introspection': - specifier: ^3.0.1 - version: 3.0.1(graphql@16.8.1) - '@graphql-codegen/typescript': - specifier: ^3.0.4 - version: 3.0.4(graphql@16.8.1) - '@graphql-codegen/typescript-apollo-client-helpers': - specifier: ^2.2.6 - version: 2.2.6(graphql@16.8.1) - '@graphql-codegen/typescript-operations': - specifier: ^3.0.4 - version: 3.0.4(graphql@16.8.1) - '@graphql-codegen/typescript-react-apollo': - specifier: ^3.3.7 - version: 3.3.7(graphql-tag@2.12.6)(graphql@16.8.1) - '@lens-protocol/eslint-config': - specifier: workspace:* - version: link:../eslint-config - '@lens-protocol/prettier-config': - specifier: workspace:* - version: link:../prettier-config - '@lens-protocol/tsconfig': - specifier: workspace:* - version: link:../tsconfig - '@types/jest': - specifier: ^29.5.10 - version: 29.5.10 - '@types/node': - specifier: ^18.18.12 - version: 18.18.12 - babel-plugin-graphql-tag: - specifier: ^3.3.0 - version: 3.3.0(@babel/core@7.23.3)(graphql-tag@2.12.6) - eslint: - specifier: ^8.54.0 - version: 8.54.0 - jest: - specifier: ^29.7.0 - version: 29.7.0(@types/node@18.18.12) - jest-mock-extended: - specifier: ^3.0.5 - version: 3.0.5(jest@29.7.0)(typescript@5.2.2) - react: - specifier: ^18.2.0 - version: 18.2.0 - react-dom: - specifier: ^18.2.0 - version: 18.2.0(react@18.2.0) - ts-jest: - specifier: ^29.1.1 - version: 29.1.1(@babel/core@7.23.3)(jest@29.7.0)(typescript@5.2.2) - typescript: - specifier: 5.2.2 - version: 5.2.2 - packages/blockchain-bindings: dependencies: '@ethersproject/abi': @@ -1119,8 +1022,6 @@ importers: specifier: 5.2.2 version: 5.2.2 - packages/react-v1: {} - packages/react-web: dependencies: '@lens-protocol/api-bindings': @@ -1215,8 +1116,6 @@ importers: specifier: 5.2.2 version: 5.2.2 - packages/react-web-v1: {} - packages/shared-kernel: dependencies: '@ethersproject/address': From 66c6df157437b3744dbfca7dd0c47c205c0da3ad Mon Sep 17 00:00:00 2001 From: Cesare Naldi Date: Mon, 12 Feb 2024 19:35:20 +0000 Subject: [PATCH 06/13] fix: makes useAccessToken reactive and fix token on-the-fly token refresh (#840) * fix: makes useAccesToken reactive and fix token on-the-fly token refresh * Fix linting issue --- .changeset/metal-bikes-applaud.md | 8 +++ .../src/apollo/__helpers__/mocks.ts | 20 +------ packages/api-bindings/src/apollo/errors.ts | 23 +++++++- .../api-bindings/src/apollo/links/AuthLink.ts | 48 +++++++++------ .../apollo/links/__tests__/AuthLink.spec.ts | 58 +++++++++++-------- .../adapters/AccessTokenStorage.ts | 54 ++++++++++++----- .../react/src/experimental/useAccessToken.ts | 11 +++- packages/shared-kernel/src/index.ts | 19 +++--- 8 files changed, 152 insertions(+), 89 deletions(-) create mode 100644 .changeset/metal-bikes-applaud.md diff --git a/.changeset/metal-bikes-applaud.md b/.changeset/metal-bikes-applaud.md new file mode 100644 index 0000000000..83899997c0 --- /dev/null +++ b/.changeset/metal-bikes-applaud.md @@ -0,0 +1,8 @@ +--- +"@lens-protocol/api-bindings": patch +"@lens-protocol/react-native": patch +"@lens-protocol/react-web": patch +"@lens-protocol/react": patch +--- + +**fixed:** make `useAccessToken` reactive diff --git a/packages/api-bindings/src/apollo/__helpers__/mocks.ts b/packages/api-bindings/src/apollo/__helpers__/mocks.ts index 2022702a30..2504e5482d 100644 --- a/packages/api-bindings/src/apollo/__helpers__/mocks.ts +++ b/packages/api-bindings/src/apollo/__helpers__/mocks.ts @@ -1,4 +1,4 @@ -import { GraphQLRequest, NormalizedCacheObject, OperationVariables } from '@apollo/client'; +import { NormalizedCacheObject } from '@apollo/client'; import { MockedResponse, mockSingleLink } from '@apollo/client/testing'; import { DocumentNode, ExecutionResult, GraphQLError } from 'graphql'; @@ -34,24 +34,6 @@ export function mockSnapshotApolloClient( }); } -function createUnauthenticatedApolloError(): GraphQLError { - return createGraphQLError({ - message: 'Authentication required', - code: ApolloServerErrorCode.UNAUTHENTICATED, - }); -} - -export function mockAuthenticationErrorResponse( - request: GraphQLRequest, -): MockedResponse { - return { - request, - result: { - errors: [createUnauthenticatedApolloError()], - }, - }; -} - function createGraphQLError({ code, message = 'No pings please!', diff --git a/packages/api-bindings/src/apollo/errors.ts b/packages/api-bindings/src/apollo/errors.ts index 42672cfa8f..a31ff22cea 100644 --- a/packages/api-bindings/src/apollo/errors.ts +++ b/packages/api-bindings/src/apollo/errors.ts @@ -1,5 +1,5 @@ -import { ApolloError, FetchResult } from '@apollo/client'; -import { CausedError } from '@lens-protocol/shared-kernel'; +import { ApolloError, FetchResult, ServerError } from '@apollo/client'; +import { CausedError, isObject } from '@lens-protocol/shared-kernel'; /** * @internal @@ -44,6 +44,25 @@ export function graphQLResultHasUnauthenticatedError(result: FetchResult) ); } +/** + * @internal + */ +export function isServerError(error: unknown): error is ServerError { + return ( + isObject(error) && + error instanceof Error && + error.name === 'ServerError' && + `statusCode` in error + ); +} + +/** + * @internal + */ +export function isUnauthorizedServerError(error: unknown): error is ServerError { + return isServerError(error) && error.statusCode === 401; +} + /** * An unexpected error, usually from an API response. * diff --git a/packages/api-bindings/src/apollo/links/AuthLink.ts b/packages/api-bindings/src/apollo/links/AuthLink.ts index 9c902635d3..550064a743 100644 --- a/packages/api-bindings/src/apollo/links/AuthLink.ts +++ b/packages/api-bindings/src/apollo/links/AuthLink.ts @@ -4,7 +4,7 @@ import { Observable, Observer } from '@apollo/client/utilities'; import { CredentialsExpiredError } from '@lens-protocol/domain/use-cases/authentication'; import { invariant, PromiseResult } from '@lens-protocol/shared-kernel'; -import { graphQLResultHasUnauthenticatedError } from '../errors'; +import { isUnauthorizedServerError } from '../errors'; export interface IAccessTokenStorage { getAccessToken(): string | null; @@ -28,11 +28,17 @@ class RequestsQueue { this.requests.delete(operation); } - consume() { + retryAll() { for (const request of this.requests.values()) { request.forward(request.operation).subscribe(request.observer); } } + + failWith(result: FetchResult) { + for (const request of this.requests.values()) { + request.observer.next?.(result); + } + } } class RefreshTokensLink extends ApolloLink { @@ -67,25 +73,29 @@ class RefreshTokensLink extends ApolloLink { return; } - if (graphQLResultHasUnauthenticatedError(result)) { - if (!this.refreshing) { - this.refreshing = true; - const refresh = await this.accessTokenStorage.refreshToken(); - this.refreshing = false; - - if (refresh.isFailure()) { - observer.next(result); - } else { - forward(operation).subscribe(observer); - } - this.queue.consume(); + observer.next(result); + }, + error: async (error) => { + if (isUnauthorizedServerError(error)) { + this.queue.enqueue({ operation, forward, observer }); + + if (this.refreshing) { + return; + } + + this.refreshing = true; + const refresh = await this.accessTokenStorage.refreshToken(); + this.refreshing = false; + + if (refresh.isSuccess()) { + this.queue.retryAll(); + return; } + + this.queue.failWith(error.result as FetchResult); + return; } - - observer.next(result); - }, - error: (error) => { observer.error(error); }, complete: () => { @@ -115,8 +125,8 @@ export function createAuthLink(accessTokenStorage: IAccessTokenStorage) { ...prevContext, // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment headers: { - authorization: `Bearer ${token}`, ...('headers' in prevContext && prevContext.headers), + authorization: `Bearer ${token}`, }, }; } diff --git a/packages/api-bindings/src/apollo/links/__tests__/AuthLink.spec.ts b/packages/api-bindings/src/apollo/links/__tests__/AuthLink.spec.ts index 73d88dddc3..c6e4ae52f5 100644 --- a/packages/api-bindings/src/apollo/links/__tests__/AuthLink.spec.ts +++ b/packages/api-bindings/src/apollo/links/__tests__/AuthLink.spec.ts @@ -1,10 +1,17 @@ -import { ApolloClient, ApolloError, from, gql, InMemoryCache } from '@apollo/client'; -import { MockedResponse, mockSingleLink } from '@apollo/client/testing'; +import { + ApolloClient, + ApolloError, + // eslint-disable-next-line no-restricted-imports + createHttpLink, + from, + gql, + InMemoryCache, +} from '@apollo/client'; import { CredentialsExpiredError } from '@lens-protocol/domain/use-cases/authentication'; import { failure, success } from '@lens-protocol/shared-kernel'; import { mock } from 'jest-mock-extended'; -import { mockAuthenticationErrorResponse } from '../../__helpers__/mocks'; +import { createHttpJsonResponse, createUnauthenticatedHttpResponse } from '../../__helpers__/mocks'; import { ApolloServerErrorCode } from '../../errors'; import { createAuthLink, IAccessTokenStorage } from '../AuthLink'; @@ -13,12 +20,10 @@ const query = gql` loopback(value: $value) } `; -type LoopbackData = { loopback: number }; -type LoopbackVariables = { value: number }; const accessTokenStorage = mock(); -function mockLoopbackResponse(): MockedResponse { +function mockLoopbackResponse() { const value = Math.random() * 100; return { request: { @@ -33,13 +38,20 @@ function mockLoopbackResponse(): MockedResponse }; } -function setupTestScenario(mocks: ReadonlyArray>) { +function setupTestScenario(mocks: ReadonlyArray) { + const fetch = jest.fn(); + + mocks.forEach((mock) => { + fetch.mockResolvedValueOnce(mock); + }); + return new ApolloClient({ cache: new InMemoryCache(), link: from([ createAuthLink(accessTokenStorage), - mockSingleLink(...mocks).setOnError((error) => { - throw error; + createHttpLink({ + fetch, + uri: 'http://localhost:4000/graphql', }), ]), }); @@ -60,8 +72,8 @@ describe(`Given an instance of the ${ApolloClient.name}`, () => { it(`should refresh the access token and retry the request`, async () => { const client = setupTestScenario([ - mockAuthenticationErrorResponse(mockedResponse.request), - mockedResponse, + createUnauthenticatedHttpResponse(), + createHttpJsonResponse(200, mockedResponse.result), ]); const result = await client.query(mockedResponse.request); @@ -73,10 +85,10 @@ describe(`Given an instance of the ${ApolloClient.name}`, () => { it('should queue any request while refreshing and retry them after the refresh', async () => { const queuedResponse = mockLoopbackResponse(); const client = setupTestScenario([ - mockAuthenticationErrorResponse(mockedResponse.request), - mockAuthenticationErrorResponse(queuedResponse.request), - mockedResponse, - queuedResponse, + createUnauthenticatedHttpResponse(), + createUnauthenticatedHttpResponse(), + createHttpJsonResponse(200, mockedResponse.result), + createHttpJsonResponse(200, queuedResponse.result), ]); const [firstResult, secondResult] = await Promise.all([ @@ -89,7 +101,7 @@ describe(`Given an instance of the ${ApolloClient.name}`, () => { }); it('should propagate the error in case the retry fails', async () => { - const mockedFailedResponse = mockAuthenticationErrorResponse(mockedResponse.request); + const mockedFailedResponse = createUnauthenticatedHttpResponse(); const client = setupTestScenario([mockedFailedResponse, mockedFailedResponse]); await expect(client.query(mockedResponse.request)).rejects.toThrowError(ApolloError); @@ -105,9 +117,7 @@ describe(`Given an instance of the ${ApolloClient.name}`, () => { }); it(`should forward the original error result`, async () => { - const client = setupTestScenario([ - mockAuthenticationErrorResponse(mockedResponse.request), - ]); + const client = setupTestScenario([createUnauthenticatedHttpResponse()]); await expect(client.query(mockedResponse.request)).rejects.toThrowError(ApolloError); }); @@ -115,16 +125,16 @@ describe(`Given an instance of the ${ApolloClient.name}`, () => { it(`should let any queued request continue (and possibly fail)`, async () => { const queuedResponse = mockLoopbackResponse(); const client = setupTestScenario([ - mockAuthenticationErrorResponse(mockedResponse.request), - mockAuthenticationErrorResponse(queuedResponse.request), - mockAuthenticationErrorResponse(queuedResponse.request), + createUnauthenticatedHttpResponse(), + createUnauthenticatedHttpResponse(), + createUnauthenticatedHttpResponse(), ]); const firstPromise = client.query(mockedResponse.request); const secondPromise = client.query(queuedResponse.request); - await expect(firstPromise).rejects.toThrowError('Authentication required'); - await expect(secondPromise).rejects.toThrowError('Authentication required'); + await expect(firstPromise).rejects.toThrow('Authentication required'); + await expect(secondPromise).rejects.toThrow('Authentication required'); }); }); }); diff --git a/packages/react/src/authentication/adapters/AccessTokenStorage.ts b/packages/react/src/authentication/adapters/AccessTokenStorage.ts index 86e1ecfc29..d1e3161cd3 100644 --- a/packages/react/src/authentication/adapters/AccessTokenStorage.ts +++ b/packages/react/src/authentication/adapters/AccessTokenStorage.ts @@ -5,21 +5,28 @@ import { PromiseResult, failure, invariant, success } from '@lens-protocol/share import { AuthApi } from './AuthApi'; import { Callback, ICredentialsExpiryEmitter } from './CredentialsExpiryController'; import { CredentialsStorage } from './CredentialsStorage'; -import { JwtCredentials } from './JwtCredentials'; + +export type Unsubscribe = () => void; export class AccessTokenStorage implements IAccessTokenStorage, ICredentialsExpiryEmitter { private isRefreshing = false; - private listeners: Set = new Set(); + private expiryListeners: Set = new Set(); + private refreshListeners: Set = new Set(); constructor( private readonly authApi: AuthApi, private readonly credentialsStorage: CredentialsStorage, ) {} - onExpiry(callback: Callback) { - this.listeners.add(callback); - return () => this.listeners.delete(callback); + onExpiry(callback: Callback): Unsubscribe { + this.expiryListeners.add(callback); + return () => this.expiryListeners.delete(callback); + } + + onRefresh(callback: Callback): Unsubscribe { + this.refreshListeners.add(callback); + return () => this.refreshListeners.delete(callback); } getAccessToken(): string | null { @@ -29,24 +36,39 @@ export class AccessTokenStorage implements IAccessTokenStorage, ICredentialsExpi async refreshToken(): PromiseResult { invariant(this.isRefreshing === false, 'Cannot refresh token while refreshing'); this.isRefreshing = true; + + const result = await this.refreshCredentials(); + + this.isRefreshing = false; + + if (result.isSuccess()) { + this.emitRefreshEvent(); + } else { + this.emitExpiryEvent(); + } + return result; + } + + private async refreshCredentials(): PromiseResult { const credentials = await this.credentialsStorage.get(); - if (credentials && credentials.canRefresh()) { - await this.refreshCredentials(credentials); - this.isRefreshing = false; + if (!credentials || !credentials.canRefresh()) { + return failure(new CredentialsExpiredError()); + } + try { + const newCredentials = await this.authApi.refreshCredentials(credentials.refreshToken); + await this.credentialsStorage.set(newCredentials); return success(); + } catch { + return failure(new CredentialsExpiredError()); } - this.isRefreshing = false; - this.emitExpiryEvent(); - return failure(new CredentialsExpiredError()); } - private async refreshCredentials(credentials: JwtCredentials) { - const newCredentials = await this.authApi.refreshCredentials(credentials.refreshToken); - await this.credentialsStorage.set(newCredentials); + private emitExpiryEvent() { + this.expiryListeners.forEach((callback) => callback()); } - private emitExpiryEvent() { - this.listeners.forEach((callback) => callback()); + private emitRefreshEvent() { + this.refreshListeners.forEach((callback) => callback()); } } diff --git a/packages/react/src/experimental/useAccessToken.ts b/packages/react/src/experimental/useAccessToken.ts index 911ae06641..fa7d155f49 100644 --- a/packages/react/src/experimental/useAccessToken.ts +++ b/packages/react/src/experimental/useAccessToken.ts @@ -1,3 +1,5 @@ +import { useEffect, useState } from 'react'; + import { useSharedDependencies } from '../shared'; /** @@ -8,6 +10,13 @@ import { useSharedDependencies } from '../shared'; */ export function useAccessToken() { const { accessTokenStorage } = useSharedDependencies(); + const [token, setToken] = useState(() => accessTokenStorage.getAccessToken()); + + useEffect(() => { + return accessTokenStorage.onRefresh(() => { + setToken(accessTokenStorage.getAccessToken()); + }); + }, [accessTokenStorage]); - return accessTokenStorage.getAccessToken(); + return token; } diff --git a/packages/shared-kernel/src/index.ts b/packages/shared-kernel/src/index.ts index e30465922a..98bd8734ca 100644 --- a/packages/shared-kernel/src/index.ts +++ b/packages/shared-kernel/src/index.ts @@ -1,21 +1,24 @@ -export * from './array'; -export * from './arithmetic/BigDecimal'; +import isObject from 'lodash/isObject'; +export { isObject }; + export * from './CausedError'; +export * from './DateUtils'; +export * from './Deferred'; +export * from './Result'; +export * from './arithmetic/BigDecimal'; +export * from './array'; export * from './crypto/Amount'; export * from './crypto/Asset'; export * from './crypto/ChainType'; export * from './crypto/types'; -export * from './DateUtils'; export * from './get'; export * from './logger/ILogger'; -export * from './Result'; -export * from './Deferred'; +export * from './maybe'; +export * from './omitDeep'; export * from './ts-helpers/assertError'; export * from './ts-helpers/assertNever'; export * from './ts-helpers/invariant'; +export * from './ts-helpers/isInEnum'; export * from './ts-helpers/never'; export * from './ts-helpers/nonNullable'; export * from './ts-helpers/types'; -export * from './ts-helpers/isInEnum'; -export * from './omitDeep'; -export * from './maybe'; From 8279f5b14bf1b000490d107404f59cc198bff013 Mon Sep 17 00:00:00 2001 From: Cesare Naldi Date: Mon, 12 Feb 2024 19:46:05 +0000 Subject: [PATCH 07/13] feat: Wagmi v2 support (#835) * feat: Wagmi v2 support * Amends NextJS example * Address review comment * Fix linting issues --- .changeset/fifty-singers-dance.md | 5 + examples/next-js/package.json | 5 +- examples/next-js/src/app/layout.tsx | 3 +- examples/next-js/src/components/Providers.tsx | 32 + examples/next-js/src/components/providers.tsx | 40 - examples/node/package.json | 1 - examples/web/package.json | 5 +- examples/web/src/App.tsx | 255 ++-- examples/web/src/LogInPage.tsx | 12 +- examples/web/src/Providers.tsx | 30 + .../auth/RequireConnectedWallet.tsx | 8 +- .../cards.tsx} | 30 +- .../src/discovery/UseExplorePublications.tsx | 4 +- examples/web/src/discovery/UseFeed.tsx | 2 +- .../web/src/discovery/UseFeedHighlights.tsx | 2 +- .../src/discovery/UseSearchPublications.tsx | 4 +- examples/web/src/hooks/useIrysUploader.ts | 60 + examples/web/src/misc/UseApproveModule.tsx | 15 +- .../src/profiles/UseSetProfileMetadata.tsx | 5 +- .../src/profiles/UseUpdateProfileManagers.tsx | 2 +- .../src/publications/UseBookmarkToggle.tsx | 2 +- .../web/src/publications/UseBookmarks.tsx | 2 +- .../web/src/publications/UseCreateComment.tsx | 127 +- .../web/src/publications/UseCreateMirror.tsx | 2 +- .../web/src/publications/UseCreatePost.tsx | 7 +- .../web/src/publications/UseCreateQuote.tsx | 94 +- .../src/publications/UseHidePublication.tsx | 2 +- .../src/publications/UseLazyPublications.tsx | 2 +- .../publications/UseNotInterestedToggle.tsx | 2 +- .../web/src/publications/UseOpenAction.tsx | 7 +- .../web/src/publications/UsePublication.tsx | 2 +- .../web/src/publications/UsePublications.tsx | 2 +- .../src/publications/UseReactionToggle.tsx | 2 +- .../src/publications/UseReportPublication.tsx | 2 +- .../components/PublicationRevenueCard.tsx | 2 +- examples/web/src/upload.ts | 85 -- packages/domain/src/entities/Wallet.ts | 5 +- .../transactions/useUpdateProfileManagers.ts | 19 +- packages/wagmi/package.json | 10 +- packages/wagmi/src/index.ts | 55 +- pnpm-lock.yaml | 1277 +++++++++++++---- 41 files changed, 1460 insertions(+), 768 deletions(-) create mode 100644 .changeset/fifty-singers-dance.md create mode 100644 examples/next-js/src/components/Providers.tsx delete mode 100644 examples/next-js/src/components/providers.tsx create mode 100644 examples/web/src/Providers.tsx rename examples/web/src/{publications/components/PublicationCard.tsx => components/cards.tsx} (76%) create mode 100644 examples/web/src/hooks/useIrysUploader.ts delete mode 100644 examples/web/src/upload.ts diff --git a/.changeset/fifty-singers-dance.md b/.changeset/fifty-singers-dance.md new file mode 100644 index 0000000000..778c88bae0 --- /dev/null +++ b/.changeset/fifty-singers-dance.md @@ -0,0 +1,5 @@ +--- +"@lens-protocol/wagmi": major +--- + +**feat:** Wagmi v2 support diff --git a/examples/next-js/package.json b/examples/next-js/package.json index 41c948c2f1..c503806da8 100644 --- a/examples/next-js/package.json +++ b/examples/next-js/package.json @@ -11,11 +11,12 @@ "dependencies": { "@lens-protocol/react-web": "workspace:*", "@lens-protocol/wagmi": "workspace:*", + "@tanstack/react-query": "^5.18.1", "next": "^14.0.3", "react": "^18.2.0", "react-dom": "^18.2.0", - "viem": "^1.19.7", - "wagmi": "^1.4.12" + "viem": "^2.7.6", + "wagmi": "^2.5.6" }, "devDependencies": { "@types/node": "^18.18.12", diff --git a/examples/next-js/src/app/layout.tsx b/examples/next-js/src/app/layout.tsx index 5514042da3..677612158c 100644 --- a/examples/next-js/src/app/layout.tsx +++ b/examples/next-js/src/app/layout.tsx @@ -1,7 +1,8 @@ import type { Metadata } from "next"; import { Inter } from "next/font/google"; + +import { Providers } from "../components/Providers"; import "./globals.css"; -import { Providers } from "../components/providers"; const inter = Inter({ subsets: ["latin"] }); diff --git a/examples/next-js/src/components/Providers.tsx b/examples/next-js/src/components/Providers.tsx new file mode 100644 index 0000000000..1483ad6d1f --- /dev/null +++ b/examples/next-js/src/components/Providers.tsx @@ -0,0 +1,32 @@ +"use client"; + +import { LensConfig, LensProvider, development } from "@lens-protocol/react-web"; +import { bindings } from "@lens-protocol/wagmi"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { WagmiProvider, createConfig, http } from "wagmi"; +import { polygon, polygonMumbai } from "wagmi/chains"; + +const queryClient = new QueryClient(); + +const wagmiConfig = createConfig({ + chains: [polygonMumbai, polygon], + transports: { + [polygonMumbai.id]: http(), + [polygon.id]: http(), + }, +}); + +const lensConfig: LensConfig = { + environment: development, + bindings: bindings(wagmiConfig), +}; + +export function Providers({ children }: { children: React.ReactNode }) { + return ( + + + {children} + + + ); +} diff --git a/examples/next-js/src/components/providers.tsx b/examples/next-js/src/components/providers.tsx deleted file mode 100644 index ffcc9af4f7..0000000000 --- a/examples/next-js/src/components/providers.tsx +++ /dev/null @@ -1,40 +0,0 @@ -"use client"; - -import { LensConfig, LensProvider, development } from "@lens-protocol/react-web"; -import { WagmiConfig, configureChains, createConfig } from "wagmi"; -import { bindings as wagmiBindings } from "@lens-protocol/wagmi"; -import { polygonMumbai } from "wagmi/chains"; -import { InjectedConnector } from "wagmi/connectors/injected"; -import { publicProvider } from "wagmi/providers/public"; -import { ReactNode } from "react"; - -const { publicClient, webSocketPublicClient } = configureChains( - [polygonMumbai], - [publicProvider()] -); - -const config = createConfig({ - autoConnect: true, - publicClient, - webSocketPublicClient, - connectors: [ - new InjectedConnector({ - options: { - shimDisconnect: false, - }, - }), - ], -}); - -const lensConfig: LensConfig = { - environment: development, - bindings: wagmiBindings(), -}; - -export function Providers({ children }: { children: ReactNode }) { - return ( - - {children} - - ); -} diff --git a/examples/node/package.json b/examples/node/package.json index f7d63739f3..a75924574e 100644 --- a/examples/node/package.json +++ b/examples/node/package.json @@ -26,7 +26,6 @@ "ethers": "^5.7.2", "typechain": "^8.3.2", "uuid": "^9.0.1", - "viem": "^1.19.7", "zod": "^3.22.4" }, "devDependencies": { diff --git a/examples/web/package.json b/examples/web/package.json index 78ee25dbb2..b1924b6724 100644 --- a/examples/web/package.json +++ b/examples/web/package.json @@ -22,6 +22,7 @@ "@lens-protocol/metadata": "^1.0.5", "@lens-protocol/react-web": "workspace:*", "@lens-protocol/wagmi": "workspace:*", + "@tanstack/react-query": "^5.18.1", "@xmtp/react-sdk": "^3.0.0", "example-shared": "workspace:*", "react": "^18.2.0", @@ -30,8 +31,8 @@ "react-hot-toast": "^2.4.1", "react-router-dom": "^6.20.0", "readable-web-to-node-stream": "^3.0.2", - "viem": "^1.19.7", - "wagmi": "^1.4.12" + "viem": "^2.7.6", + "wagmi": "^2.5.6" }, "devDependencies": { "@babel/core": "^7.23.3", diff --git a/examples/web/src/App.tsx b/examples/web/src/App.tsx index d627311ccd..d485167f2b 100644 --- a/examples/web/src/App.tsx +++ b/examples/web/src/App.tsx @@ -1,16 +1,11 @@ -import { LensConfig, LensProvider, development } from '@lens-protocol/react-web'; -import { bindings as wagmiBindings } from '@lens-protocol/wagmi'; import { XMTPProvider } from '@xmtp/react-sdk'; import { Toaster } from 'react-hot-toast'; import { Outlet, Route, BrowserRouter as Router, Routes } from 'react-router-dom'; -import { WagmiConfig, configureChains, createConfig } from 'wagmi'; -import { polygonMumbai } from 'wagmi/chains'; -import { InjectedConnector } from 'wagmi/connectors/injected'; -import { publicProvider } from 'wagmi/providers/public'; import { HomePage } from './HomePage'; import { Layout } from './Layout'; import { LogInPage } from './LogInPage'; +import { Providers } from './Providers'; import { GenericErrorBoundary } from './components/GenericErrorBoundary'; import { ErrorMessage } from './components/error/ErrorMessage'; import { Header } from './components/header/Header'; @@ -67,8 +62,8 @@ import { } from './profiles'; import { PublicationsPage, - UseBookmarkToggle, UseBookmarks, + UseBookmarkToggle, UseCreateComment, UseCreateMirror, UseCreatePost, @@ -90,153 +85,125 @@ import { UseRevenueFromPublications, } from './revenue'; -const { publicClient, webSocketPublicClient } = configureChains( - [polygonMumbai], - [publicProvider()], -); - -const config = createConfig({ - autoConnect: true, - publicClient, - webSocketPublicClient, - connectors: [ - new InjectedConnector({ - options: { - shimDisconnect: false, - }, - }), - ], -}); - -const lensConfig: LensConfig = { - environment: development, - bindings: wagmiBindings(), -}; - export function App() { return ( - - - -
-
- - - } /> - } /> + + +
+
+ + + } /> + } /> - }> - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } - /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - + }> + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } + /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + - - } /> - } /> - } - /> - } - /> - + + } /> + } /> + } /> + } + /> + - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } - /> - + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } + /> + + + + + } + > + } /> + } /> - - - } - > - } /> - } /> - } - /> - } /> - + path="useEnhanceConversation/:conversationId" + element={} + /> + } /> + - Not found

} /> -
-
- -
- - - + Not found

} /> + + + +
+ + ); } diff --git a/examples/web/src/LogInPage.tsx b/examples/web/src/LogInPage.tsx index 5bbc4ee6ab..1b0020203b 100644 --- a/examples/web/src/LogInPage.tsx +++ b/examples/web/src/LogInPage.tsx @@ -1,7 +1,6 @@ -import { toast } from 'react-hot-toast'; import { useNavigate } from 'react-router-dom'; import { useAccount, useConnect } from 'wagmi'; -import { InjectedConnector } from 'wagmi/connectors/injected'; +import { injected } from 'wagmi/connectors'; import { LoginForm } from './components/auth'; @@ -9,17 +8,12 @@ export function LogInPage() { const navigate = useNavigate(); const { address, isConnecting, isDisconnected } = useAccount(); - const { connect } = useConnect({ - connector: new InjectedConnector(), - onError: (error) => { - toast.error(error.message); - }, - }); + const { connect } = useConnect(); return (
{isDisconnected && ( - )} diff --git a/examples/web/src/Providers.tsx b/examples/web/src/Providers.tsx new file mode 100644 index 0000000000..1a71273dda --- /dev/null +++ b/examples/web/src/Providers.tsx @@ -0,0 +1,30 @@ +import { LensConfig, LensProvider, development } from '@lens-protocol/react-web'; +import { bindings } from '@lens-protocol/wagmi'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { WagmiProvider, createConfig, http } from 'wagmi'; +import { polygon, polygonMumbai } from 'wagmi/chains'; + +const queryClient = new QueryClient(); + +const wagmiConfig = createConfig({ + chains: [polygonMumbai, polygon], + transports: { + [polygonMumbai.id]: http(), + [polygon.id]: http(), + }, +}); + +const lensConfig: LensConfig = { + environment: development, + bindings: bindings(wagmiConfig), +}; + +export function Providers({ children }: { children: React.ReactNode }) { + return ( + + + {children} + + + ); +} diff --git a/examples/web/src/components/auth/RequireConnectedWallet.tsx b/examples/web/src/components/auth/RequireConnectedWallet.tsx index d5d80a4ee1..9de8c8ee27 100644 --- a/examples/web/src/components/auth/RequireConnectedWallet.tsx +++ b/examples/web/src/components/auth/RequireConnectedWallet.tsx @@ -1,6 +1,6 @@ import { ReactNode } from 'react'; import { useAccount, useConnect } from 'wagmi'; -import { InjectedConnector } from 'wagmi/connectors/injected'; +import { injected } from 'wagmi/connectors'; type RenderFunction = (address: string) => ReactNode; @@ -12,9 +12,7 @@ export type RequireConnectedWalletProps = { export function RequireConnectedWallet({ children, message }: RequireConnectedWalletProps) { const { address, isConnected, isConnecting } = useAccount(); - const { connect } = useConnect({ - connector: new InjectedConnector(), - }); + const { connect } = useConnect(); if (isConnected && address) { if (typeof children === 'function') { @@ -26,7 +24,7 @@ export function RequireConnectedWallet({ children, message }: RequireConnectedWa return (
{message &&

{message}

} -
diff --git a/examples/web/src/publications/components/PublicationCard.tsx b/examples/web/src/components/cards.tsx similarity index 76% rename from examples/web/src/publications/components/PublicationCard.tsx rename to examples/web/src/components/cards.tsx index 5ded726670..acbdfacb3d 100644 --- a/examples/web/src/publications/components/PublicationCard.tsx +++ b/examples/web/src/components/cards.tsx @@ -4,10 +4,11 @@ import { Post, PublicationMetadata, PublicationStats, + Quote, } from '@lens-protocol/react-web'; import { ReactNode } from 'react'; -import { ProfilePicture } from '../../profiles/components/ProfilePicture'; +import { ProfilePicture } from '../profiles/components/ProfilePicture'; function MetadataSwitch({ metadata }: { metadata: PublicationMetadata }) { switch (metadata.__typename) { @@ -47,7 +48,7 @@ function PublicationTickers({ stats }: { stats: PublicationStats }) { ); } -function PublicationBody({ publication }: { publication: Post | Comment }) { +function PublicationBody({ publication }: { publication: Post | Comment | Quote }) { return (
@@ -61,6 +62,7 @@ function PublicationSwitch({ publication }: { publication: AnyPublication }) { switch (publication.__typename) { case 'Post': case 'Comment': + case 'Quote': return ; default: return null; @@ -96,3 +98,27 @@ export function PublicationCard({ publication, children }: PublicationCardProps) ); } + +type CommentCardProps = { + comment: Comment; + children?: ReactNode; +}; + +export function CommentCard({ comment }: CommentCardProps) { + return ( +
+
+ +

{comment.by.metadata?.displayName ?? comment.by.handle?.fullHandle ?? comment.by.id}

+
+ +
+ ); +} diff --git a/examples/web/src/discovery/UseExplorePublications.tsx b/examples/web/src/discovery/UseExplorePublications.tsx index cd406001c4..b749f564dd 100644 --- a/examples/web/src/discovery/UseExplorePublications.tsx +++ b/examples/web/src/discovery/UseExplorePublications.tsx @@ -1,9 +1,9 @@ -import { useExplorePublications, ExplorePublicationsOrderByType } from '@lens-protocol/react-web'; +import { ExplorePublicationsOrderByType, useExplorePublications } from '@lens-protocol/react-web'; +import { PublicationCard } from '../components/cards'; import { ErrorMessage } from '../components/error/ErrorMessage'; import { Loading } from '../components/loading/Loading'; import { useInfiniteScroll } from '../hooks/useInfiniteScroll'; -import { PublicationCard } from '../publications/components/PublicationCard'; export function UseExplorePublications() { const { diff --git a/examples/web/src/discovery/UseFeed.tsx b/examples/web/src/discovery/UseFeed.tsx index 1ea99dcc03..8157c10b3b 100644 --- a/examples/web/src/discovery/UseFeed.tsx +++ b/examples/web/src/discovery/UseFeed.tsx @@ -1,10 +1,10 @@ import { ProfileId, useFeed } from '@lens-protocol/react-web'; import { RequireProfileSession } from '../components/auth'; +import { PublicationCard } from '../components/cards'; import { ErrorMessage } from '../components/error/ErrorMessage'; import { Loading } from '../components/loading/Loading'; import { useInfiniteScroll } from '../hooks/useInfiniteScroll'; -import { PublicationCard } from '../publications/components/PublicationCard'; function UseFeedInner({ profileId }: { profileId: ProfileId }) { const { data, error, loading, hasMore, beforeCount, observeRef, prev } = useInfiniteScroll( diff --git a/examples/web/src/discovery/UseFeedHighlights.tsx b/examples/web/src/discovery/UseFeedHighlights.tsx index 851c29c16e..bef4dbed1d 100644 --- a/examples/web/src/discovery/UseFeedHighlights.tsx +++ b/examples/web/src/discovery/UseFeedHighlights.tsx @@ -1,10 +1,10 @@ import { ProfileId, useFeedHighlights } from '@lens-protocol/react-web'; import { RequireProfileSession } from '../components/auth'; +import { PublicationCard } from '../components/cards'; import { ErrorMessage } from '../components/error/ErrorMessage'; import { Loading } from '../components/loading/Loading'; import { useInfiniteScroll } from '../hooks/useInfiniteScroll'; -import { PublicationCard } from '../publications/components/PublicationCard'; function UseFeedHighlightsInner({ profileId }: { profileId: ProfileId }) { const { data, error, loading, hasMore, beforeCount, observeRef, prev } = useInfiniteScroll( diff --git a/examples/web/src/discovery/UseSearchPublications.tsx b/examples/web/src/discovery/UseSearchPublications.tsx index 05a38c8ddf..8161ad37fe 100644 --- a/examples/web/src/discovery/UseSearchPublications.tsx +++ b/examples/web/src/discovery/UseSearchPublications.tsx @@ -1,10 +1,10 @@ -import { useSearchPublications, LimitType } from '@lens-protocol/react-web'; +import { LimitType, useSearchPublications } from '@lens-protocol/react-web'; import { ChangeEvent, useState } from 'react'; +import { PublicationCard } from '../components/cards'; import { ErrorMessage } from '../components/error/ErrorMessage'; import { Loading } from '../components/loading/Loading'; import { useInfiniteScroll } from '../hooks/useInfiniteScroll'; -import { PublicationCard } from '../publications/components/PublicationCard'; type SearchResultsProps = { query: string; diff --git a/examples/web/src/hooks/useIrysUploader.ts b/examples/web/src/hooks/useIrysUploader.ts new file mode 100644 index 0000000000..afaa765156 --- /dev/null +++ b/examples/web/src/hooks/useIrysUploader.ts @@ -0,0 +1,60 @@ +import { Web3Provider } from '@ethersproject/providers'; +import { WebIrys } from '@irys/sdk'; +import { Account, Chain, Client, Transport } from 'viem'; +import { useConnectorClient } from 'wagmi'; + +import { never } from '../utils'; + +const TOP_UP = '200000000000000000'; // 0.2 MATIC +const MIN_FUNDS = 0.05; + +async function getWebIrys(client: Client) { + const webIrys = new WebIrys({ + url: 'https://devnet.irys.xyz', + token: 'matic', + wallet: { + rpcUrl: 'https://rpc-mumbai.maticvigil.com/', + name: 'ethersv5', + provider: new Web3Provider(client.transport), + }, + }); + + await webIrys.ready(); + + const balance = await webIrys.getBalance(client.account.address); + + if (webIrys.utils.fromAtomic(balance).toNumber() < MIN_FUNDS) { + await webIrys.fund(TOP_UP); + } + + return webIrys; +} + +export function useIrysUploader() { + const { data: client } = useConnectorClient(); + + return { + uploadMetadata: async (data: unknown) => { + const confirm = window.confirm( + `In this example we will now upload metadata file via the Bundlr Network. + + Please make sure your wallet is connected to the Polygon Mumbai testnet. + + You can get some Mumbai MATIC from the Mumbai Faucet: https://mumbaifaucet.com/`, + ); + + if (!confirm) { + throw new Error('User cancelled'); + } + + const irys = await getWebIrys(client ?? never('viem Client not found')); + + const serialized = JSON.stringify(data); + const tx = await irys.upload(serialized, { + tags: [{ name: 'Content-Type', value: 'application/json' }], + }); + + return `https://arweave.net/${tx.id}`; + }, + }; +} diff --git a/examples/web/src/misc/UseApproveModule.tsx b/examples/web/src/misc/UseApproveModule.tsx index 309f987469..533686d77e 100644 --- a/examples/web/src/misc/UseApproveModule.tsx +++ b/examples/web/src/misc/UseApproveModule.tsx @@ -1,26 +1,26 @@ import { textOnly } from '@lens-protocol/metadata'; import { Amount, + InsufficientAllowanceError, + OpenActionKind, OpenActionType, + PublicationId, + useApproveModule, useCreatePost, useCurrencies, - useApproveModule, useOpenAction, - OpenActionKind, - InsufficientAllowanceError, usePublication, - PublicationId, } from '@lens-protocol/react-web'; import { useState } from 'react'; import { toast } from 'react-hot-toast'; import { useAccount } from 'wagmi'; import { Logs } from '../components/Logs'; +import { PublicationCard } from '../components/cards'; import { ErrorMessage } from '../components/error/ErrorMessage'; import { Loading } from '../components/loading/Loading'; +import { useIrysUploader } from '../hooks/useIrysUploader'; import { useLogs } from '../hooks/useLogs'; -import { PublicationCard } from '../publications/components/PublicationCard'; -import { uploadJson } from '../upload'; import { never } from '../utils'; function TestScenario({ publicationId }: { publicationId: PublicationId }) { @@ -86,6 +86,7 @@ function TestScenario({ publicationId }: { publicationId: PublicationId }) { } export function UseApproveModule() { + const { uploadMetadata } = useIrysUploader(); const [id, setId] = useState(); const { address } = useAccount(); const { data: currencies, loading, error } = useCurrencies(); @@ -109,7 +110,7 @@ export function UseApproveModule() { }); log('Uploading metadata...'); - const uri = await uploadJson(metadata); + const uri = await uploadMetadata(metadata); log('Creating collectable test post...'); const result = await post({ diff --git a/examples/web/src/profiles/UseSetProfileMetadata.tsx b/examples/web/src/profiles/UseSetProfileMetadata.tsx index 4f55380b25..c7ba0edfaf 100644 --- a/examples/web/src/profiles/UseSetProfileMetadata.tsx +++ b/examples/web/src/profiles/UseSetProfileMetadata.tsx @@ -3,7 +3,7 @@ import { Profile, useSetProfileMetadata } from '@lens-protocol/react-web'; import { toast } from 'react-hot-toast'; import { RequireProfileSession } from '../components/auth'; -import { uploadJson } from '../upload'; +import { useIrysUploader } from '../hooks/useIrysUploader'; import { ProfileCard } from './components/ProfileCard'; type UpdateProfileFormProps = { @@ -11,6 +11,7 @@ type UpdateProfileFormProps = { }; function UpdateProfileForm({ activeProfile }: UpdateProfileFormProps) { + const { uploadMetadata } = useIrysUploader(); const { execute: update, error, loading } = useSetProfileMetadata(); async function onSubmit(event: React.FormEvent) { @@ -40,7 +41,7 @@ function UpdateProfileForm({ activeProfile }: UpdateProfileFormProps) { ], }); - const metadataURI = await uploadJson(metadata); + const metadataURI = await uploadMetadata(metadata); const result = await update({ metadataURI, diff --git a/examples/web/src/profiles/UseUpdateProfileManagers.tsx b/examples/web/src/profiles/UseUpdateProfileManagers.tsx index 7b8f03dd20..de864c80f9 100644 --- a/examples/web/src/profiles/UseUpdateProfileManagers.tsx +++ b/examples/web/src/profiles/UseUpdateProfileManagers.tsx @@ -1,4 +1,4 @@ -import { Profile, useUpdateProfileManagers, useProfileManagers } from '@lens-protocol/react-web'; +import { Profile, useProfileManagers, useUpdateProfileManagers } from '@lens-protocol/react-web'; import { RequireProfileSession } from '../components/auth'; import { ErrorMessage } from '../components/error/ErrorMessage'; diff --git a/examples/web/src/publications/UseBookmarkToggle.tsx b/examples/web/src/publications/UseBookmarkToggle.tsx index 920cfb81aa..653b630fa4 100644 --- a/examples/web/src/publications/UseBookmarkToggle.tsx +++ b/examples/web/src/publications/UseBookmarkToggle.tsx @@ -8,9 +8,9 @@ import { } from '@lens-protocol/react-web'; import { RequireProfileSession } from '../components/auth'; +import { PublicationCard } from '../components/cards'; import { ErrorMessage } from '../components/error/ErrorMessage'; import { Loading } from '../components/loading/Loading'; -import { PublicationCard } from './components/PublicationCard'; function IndividualPublication({ publication }: { publication: Post | Comment }) { const { execute: toggle, loading } = useBookmarkToggle(); diff --git a/examples/web/src/publications/UseBookmarks.tsx b/examples/web/src/publications/UseBookmarks.tsx index 831bc0db29..c1cae33192 100644 --- a/examples/web/src/publications/UseBookmarks.tsx +++ b/examples/web/src/publications/UseBookmarks.tsx @@ -1,10 +1,10 @@ import { useBookmarks } from '@lens-protocol/react-web'; import { RequireProfileSession } from '../components/auth'; +import { PublicationCard } from '../components/cards'; import { ErrorMessage } from '../components/error/ErrorMessage'; import { Loading } from '../components/loading/Loading'; import { useInfiniteScroll } from '../hooks/useInfiniteScroll'; -import { PublicationCard } from './components/PublicationCard'; export function MyBookmarks() { const { diff --git a/examples/web/src/publications/UseCreateComment.tsx b/examples/web/src/publications/UseCreateComment.tsx index feb3dff751..f0227abdad 100644 --- a/examples/web/src/publications/UseCreateComment.tsx +++ b/examples/web/src/publications/UseCreateComment.tsx @@ -1,22 +1,33 @@ import { textOnly } from '@lens-protocol/metadata'; -import { publicationId, useCreateComment, usePublication } from '@lens-protocol/react-web'; +import { + AnyPublication, + Comment, + LimitType, + publicationId, + useCreateComment, + usePublication, + usePublications, +} from '@lens-protocol/react-web'; import { toast } from 'react-hot-toast'; import { RequireProfileSession } from '../components/auth'; +import { CommentCard, PublicationCard } from '../components/cards'; import { ErrorMessage } from '../components/error/ErrorMessage'; import { Loading } from '../components/loading/Loading'; -import { uploadJson } from '../upload'; +import { useIrysUploader } from '../hooks/useIrysUploader'; import { never } from '../utils'; -import { PublicationCard } from './components/PublicationCard'; -function CommentComposer() { - const { - data: publication, - error: publicationError, - loading: publicationLoading, - } = usePublication({ forId: publicationId('0x56-0x02') }); +type CommentComposerProps = { + commentOn: AnyPublication; +}; +function CommentComposer({ commentOn }: CommentComposerProps) { + const { uploadMetadata } = useIrysUploader(); const { execute, loading, error } = useCreateComment(); + const { data: comments, prev: refresh } = usePublications({ + where: { commentOn: { id: commentOn.id } }, + limit: LimitType.Ten, + }); const submit = async (event: React.FormEvent) => { event.preventDefault(); @@ -30,8 +41,8 @@ function CommentComposer() { // publish post const result = await execute({ - commentOn: publication?.id ?? never('publication is not loaded'), - metadata: await uploadJson(metadata), + commentOn: commentOn?.id ?? never('publication is not loaded'), + metadata: await uploadMetadata(metadata), sponsored: formData.get('sponsored') === 'on', }); @@ -41,6 +52,8 @@ function CommentComposer() { return; } + toast.success(`Comment broadcasted, waiting for completion...`); + // wait for full completion const completion = await result.value.waitForCompletion(); @@ -50,60 +63,74 @@ function CommentComposer() { return; } - // post was created - const post = completion.value; - toast.success(`Post ID: ${post.id}`); - }; + await refresh(); - if (publicationLoading) return ; - - if (publicationError) return ; + // comment was created + const comment = completion.value; + toast.success(`Comment ID: ${comment.id}`); + }; return ( -
- - -
- - -