Skip to content

Commit

Permalink
Merge pull request #1085 from defispartan/feat/frames-1.1
Browse files Browse the repository at this point in the history
feat: frames 1.1
  • Loading branch information
cesarenaldi authored Feb 25, 2025
2 parents f1a391e + 67e3092 commit 66eaf36
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 0 deletions.
100 changes: 100 additions & 0 deletions packages/client/src/actions/frames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {
CreateFrameTypedDataQuery,
type FrameVerifySignatureResult,
SignFrameActionMutation,
VerifyFrameSignatureQuery,
} from '@lens-protocol/graphql';
import type {
CreateFrameEip712TypedDataFragment,
CreateFrameTypedDataRequest,
FrameLensManagerSignatureResultFragment,
SignFrameActionRequest,
VerifyFrameSignatureRequest,
} from '@lens-protocol/graphql';
import type { ResultAsync } from '@lens-protocol/types';
import type { AnyClient, SessionClient } from '../clients';
import type { UnauthenticatedError, UnexpectedError } from '../errors';

/**
* Create Frame action typed data to be signed by user wallet
*
* @param request - The request object
* @returns Typed data for Frame request
* @experimental This function might change in the future release
*
* @example
* ```ts
* const result = await createFrameTypedData(anyClient, {
* transactionId: '0x0000000000000000000000000000000000000000',
* buttonIndex: 2,
* deadline: 1711038973,
* inputText: 'Hello, World!',
* account: '0x0000000000000000000000000000000000000000',
* post: '0x01-0x01',
* app: '0x0000000000000000000000000000000000000000,
* specVersion: '1.1.0',
* state: '{"counter":1,"idempotency_key":"431b8b38-eb4d-455b"}',
* url: 'https://mylensframe.xyz',
* });
* ```
*/
export function createFrameTypedData(
client: AnyClient,
request: CreateFrameTypedDataRequest,
): ResultAsync<CreateFrameEip712TypedDataFragment, UnexpectedError> {
return client.query(CreateFrameTypedDataQuery, { request });
}

/**
* Sign Frame action with Lens Manager if enabled
*
* ⚠️ Requires authenticated SessionClient.
*
* @param request - The request object
* @returns Signature result
* @experimental This function might change in the future release
*
* @example
* ```ts
* const result = await signFrameAction(sessionClient, {
* transactionId: '0x0000000000000000000000000000000000000000',
* buttonIndex: 2,
* inputText: 'Hello, World!',
* account: '0x0000000000000000000000000000000000000000',
* post: '0x01-0x01',
* app: '0x0000000000000000000000000000000000000000,
* specVersion: '1.1.0',
* state: '{"counter":1,"idempotency_key":"431b8b38-eb4d-455b"}',
* url: 'https://mylensframe.xyz',
* });
* ```
*/
export function signFrameAction(
client: SessionClient,
request: SignFrameActionRequest,
): ResultAsync<FrameLensManagerSignatureResultFragment, UnexpectedError | UnauthenticatedError> {
return client.mutation(SignFrameActionMutation, { request });
}

/**
* Verify Frame signature
*
* @param request - The request object
* @returns Verification result
* @experimental This function might change in the future release
*
* @example
* ```ts
* const result = await verifyFrameSignature(anyClient, {
* identityToken: identityToken,
* signature: data.signature,
* signedTypedData: data.signedTypedData,
* });
* ```
*/
export function verifyFrameSignature(
client: AnyClient,
request: VerifyFrameSignatureRequest,
): ResultAsync<FrameVerifySignatureResult, UnexpectedError> {
return client.query(VerifyFrameSignatureQuery, { request });
}
14 changes: 14 additions & 0 deletions packages/graphql/src/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1129,3 +1129,17 @@ export enum SimpleCollectValidationFailedReason {
NotAFollower = 'NOT_A_FOLLOWER',
PostDeleted = 'POST_DELETED',
}

