diff --git a/.changeset/honest-buses-flow.md b/.changeset/honest-buses-flow.md new file mode 100644 index 0000000000..7c7b1a5265 --- /dev/null +++ b/.changeset/honest-buses-flow.md @@ -0,0 +1,5 @@ +--- +"@lens-protocol/client": minor +--- + +**feat**: Added `authentication.fromRefreshToken` method to allow to authenticate LensClient from an existing refresh token diff --git a/examples/node/scripts/authentication/authenticate.ts b/examples/node/scripts/authentication/authenticate.ts index 63d03b4e3b..1d4f9bee29 100644 --- a/examples/node/scripts/authentication/authenticate.ts +++ b/examples/node/scripts/authentication/authenticate.ts @@ -5,11 +5,6 @@ import { setupWallet } from '../shared/setupWallet'; async function main() { const client = new LensClient({ environment: development, - headers: { - origin: 'https://lens-scripts.example', - 'user-agent': - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', - }, }); const wallet = setupWallet(); diff --git a/examples/node/scripts/authentication/fromRefreshToken.ts b/examples/node/scripts/authentication/fromRefreshToken.ts new file mode 100644 index 0000000000..1126af0901 --- /dev/null +++ b/examples/node/scripts/authentication/fromRefreshToken.ts @@ -0,0 +1,21 @@ +import { LensClient, development } from '@lens-protocol/client'; + +async function main() { + const client = new LensClient({ + environment: development, + }); + + const token = 'YOUR_VALID_REFRESH_TOKEN_HERE'; + await client.authentication.fromRefreshToken(token); + + console.log(`Is LensClient authenticated? `, await client.authentication.isAuthenticated()); + + const accessTokenResult = await client.authentication.getAccessToken(); + const accessToken = accessTokenResult.unwrap(); + const profileId = await client.authentication.getProfileId(); + + console.log(`Authenticated profileId: `, profileId); + console.log(`Access token: `, accessToken); +} + +main(); diff --git a/examples/node/scripts/authentication/overwriteOrigin.ts b/examples/node/scripts/authentication/overwriteOrigin.ts new file mode 100644 index 0000000000..1498383a46 --- /dev/null +++ b/examples/node/scripts/authentication/overwriteOrigin.ts @@ -0,0 +1,36 @@ +import { LensClient, development } from '@lens-protocol/client'; + +import { setupWallet } from '../shared/setupWallet'; + +async function main() { + const client = new LensClient({ + environment: development, + headers: { + origin: 'https://lens-scripts.example', + }, + }); + + const wallet = setupWallet(); + const address = await wallet.getAddress(); + + const managedProfiles = await client.wallet.profilesManaged({ for: wallet.address }); + + if (managedProfiles.items.length === 0) { + throw new Error(`You don't manage any profiles, create one first`); + } + + const { id, text } = await client.authentication.generateChallenge({ + signedBy: address, + for: managedProfiles.items[0].id, + }); + + console.log(`Challenge: `, text); // Notice the origin URL in the challenge message + + const signature = await wallet.signMessage(text); + + await client.authentication.authenticate({ id, signature }); + + console.log(`Is LensClient authenticated? `, await client.authentication.isAuthenticated()); +} + +main(); diff --git a/packages/client/package.json b/packages/client/package.json index 49265eefdf..580257c1bd 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -97,7 +97,7 @@ "typescript": "5.2.2" }, "engines": { - "node": "^18.15.0" + "node": ">=18 <21" }, "prettier": "@lens-protocol/prettier-config", "babel": { diff --git a/packages/client/src/authentication/Authentication.ts b/packages/client/src/authentication/Authentication.ts index 76662f9a73..45fee15d00 100644 --- a/packages/client/src/authentication/Authentication.ts +++ b/packages/client/src/authentication/Authentication.ts @@ -35,6 +35,11 @@ export class Authentication implements IAuthentication { this.credentials = new CredentialsStorage(context.storage, context.environment.name); } + async fromRefreshToken(refreshToken: string): Promise { + const credentials = new Credentials(undefined, refreshToken); + await this.credentials.set(credentials); + } + async generateChallenge(request: ChallengeRequest): Promise { return this.api.challenge(request); } diff --git a/packages/client/src/authentication/IAuthentication.ts b/packages/client/src/authentication/IAuthentication.ts index e65e39aae7..3e87fa4a0a 100644 --- a/packages/client/src/authentication/IAuthentication.ts +++ b/packages/client/src/authentication/IAuthentication.ts @@ -20,6 +20,13 @@ import type { * @group LensClient Modules */ export interface IAuthentication { + /** + * Authenticate from an existing, valid refresh token. + * + * @param refreshToken - The refresh token + */ + fromRefreshToken(refreshToken: string): Promise; + /** * Generate a challenge string for the wallet to sign. *