Skip to content

Commit

Permalink
Improves documentation and exported types
Browse files Browse the repository at this point in the history
  • Loading branch information
cesarenaldi committed Sep 28, 2023
1 parent d0f7a8d commit 08c4f70
Show file tree
Hide file tree
Showing 20 changed files with 1,045 additions and 949 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
},
"devDependencies": {
"@changesets/cli": "^2.26.0",
"@mxssfd/typedoc-theme": "^1.0.6",
"@mxssfd/typedoc-theme": "^1.1.3",
"@preconstruct/cli": "^2.3.0",
"prettier": "^2.8.4",
"rimraf": "^4.1.2",
"turbo": "^1.8.1",
"typedoc": "^0.23.27",
"typedoc": "^0.25.1",
"typescript": "^4.9.5"
},
"resolutions": {
Expand Down
4 changes: 0 additions & 4 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,6 @@
],
"exports": true
},
"typedoc": {
"entryPoint": "./src/index.ts",
"tsconfig": "./tsconfig.json"
},
"peerDependencies": {
"@lens-protocol/metadata": "0.1.0-alpha.29"
}
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/LensClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export type LensClientConfig = {

/**
* The LensClient is the main entry point for the LensClient SDK.
*
* It provides access to all the different modules.
*
* @group LensClient
Expand Down
5 changes: 5 additions & 0 deletions packages/client/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export type MediaTransformsConfig = {
profileCover?: ImageTransform;
};

/**
* The LensClient context.
*
* @internal
*/
export type LensContext = {
environment: Environment;

Expand Down
4 changes: 2 additions & 2 deletions packages/client/src/environments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ export const production = new Environment(

export const development = new Environment(
'development',
'https://api-mumbai.lens.dev',
'https://api-v2-mumbai.lens.dev/graphql',
GatedEnvironments.development,
);

export const sandbox = new Environment(
'sandbox',
'https://api-sandbox-mumbai.lens.dev',
'https://api-v2-mumbai.lens.dev/graphql', // same as development for now
GatedEnvironments.sandbox,
);
4 changes: 2 additions & 2 deletions packages/client/src/gated/Gated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { failure, PromiseResult, success } from '@lens-protocol/shared-kernel';

import { Authentication } from '../authentication';
import { CredentialsExpiredError, NotAuthenticatedError } from '../errors';
import { EncryptablePublicationMetadataFragment } from '../graphql';
import { AnyEncryptablePublicationMetadataFragment } from '../graphql';

/**
* Gated module.
Expand Down Expand Up @@ -115,7 +115,7 @@ export class Gated {
* }
* ```
*/
async decryptPublicationMetadataFragment<T extends EncryptablePublicationMetadataFragment>(
async decryptPublicationMetadataFragment<T extends AnyEncryptablePublicationMetadataFragment>(
encryptedMetadata: T,
): PromiseResult<T, CannotDecryptError | CredentialsExpiredError | NotAuthenticatedError> {
return this.authentication.requireAuthentication(async (profileId) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/gated/LensClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export type LensClientConfig = base.LensClientConfig & {
/**
* Lens Protocol Client with token-gated content support.
*
* @group LensClient
* It provides access to all the base {@link Base.LensClient} modules and the {@link Gated} module.
*
* @example
* NodeJS example:
Expand Down
193 changes: 193 additions & 0 deletions packages/client/src/gated/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,196 @@
/**
* The Gated module is a secondary entry point of the `@lens-protocol/client` package.
* It provides an alternative {@link Gated.LensClient} class that supports all the
* functionalities of the {@link Base.LensClient} plus the {@link Gated} module.
*
* The reason for this separation is that token-gated feature requires extra 3rd party dependencies
* that could potentially impact the bundle size of your application. This way the
* developer have the choice to opt-in for token-gated support only when needed.
*
* The usage is the same as the {@link Base.LensClient} class, but with the addition of
* token gated configuration {@link Gated.LensClientConfig}: `authentication`, `signer`, and `encryption`.
*
* ## Quick start
*
* Install:
*
* ```bash
* npm install zod @lens-protocol/metadata@latest @lens-protocol/client@alpha
*
* # OR
*
* yarn add zod @lens-protocol/metadata@latest @lens-protocol/client@alpha
*
* # OR
*
* pnpm add zod @lens-protocol/metadata@latest @lens-protocol/client@alpha
* ```
*
* Typical NodeJS setup:
* ```ts
* import { Wallet } from 'ethers';
* import { production } from '@lens-protocol/client';
* import { LensClient } from '@lens-protocol/client/gated';
*
* const signer = new Wallet(process.env.PRIVATE_KEY);
*
* const client = new LensClient({
* environment: production,
*
* authentication: {
* domain: process.env.DOMAIN,
* uri: process.env.URI,
* },
*
* signer,
* });
* ```
*
* Browser setup with `ethers` v6 and an EIP-1193 wallet (e.g. MetaMask):
* ```ts
* import { BrowserProvider } from 'ethers';
* import { production } from '@lens-protocol/client';
* import { LensClient } from '@lens-protocol/client/gated';
*
* // wrap the EIP-1193 provider with ethers v6 BrowserProvider
* const provider = new BrowserProvider(window.ethereum);
*
* const client = new LensClient({
* environment: production,
*
* authentication: {
* domain: window.location.hostname,
* uri: window.location.href,
* },
*
* signer: await provider.getSigner(),
* });
* ```
*
* ## Encryption
*
* You can encrypt publication metadata using the {@link Gated.encryptPublicationMetadata} method.
*
* ```ts
* import { article, erc721OwnershipCondition } from '@lens-protocol/metadata';
*
* // create metadata via '@lens-protocol/metadata' helpers
* const metadata = article({ content: '...' });
*
* // encrypt the metadata specifying the access condition
* const result = await client.gated.encryptPublicationMetadata(
* metadata,
* erc721OwnershipCondition({
* contract: { address: '0x...', chainId: 1 }
* })
* );
*
* // handle encryption errors
* if (result.isFailure()) {
* console.error(result.error);
* return; // bail out
* }
*
* // upload the encrypted metadata to your storage of choice
* const contentURI = await uploadToIPFS(result.value);
*
* // use the contentURI to create a publication
* const result = await client.publication.postOnchain({ contentURI });
* ```
*
* **What's happening?**
* 1) create metadata via `@lens-protocol/metadata` helpers,
* 2) encrypt it with the given access condition,
* 3) upload it to a public location (e.g. IPFS, Arweave, public S3 bucket),
* 4) use the resulting `contentURI` to create a Lens publication.
*
* ### Simple criteria
*
* Supported criteria available as helpers in the `@lens-protocol/metadata` package:
* - `collectCondition` - the collection of a given publication is required
* - `eoaOwnershipCondition` - the ownership of a given EOA is required
* - `erc20OwnershipCondition` - the ownership of a given ERC20 amount is required
* - `erc721OwnershipCondition` - the ownership of a given ERC721 token is required
* - `erc1155OwnershipCondition` - the ownership of a given ERC1155 token is required
* - `profileOwnershipCondition` - the ownership of a given profile is required
* - `followCondition` - following a given profile is required
*
* Refer to the [`@lens-protocol/metadata`](https://lens-protocol.github.io/metadata/) reference for more details.
*
* **Collect this publication**
*
* It's possible to define an access condition where one of the criteria is to collect the current publication.
*
* Because at the time of encryption the publication is not yet created, the {@link Base.Publication.predictNextOnChainPublicationId} can be
* used to predict the publication ID.
*
* ```ts
* const condition = collectCondition({
* publicationId: await client.publication.predictNextOnChainPublicationId({
* from: profile.id,
* }),
* thisPublication: true, // flag to indicate that the current publication is the one to collect
* });
* ```
*
* ### Compound criteria
*
* Multiple criteria can be combined using the `orCondition` and `andCondition` helpers.
* ```ts
* const result = await client.gated.encryptPublicationMetadata(
* metadata,
* orCondition([
* profileOwnershipCondition({
* profileId: profile.id,
* }),
* erc721OwnershipCondition({
* contract: { address: '0x...', chainId: 1 }
* })
* ])
* );
* ```
*
* Supported compound criteria:
* - `andCondition` - up to 5 criteria can be combined using the AND operator (except `orCondition` and `andCondition`)
* - `orCondition` - up to 5 criteria can be combined using the OR operator (except `orCondition` and `andCondition`)
*
* ## Decryption
*
* You can decrypt publication metadata using the {@link Gated.decryptPublicationMetadataFragment} method.
*
* The method works seamlessly with publications returned by any `LensClient` method.
*
* ```ts
* import { isEncryptedPublicationMetadata } from '@lens-protocol/client/gated';
*
* // fetch a publication, works with publications returned by any LensClient method
* const post = await client.publication.fetch({ forId: '...' });
*
* // check if the publication metadata is encrypted
* if (isEncryptedPublicationMetadata(post.metadata)) {
*
* // decrypt the metadata
* const result = await client.gated.decryptPublicationMetadataFragment(post.metadata);
*
* // handle decryption errors
* if (result.isFailure()) {
* console.error(result.error);
* return; // bail out
* }
*
* // use the decrypted metadata
* console.log(result.value);
* }
* ```
*
* ⚠️ In case you find yourself using this feature with publication metadata fragment not originated from the `LensClient`
* it's your responsibility to make sure the `PublicationMetadata` fragment is valid by making sure it:
* - has `__typename` defined at every level of the fragment
* - has the `encryptedWith` including ALL fields and sub-fields of the corresponding GQL node.
*
* @module Gated
*/

export * from './Gated';
export * from './LensClient';
export { isEncryptedPublicationMetadata } from '@lens-protocol/gated-content';
Expand Down
Loading

0 comments on commit 08c4f70

Please sign in to comment.