Skip to content

Commit

Permalink
feat: better handling of FrameButton post actions (#1053)
Browse files Browse the repository at this point in the history
  • Loading branch information
brendan-defi authored Aug 15, 2024
1 parent a17237a commit 5b21c56
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/frame/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export type FrameButtonMetadata =
| {
action?: 'post' | 'post_redirect';
label: string;
postUrl?: string;
target?: string;
}
| {
Expand Down
33 changes: 33 additions & 0 deletions src/frame/utils/getFrameMetadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,39 @@ describe('getFrameMetadata', () => {
});
});

it('should return the correct metadata with action post and post_url', () => {
expect(
getFrameMetadata({
buttons: [
{
label: 'Button1',
action: 'post',
postUrl: 'https://zizzamia.xyz/api/frame/post-url?queryParam=XXX',
},
{
label: 'Button2',
action: 'post',
postUrl: 'https://zizzamia.xyz/api/frame/post-url?queryParam=YYY',
},
],
image: 'https://zizzamia.xyz/park-1.png',
postUrl: 'https://zizzamia.xyz/api/frame',
}),
).toEqual({
'fc:frame': 'vNext',
'fc:frame:button:1': 'Button1',
'fc:frame:button:1:action': 'post',
'fc:frame:button:1:post_url':
'https://zizzamia.xyz/api/frame/post-url?queryParam=XXX',
'fc:frame:button:2': 'Button2',
'fc:frame:button:2:action': 'post',
'fc:frame:button:2:post_url':
'https://zizzamia.xyz/api/frame/post-url?queryParam=YYY',
'fc:frame:image': 'https://zizzamia.xyz/park-1.png',
'fc:frame:post_url': 'https://zizzamia.xyz/api/frame',
});
});

