-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Add Open Frames Neynar validator #116
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { OpenFramesRequest, RequestValidator, ValidationResponse } from '@open-frames/types'; | ||
import { FarcasterOpenFramesRequest, FrameRequest, FrameValidationData } from '../../../core/types'; | ||
import { NEYNAR_DEFAULT_API_KEY, neynarFrameValidation } from '../frame/neynarFrameFunctions'; | ||
import { Options } from './types'; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh side note, we prefer Functional code vs Object Oriented, as it is much lighter in terms of memory and also easier to write test for. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough. All I really care about is having something that satisfies a common interface so that developers can build their own request validators and have confidence they will be able to integrate. Whether the implementation of the interface is a module, an object, or a class is up to the implementer. |
||
export class NeynarValidator | ||
implements RequestValidator<FarcasterOpenFramesRequest, FrameValidationData, 'farcaster'> | ||
{ | ||
readonly protocolIdentifier = 'farcaster'; | ||
private options: Required<Options>; | ||
|
||
constructor(options?: Options) { | ||
this.options = { | ||
neynarApiKey: options?.neynarApiKey || NEYNAR_DEFAULT_API_KEY, | ||
castReactionContext: options?.castReactionContext || true, | ||
followContext: options?.followContext || true, | ||
}; | ||
} | ||
|
||
minProtocolVersion(): string { | ||
return `${this.protocolIdentifier}@VNext`; | ||
} | ||
|
||
isSupported(payload: OpenFramesRequest): payload is FarcasterOpenFramesRequest { | ||
const isCorrectClientProtocol = | ||
!!payload.clientProtocol && payload.clientProtocol.startsWith('farcaster@'); | ||
const isTrustedDataValid = typeof payload.trustedData?.messageBytes === 'string'; | ||
|
||
return isCorrectClientProtocol && isTrustedDataValid; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I see, And ideally we can have as many client as we want. There are some implementation details that we need to align, but I like where your head is @neekolas There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly. Here is an example of the XMTP RequestValidator that can be safely passed in to |
||
|
||
async validate( | ||
payload: FarcasterOpenFramesRequest, | ||
): Promise<ValidationResponse<FrameValidationData, typeof this.protocolIdentifier>> { | ||
const response = await neynarFrameValidation( | ||
payload.trustedData?.messageBytes, | ||
this.options.neynarApiKey, | ||
this.options.castReactionContext, | ||
this.options.followContext, | ||
); | ||
|
||
if (response?.valid) { | ||
return { | ||
isValid: true, | ||
clientProtocol: payload.clientProtocol, | ||
message: response, | ||
}; | ||
} | ||
|
||
return { | ||
isValid: false, | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export type Options = { | ||
neynarApiKey?: string; | ||
castReactionContext?: boolean; | ||
followContext?: boolean; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Veeeery interesting