export enum FrameVerifySignatureResult {
Verified = 'VERIFIED',
PostDoesntExist = 'POST_DOESNT_EXIST',
IdentityUnauthorized = 'IDENTITY_UNAUTHORIZED',
IdentityTokenNotValid = 'IDENTITY_TOKEN_NOT_VALID',
TypedDataTypesIncorrectFields = 'TYPED_DATA_TYPES_INCORRECT_FIELDS',
TypedDataDomainIncorrect = 'TYPED_DATA_DOMAIN_INCORRECT',
TypedDataAccountNotMatchingIdentityToken = 'TYPED_DATA_ACCOUNT_NOT_MATCHING_IDENTITY_TOKEN',
IdentityCannotUseAccount = 'IDENTITY_CANNOT_USE_ACCOUNT',
SignatureNotValid = 'SIGNATURE_NOT_VALID',
DeadlineExpired = 'DEADLINE_EXPIRED',
SignerAddressCannotUseAccount = 'SIGNER_ADDRESS_CANNOT_USE_ACCOUNT',
}
81 changes: 81 additions & 0 deletions packages/graphql/src/frames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { FragmentOf } from 'gql.tada';
import { type RequestOf, graphql } from './graphql';

const EIP712TypedDataDomainFragment = graphql(
`fragment EIP712TypedDataDomain on EIP712TypedDataDomain {
name
chain_id
version
verifying_contract
}`,
);

export const CreateFrameEip712TypedDataFragment = graphql(
`fragment CreateFrameEip712TypedData on CreateFrameEIP712TypedData {
types {
FrameData {
name
type
}
}
domain {
...EIP712TypedDataDomain
}
value {
specVersion
url
buttonIndex
account
post
inputText
state
transactionId
app
deadline
}
}`,
[EIP712TypedDataDomainFragment],
);
export type CreateFrameEip712TypedDataFragment = FragmentOf<
typeof CreateFrameEip712TypedDataFragment
>;

export const CreateFrameTypedDataQuery = graphql(
`query CreateFrameTypedData($request: FrameEIP712Request!) {
value: createFrameTypedData(request: $request) {
...CreateFrameEip712TypedData
}
}`,
[CreateFrameEip712TypedDataFragment],
);
export type CreateFrameTypedDataRequest = RequestOf<typeof CreateFrameTypedDataQuery>;

export const VerifyFrameSignatureQuery = graphql(
`query VerifyFrameSignature($request: FrameVerifySignature!) {
value: verifyFrameSignature(request: $request)
}`,
);
export type VerifyFrameSignatureRequest = RequestOf<typeof VerifyFrameSignatureQuery>;

export const FrameLensManagerSignatureResultFragment = graphql(
`fragment FrameLensManagerSignatureResult on FrameLensManagerSignatureResult {
signedTypedData {
...CreateFrameEip712TypedData
}
signature
}`,
[CreateFrameEip712TypedDataFragment],
);
export type FrameLensManagerSignatureResultFragment = FragmentOf<
typeof FrameLensManagerSignatureResultFragment
>;

export const SignFrameActionMutation = graphql(
`mutation SignFrameAction($request: FrameLensManagerEIP712Request!) {
value: signFrameAction(request: $request) {
...FrameLensManagerSignatureResult
}
}`,
[FrameLensManagerSignatureResultFragment],
);
export type SignFrameActionRequest = RequestOf<typeof SignFrameActionMutation>;
2 changes: 2 additions & 0 deletions packages/graphql/src/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import type {
FollowersYouKnowOrderBy,
FollowingOrderBy,
ForYouSource,
FrameVerifySignatureResult,
GraphRuleExecuteOn,
GraphRuleType,
GraphsOrderBy,
Expand Down Expand Up @@ -140,6 +141,7 @@ export const graphql = initGraphQLTada<{
FollowersYouKnowOrderBy: FollowersYouKnowOrderBy;
FollowingOrderBy: FollowingOrderBy;
ForYouSource: ForYouSource;
FrameVerifySignatureResult: FrameVerifySignatureResult;
GeneratedNotificationId: ID;
GraphRuleExecuteOn: GraphRuleExecuteOn;
GraphRuleType: GraphRuleType;
Expand Down
1 change: 1 addition & 0 deletions packages/graphql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './common';
export * from './enums';
export * from './feed';
export * from './follow';
export * from './frames';
export * from './fragments';
export * from './graph';
export * from './graphql';
Expand Down

0 comments on commit 66eaf36

Please sign in to comment.