it('should not render action target if action is not link, mint or tx', () => {
expect(
getFrameMetadata({
Expand Down
14 changes: 2 additions & 12 deletions src/frame/utils/getFrameMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { FrameMetadataResponse, FrameMetadataType } from '../types';
import { setFrameMetadataButtons } from './setFrameMetadataButtons';

/**
* This function generates the metadata for a Farcaster Frame.
Expand Down Expand Up @@ -36,18 +37,7 @@ export const getFrameMetadata = ({
metadata['fc:frame:input:text'] = input.text;
}
if (buttons) {
buttons.forEach((button, index) => {
metadata[`fc:frame:button:${index + 1}`] = button.label;
if (button.action) {
metadata[`fc:frame:button:${index + 1}:action`] = button.action;
}
if (button.target) {
metadata[`fc:frame:button:${index + 1}:target`] = button.target;
}
if (button.action && button.action === 'tx' && button.postUrl) {
metadata[`fc:frame:button:${index + 1}:post_url`] = button.postUrl;
}
});
setFrameMetadataButtons(metadata, buttons);
}
if (postUrlToUse) {
metadata['fc:frame:post_url'] = postUrlToUse;
Expand Down
126 changes: 126 additions & 0 deletions src/frame/utils/setFrameMetadataButtons.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { describe, expect, it } from 'vitest';
import { setFrameMetadataButtons } from './setFrameMetadataButtons';

describe('setFrameMetadataButtons', () => {
it('should return no button metadata', () => {
const testMetadata = {
'fc:frame': 'vNext',
};
setFrameMetadataButtons(testMetadata, undefined);

expect(testMetadata).toEqual({
'fc:frame': 'vNext',
});
});

it('should return the correct metadata', () => {
const testMetadata = {
'fc:frame': 'vNext',
};
setFrameMetadataButtons(testMetadata, [
{ label: 'button1', action: 'post' },
{ label: 'button2', action: 'post_redirect' },
{ label: 'button3' },
]);

expect(testMetadata).toEqual({
'fc:frame': 'vNext',
'fc:frame:button:1': 'button1',
'fc:frame:button:1:action': 'post',
'fc:frame:button:2': 'button2',
'fc:frame:button:2:action': 'post_redirect',
'fc:frame:button:3': 'button3',
});
});

it('should return the correct metadata for button with action tx and target', () => {
const testMetadata = { 'fc:frame': 'vNext' };
setFrameMetadataButtons(testMetadata, [
{
label: 'Button1',
action: 'tx',
target: 'https://zizzamia.xyz/api/frame/tx',
},
]);

expect(testMetadata).toEqual({
'fc:frame': 'vNext',
'fc:frame:button:1': 'Button1',
'fc:frame:button:1:action': 'tx',
'fc:frame:button:1:target': 'https://zizzamia.xyz/api/frame/tx',
});
});

it('should return the correct metadata for button with action post and post_url', () => {
const testMetadata = { 'fc:frame': 'vNext' };
setFrameMetadataButtons(testMetadata, [
{
label: 'Button1',
action: 'post',
postUrl: 'https://zizzamia.xyz/api/frame/post_url',
},
]);

expect(testMetadata).toEqual({
'fc:frame': 'vNext',
'fc:frame:button:1': 'Button1',
'fc:frame:button:1:action': 'post',
'fc:frame:button:1:post_url': 'https://zizzamia.xyz/api/frame/post_url',
});
});

it('should return the correct metadata for buttons with action tx and custom targets', () => {
const testMetadata = { 'fc:frame': 'vNext' };
setFrameMetadataButtons(testMetadata, [
{
label: 'Button1',
action: 'tx',
target: 'https://zizzamia.xyz/api/frame/tx?queryParam=XXX',
},
{
label: 'Button2',
action: 'tx',
target: 'https://zizzamia.xyz/api/frame/tx?queryParam=YYY',
},
]);

expect(testMetadata).toEqual({
'fc:frame': 'vNext',
'fc:frame:button:1': 'Button1',
'fc:frame:button:1:action': 'tx',
'fc:frame:button:1:target':
'https://zizzamia.xyz/api/frame/tx?queryParam=XXX',
'fc:frame:button:2': 'Button2',
'fc:frame:button:2:action': 'tx',
'fc:frame:button:2:target':
'https://zizzamia.xyz/api/frame/tx?queryParam=YYY',
});
});

it('should return the correct metadata for buttons with action post and custom post_urls', () => {
const testMetadata = { 'fc:frame': 'vNext' };
setFrameMetadataButtons(testMetadata, [
{
label: 'Button1',
action: 'post',
postUrl: 'https://zizzamia.xyz/api/frame/post-url?queryParam=XXX',
},
{
label: 'Button2',
action: 'post',
postUrl: 'https://zizzamia.xyz/api/frame/post-url?queryParam=YYY',
},
]);
expect(testMetadata).toEqual({
'fc:frame': 'vNext',
'fc:frame:button:1': 'Button1',
'fc:frame:button:1:action': 'post',
'fc:frame:button:1:post_url':
'https://zizzamia.xyz/api/frame/post-url?queryParam=XXX',
'fc:frame:button:2': 'Button2',
'fc:frame:button:2:action': 'post',
'fc:frame:button:2:post_url':
'https://zizzamia.xyz/api/frame/post-url?queryParam=YYY',
});
});
});
27 changes: 27 additions & 0 deletions src/frame/utils/setFrameMetadataButtons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { FrameMetadataType } from '../types';

export function setFrameMetadataButtons(
metadata: Record<string, string>,
buttons: FrameMetadataType['buttons'],
) {
if (!buttons) {
return;
}

buttons.forEach((button, index) => {
metadata[`fc:frame:button:${index + 1}`] = button.label;
if (button.action) {
metadata[`fc:frame:button:${index + 1}:action`] = button.action;
}
if (button.target) {
metadata[`fc:frame:button:${index + 1}:target`] = button.target;
}
if (
button.action &&
(button.action === 'tx' || button.action === 'post') &&
button.postUrl
) {
metadata[`fc:frame:button:${index + 1}:post_url`] = button.postUrl;
}
});
}

0 comments on commit 5b21c56

Please sign in to comment.