Closed defispartan closed 1 month ago
@defispartan can you help me with the fix here 🙇🏼
import type { ButtonType } from '@hey/types/misc';
import type { Request, Response } from 'express';
import { IS_MAINNET } from '@hey/data/constants';
import logger from '@hey/helpers/logger';
import parseJwt from '@hey/helpers/parseJwt';
import axios from 'axios';
import { parseHTML } from 'linkedom';
import catchedError from 'src/helpers/catchedError';
import { HEY_USER_AGENT } from 'src/helpers/constants';
import signFrameAction from 'src/helpers/frames/signFrameAction';
import { rateLimiter } from 'src/helpers/middlewares/rateLimiter';
import validateLensAccount from 'src/helpers/middlewares/validateLensAccount';
import getFrame from 'src/helpers/oembed/meta/getFrame';
import { invalidBody, noBody } from 'src/helpers/responses';
import { number, object, string } from 'zod';
type ExtensionRequest = {
buttonAction?: ButtonType;
buttonIndex: number;
inputText?: string;
postUrl: string;
pubId: string;
state?: string;
};
const validationSchema = object({
buttonAction: string().optional(),
buttonIndex: number(),
postUrl: string(),
pubId: string()
});
export const post = [
rateLimiter({ requests: 100, within: 1 }),
validateLensAccount,
async (req: Request, res: Response) => {
const { body } = req;
if (!body) {
return noBody(res);
}
const validation = validationSchema.safeParse(body);
if (!validation.success) {
return invalidBody(res);
}
const { buttonAction, buttonIndex, inputText, postUrl, pubId, state } =
body as ExtensionRequest;
try {
const accessToken = req.headers['x-access-token'] as string;
const identityToken = req.headers['x-identity-token'] as string;
const payload = parseJwt(identityToken);
const { id } = payload;
const request = {
actionResponse: '',
buttonIndex,
inputText: inputText || '',
profileId: id,
pubId,
specVersion: '1.0.0',
state: state || '',
url: postUrl
};
const signature = await signFrameAction(
request,
accessToken,
IS_MAINNET ? 'mainnet' : 'testnet'
);
const trustedData = { messageBytes: signature?.signature };
const untrustedData = {
identityToken,
unixTimestamp: Math.floor(Date.now() / 1000),
...signature?.signedTypedData.value
};
const { data } = await axios.post(
postUrl,
{ clientProtocol: 'lens@1.0.0', trustedData, untrustedData },
{ headers: { 'User-Agent': HEY_USER_AGENT } }
);
logger.info(`Open frame button clicked by ${id} on ${postUrl}`);
if (buttonAction === 'tx') {
return res
.status(200)
.json({ frame: { transaction: data }, success: true });
}
const { document } = parseHTML(data);
return res
.status(200)
.json({ frame: getFrame(document, postUrl), success: true });
} catch (error) {
return catchedError(res, error);
}
}
];
@bigint Yes I can submit a PR for this today
This issue has been locked since it has been closed for more than 10 days.
If you found a concrete bug or regression related to it, please open a new bug report.
Is there an existing issue for this?
Current Behavior
A Frame is considered valid to be rendered by a Lens application if it contains
of:accepts:lens
orof:accepts:anonymous
.Hey currently supports rendering Frame with
of:accepts:anonymous
but currently performs the samesignFrameAction
process which is unnecessary.Expected Behavior
If a Frame specifies
of:accepts:anonymous
, which is passed through the Hey Frame API endpoint as the unauthenticated field, thesignFrameAction
step should be skipped before POST request to Frame server.Steps To Reproduce
Example Frames with
of:accepts:anonymous
:What platform(s) does this occur on?
Web, Mobile
What browser(s) does this occur on?
Chrome, Firefox, Brave, Safari, Edge
Anything else?
The
of:accepts:anonymous
tag was just recently merged to the Open Frames standard so it can be considered as stable tag for Open Frames