Skip to content

Commit

Permalink
fix: wrong parsing of frame message for different handlers (#466)
Browse files Browse the repository at this point in the history
* fix: wrong parsing of frame message for different handlers

* chore: changesets

* nit: change changeset bump and export other types

* Update .changeset/lemon-doors-fail.md
  • Loading branch information
dalechyn authored Aug 10, 2024
1 parent e0b2e2c commit d4899ab
Show file tree
Hide file tree
Showing 22 changed files with 424 additions and 133 deletions.
7 changes: 7 additions & 0 deletions .changeset/lemon-doors-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"frog": minor
---

**Breaking Change:** Renamed exported `Context` type to `FrameBaseContext`.
Fixed an issue where frame message was parsed incorrectly and was expecting `cast_id` in Composer Action Handler.
Exported previously forgotten types.
16 changes: 8 additions & 8 deletions src/frog-base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ import { parseHonoPath } from './utils/parseHonoPath.js'
import { parseImage } from './utils/parseImage.js'
import { parseIntents } from './utils/parseIntents.js'
import { parsePath } from './utils/parsePath.js'
import { requestBodyToContext } from './utils/requestBodyToContext.js'
import { requestBodyToCastActionBaseContext } from './utils/requestBodyToCastActionBaseContext.js'
import { requestBodyToComposerActionBaseContext } from './utils/requestBodyToComposerActionBaseContext.js'
import { requestBodyToFrameBaseContext } from './utils/requestBodyToFrameBaseContext.js'
import { requestBodyToImageContext } from './utils/requestBodyToImageContext.js'
import { serializeJson } from './utils/serializeJson.js'
import { toSearchParams } from './utils/toSearchParams.js'
Expand Down Expand Up @@ -437,11 +439,10 @@ export class FrogBase<
const baseUrl = origin + parsePath(this.basePath)

const { context } = getCastActionContext<env, string>({
context: await requestBodyToContext(c, {
context: await requestBodyToCastActionBaseContext(c, {
hub:
this.hub ||
(this.hubApiUrl ? { apiUrl: this.hubApiUrl } : undefined),
secret: this.secret,
verify,
verifyOrigin: this.verifyOrigin,
}),
Expand Down Expand Up @@ -520,11 +521,10 @@ export class FrogBase<
// Composer Action Route (implements POST).
this.hono.post(parseHonoPath(path), ...middlewares, async (c) => {
const { context } = getComposerActionContext<env, string>({
context: await requestBodyToContext(c, {
context: await requestBodyToComposerActionBaseContext(c, {
hub:
this.hub ||
(this.hubApiUrl ? { apiUrl: this.hubApiUrl } : undefined),
secret: this.secret,
verify,
verifyOrigin: this.verifyOrigin,
}),
Expand Down Expand Up @@ -603,7 +603,7 @@ export class FrogBase<
this.initialBasePath,
)
const { context, getState } = await getFrameContext<env, string>({
context: await requestBodyToContext(c, {
context: await requestBodyToFrameBaseContext(c, {
hub:
this.hub ||
(this.hubApiUrl ? { apiUrl: this.hubApiUrl } : undefined),
Expand Down Expand Up @@ -1126,7 +1126,7 @@ export class FrogBase<

this.hono.post(parseHonoPath(path), ...middlewares, async (c) => {
const { context } = await getTransactionContext<env, string, {}, _state>({
context: await requestBodyToContext(c, {
context: await requestBodyToFrameBaseContext(c, {
hub:
this.hub ||
(this.hubApiUrl ? { apiUrl: this.hubApiUrl } : undefined),
Expand Down Expand Up @@ -1164,7 +1164,7 @@ export class FrogBase<

this.hono.post(parseHonoPath(path), ...middlewares, async (c) => {
const { context } = await getSignatureContext<env, string, {}, _state>({
context: await requestBodyToContext(c, {
context: await requestBodyToFrameBaseContext(c, {
hub:
this.hub ||
(this.hubApiUrl ? { apiUrl: this.hubApiUrl } : undefined),
Expand Down
2 changes: 1 addition & 1 deletion src/hubs/neynar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const neynar = createHub((parameters: NeynarHubParameters) => {
api_key: apiKey,
},
},
verifyFrame: async ({ trustedData }: { trustedData: TrustedData }) => {
verifyMessage: async ({ trustedData }: { trustedData: TrustedData }) => {
return await fetch('https://api.neynar.com/v2/farcaster/frame/validate', {
method: 'POST',
headers: {
Expand Down
32 changes: 31 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,40 @@ export {
getFrameMetadata,
} from './utils/getFrameMetadata.js'

export {
messageToCastActionData,
type VerifyCastActionParameters,
type VerifyCastActionReturnType,
verifyCastAction,
} from './utils/verifyCastAction.js'

export {
messageToComposerActionData,
type VerifyComposerActionParameters,
type VerifyComposerActionReturnType,
verifyComposerAction,
} from './utils/verifyComposerAction.js'

export {
messageToFrameData,
type VerifyFrameParameters,
type VerifyFrameReturnType,
verifyFrame,
} from './utils/verifyFrame.js'

export {
type VerifyMessageParameters,
type VerifyMessageReturnType,
verifyMessage,
} from './utils/verifyMessage.js'

export type { CastActionResponse } from './types/castAction.js'
export type {
CastActionBaseContext,
CastActionContext,
Context,
ComposerActionBaseContext,
ComposerActionContext,
FrameBaseContext,
FrameContext,
ImageContext,
TransactionContext,
Expand All @@ -47,6 +70,7 @@ export type { ImageResponse } from './types/image.js'
export type { HandlerResponse, TypedResponse } from './types/response.js'
export type {
CastActionHandler,
ComposerActionHandler,
FrameHandler,
HandlerInterface,
ImageHandler,
Expand All @@ -60,3 +84,9 @@ export type {
SendTransactionParameters,
TransactionParameters,
} from './types/transaction.js'

export type {
SignatureResponse,
SignatureParameters,
SignTypedDataParameters,
} from './types/signature.js'
1 change: 0 additions & 1 deletion src/types/composerAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export type ComposerActionResponseFn = (

export type ComposerActionData = {
buttonIndex: 1
castId: { fid: number; hash: string }
fid: number
messageHash: string
network: number
Expand Down
88 changes: 54 additions & 34 deletions src/types/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ import type {
} from './transaction.js'
import type { Pretty } from './utils.js'

export type CastActionContext<
export type CastActionBaseContext<
env extends Env = Env,
path extends string = string,
input extends Input = {},
> = {
/**
* Data from the action that was passed via the POST body.
* The {@link Context`verified`} flag indicates whether the data is trusted or not.
* The {@link FrameBaseContext`verified`} flag indicates whether the data is trusted or not.
*/
actionData: Pretty<CastActionData>
/**
Expand All @@ -49,6 +49,29 @@ export type CastActionContext<
* @see https://hono.dev/api/context#env
*/
env: Context_hono<env, path>['env']
/**
* Hono request object.
*
* @see https://hono.dev/api/context#req
*/
req: Context_hono<env, path, input>['req']
/**
* Extract a context value that was previously set via `set` in [Middleware](/concepts/middleware).
*
* @see https://hono.dev/api/context#var
*/
var: Context_hono<env, path, input>['var']
/**
* Whether or not the {@link FrameBaseContext`actionData`} was verified by the Farcaster Hub API.
*/
verified: boolean
}

export type CastActionContext<
env extends Env = Env,
path extends string = string,
input extends Input = {},
> = CastActionBaseContext<env, path, input> & {
/** Error response that includes message and statusCode. */
error: BaseErrorResponseFn
/**
Expand All @@ -63,38 +86,22 @@ export type CastActionContext<
* @see https://warpcast.notion.site/Frames-Cast-Actions-v1-84d5a85d479a43139ea883f6823d8caa
*/
message: CastActionMessageResponseFn
/**
* Hono request object.
*
* @see https://hono.dev/api/context#req
*/
req: Context_hono<env, path, input>['req']
/**
* Raw action response that includes action properties such as: message, statusCode.
*
* @see https://warpcast.notion.site/Spec-Farcaster-Actions-84d5a85d479a43139ea883f6823d8caa
* */
res: CastActionResponseFn
/**
* Extract a context value that was previously set via `set` in [Middleware](/concepts/middleware).
*
* @see https://hono.dev/api/context#var
*/
var: Context_hono<env, path, input>['var']
/**
* Whether or not the {@link Context`actionData`} was verified by the Farcaster Hub API.
*/
verified: boolean
}

export type ComposerActionContext<
export type ComposerActionBaseContext<
env extends Env = Env,
path extends string = string,
input extends Input = {},
> = {
/**
* Data from the action that was passed via the POST body.
* The {@link Context`verified`} flag indicates whether the data is trusted or not.
* The {@link ComposerActionBaseContext`verified`} flag indicates whether the data is trusted or not.
*/
actionData: Pretty<ComposerActionData>
/**
Expand All @@ -110,14 +117,31 @@ export type ComposerActionContext<
* @see https://hono.dev/api/context#env
*/
env: Context_hono<env, path>['env']
/** Error response that includes message and statusCode. */
error: BaseErrorResponseFn
/**
* Hono request object.
*
* @see https://hono.dev/api/context#req
*/
req: Context_hono<env, path, input>['req']
/**
* Extract a context value that was previously set via `set` in [Middleware](/concepts/middleware).
*
* @see https://hono.dev/api/context#var
*/
var: Context_hono<env, path, input>['var']
/**
* Whether or not the {@link ComposerActionBaseContext`actionData`} was verified by the Farcaster Hub API.
*/
verified: boolean
}

export type ComposerActionContext<
env extends Env = Env,
path extends string = string,
input extends Input = {},
> = ComposerActionBaseContext<env, path, input> & {
/** Error response that includes message and statusCode. */
error: BaseErrorResponseFn
/**
* Composer action response.
*
Expand All @@ -130,13 +154,9 @@ export type ComposerActionContext<
* @see https://hono.dev/api/context#var
*/
var: Context_hono<env, path, input>['var']
/**
* Whether or not the {@link Context`actionData`} was verified by the Farcaster Hub API.
*/
verified: boolean
}

export type Context<
export type FrameBaseContext<
env extends Env = Env,
path extends string = string,
input extends Input = {},
Expand Down Expand Up @@ -166,7 +186,7 @@ export type Context<
env: Context_hono<env, path>['env']
/**
* Data from the frame that was passed via the POST body.
* The {@link Context`verified`} flag indicates whether the data is trusted or not.
* The {@link FrameBaseContext`verified`} flag indicates whether the data is trusted or not.
*/
frameData?: Pretty<FrameData>
/**
Expand Down Expand Up @@ -205,7 +225,7 @@ export type Context<
*/
var: Context_hono<env, path, input>['var']
/**
* Whether or not the {@link Context`frameData`} was verified by the Farcaster Hub API.
* Whether or not the {@link FrameBaseContext`frameData`} was verified by the Farcaster Hub API.
*/
verified: boolean
/**
Expand All @@ -220,7 +240,7 @@ export type FrameContext<
input extends Input = {},
//
_state = env['State'],
> = Context<env, path, input, _state> & {
> = FrameBaseContext<env, path, input, _state> & {
/**
* @deprecated As of `v0.5.0`, this property is redundant (there is now only one render cycle) and will be removed in a future version.
*
Expand Down Expand Up @@ -256,15 +276,15 @@ export type TransactionContext<
input extends Input = {},
//
_state = env['State'],
> = Context<env, path, input, _state> & {
> = FrameBaseContext<env, path, input, _state> & {
/**
* Address of the account that is executing a transaction (if any). Maps to:
* - Ethereum: 20-byte address string.
*/
address: string
/**
* Data from the frame that was passed via the POST body.
* The {@link Context`verified`} flag indicates whether the data is trusted or not.
* The {@link FrameBaseContext`verified`} flag indicates whether the data is trusted or not.
*/
frameData?: Pretty<FrameData>
/**
Expand Down Expand Up @@ -342,15 +362,15 @@ export type SignatureContext<
input extends Input = {},
//
_state = env['State'],
> = Context<env, path, input, _state> & {
> = FrameBaseContext<env, path, input, _state> & {
/**
* Address of the account that is signing a message (if any). Maps to:
* - Ethereum: 20-byte address string.
*/
address: string
/**
* Data from the frame that was passed via the POST body.
* The {@link Context`verified`} flag indicates whether the data is trusted or not.
* The {@link FrameBaseContext`verified`} flag indicates whether the data is trusted or not.
*/
frameData?: Pretty<FrameData>
/** Error response that includes message and statusCode. */
Expand Down
2 changes: 1 addition & 1 deletion src/types/hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ export type Hub = {
/** Options to pass to `fetch`. */
fetchOptions?: RequestInit
/** Verify frame override. */
verifyFrame?: (parameters: { trustedData: TrustedData }) => Promise<void>
verifyMessage?: (parameters: { trustedData: TrustedData }) => Promise<void>
}
4 changes: 2 additions & 2 deletions src/types/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type { ComposerActionResponse } from './composerAction.js'
import type {
CastActionContext,
ComposerActionContext,
Context,
FrameBaseContext,
FrameContext,
ImageContext,
SignatureContext,
Expand Down Expand Up @@ -91,7 +91,7 @@ export type Handler<
P extends string = any,
I extends Input = BlankInput,
R extends HandlerResponse<any> = any,
> = (c: Context<E, P, I>) => R
> = (c: FrameBaseContext<E, P, I>) => R

export type MiddlewareHandler<
E extends Env = any,
Expand Down
Loading

0 comments on commit d4899ab

Please sign in to comment.