diff --git a/.changeset/silly-beans-visit.md b/.changeset/silly-beans-visit.md new file mode 100644 index 0000000000..80207a656e --- /dev/null +++ b/.changeset/silly-beans-visit.md @@ -0,0 +1,5 @@ +--- +'@coinbase/onchainkit': patch +--- + +- **feat**: Added `getXmtpFrameMessage` and `isXmtpFrameRequest` so that Frames can receive interactions from apps outside of Farcaster, such as from XMTP conversations. By @neekolas #123 diff --git a/README.md b/README.md index b65873ad30..ce2d240f8d 100644 --- a/README.md +++ b/README.md @@ -60,15 +60,19 @@ OnchainKit offers three themes packed with React components and TypeScript utili - Utilities: - [`getFrameHtmlResponse`](https://onchainkit.xyz/framekit/get-frame-html-response) - [`getFrameMessage`](https://onchainkit.xyz/framekit/get-frame-message) - - [`getXmtpFrameMessage`](https://onchainkit.xyz/framekit/get-xmtp-frame-message) - [`getFrameMetadata`](https://onchainkit.xyz/framekit/get-frame-metadata) - [Framegear](https://onchainkit.xyz/framekit/framegear) - [Identity Kit](https://onchainkit.xyz/identitykit/introduction) + - Components: - [``](https://onchainkit.xyz/identitykit/avatar) - [``](https://onchainkit.xyz/identitykit/name) +- [XMTP Kit](https://onchainkit.xyz/xmtpkit/introduction) + - Utilities: + - [`getXmtpFrameMessage`](https://onchainkit.xyz/xmtpkit/get-xmtp-frame-message) + ## Overview To integrate OnchainKit into your project, begin by installing the necessary packages. diff --git a/site/.yarn/install-state.gz b/site/.yarn/install-state.gz index 6b3b801305..eff354a5ae 100644 Binary files a/site/.yarn/install-state.gz and b/site/.yarn/install-state.gz differ diff --git a/site/docs/pages/framekit/introduction.mdx b/site/docs/pages/framekit/introduction.mdx index 342db04e3c..6898b67a4c 100644 --- a/site/docs/pages/framekit/introduction.mdx +++ b/site/docs/pages/framekit/introduction.mdx @@ -18,7 +18,6 @@ To assist you in engaging with Frames, here is the Frame Kit which includes: - Utilities: - [`getFrameHtmlResponse`](/framekit/get-frame-html-response) - [`getFrameMessage`](/framekit/get-frame-message) - - [`getXmtpFrameMessage`](/framekit/get-xmtp-frame-message) - [`getFrameMetadata`](/framekit/get-frame-metadata) - Emulator - [`framegear`](/framekit/framegear) diff --git a/site/docs/pages/index.mdx b/site/docs/pages/index.mdx index 9485cd32f7..a7c41907e9 100644 --- a/site/docs/pages/index.mdx +++ b/site/docs/pages/index.mdx @@ -87,15 +87,19 @@ OnchainKit offers three themes packed with React components and TypeScript utili - Utilities: - [`getFrameHtmlResponse`](/framekit/get-frame-html-response) - [`getFrameMessage`](/framekit/get-frame-message) - - [`getXmtpFrameMessage`](/framekit/get-xmtp-frame-message) - [`getFrameMetadata`](/framekit/get-frame-metadata) - [Framegear](/framekit/framegear) - [Identity Kit](/identitykit/introduction) + - Components: - [``](/identitykit/avatar) - [``](/identitykit/name) +- [XMTP Kit](/xmtpkit/introduction) + - Utilities: + - [`getXmtpFrameMessage`](/xmtpkit/get-xmtp-frame-message) + # Community Check out the following places for more OnchainKit-related content: diff --git a/site/docs/pages/framekit/get-xmtp-frame-message.mdx b/site/docs/pages/xmtpkit/get-xmtp-frame-message.mdx similarity index 91% rename from site/docs/pages/framekit/get-xmtp-frame-message.mdx rename to site/docs/pages/xmtpkit/get-xmtp-frame-message.mdx index 089d66d468..ea9e476c9c 100644 --- a/site/docs/pages/framekit/get-xmtp-frame-message.mdx +++ b/site/docs/pages/xmtpkit/get-xmtp-frame-message.mdx @@ -1,6 +1,8 @@ # getXmtpFrameMessage -Frames can receive interactions from apps outside of Farcaster, such as from XMTP conversations. When receiving these interactions you can expect a slightly different response format, since fields like `fid` or `castId` are not available. +Frames can receive interactions from apps outside of Farcaster, such as from XMTP conversations. +When receiving these interactions you can expect a slightly different response format, +since fields like `fid` or `castId` are not available. You can also use `getXmtpFrameMessage` to access useful information such as: @@ -42,7 +44,27 @@ export async function POST(req: NextRequest): Promise { } ``` -**@Param** +## Returns + +```ts +type Promise; + +type XmtpFrameValidationResponse = + | { isValid: true; message: XmtpFrameValidationData } + | { isValid: false; message: undefined }; + +interface FrameValidationData { + frameUrl: string; + buttonIndex: number; + timestamp: number; + identifier: string; + verifiedWalletAddress: string; + // Same as verifiedWalletAddress + identifier: string; +} +``` + +## Param ```ts export type UntrustedData = { @@ -63,25 +85,3 @@ export type XmtpFramesRequest = { }; }; ``` - -**@Returns** - -```ts -type Promise; - -type XmtpFrameValidationResponse = - | { isValid: true; message: XmtpFrameValidationData } - | { isValid: false; message: undefined }; - -interface FrameValidationData { - frameUrl: string; - buttonIndex: number; - timestamp: number; - identifier: string; - verifiedWalletAddress: string; - // Same as verifiedWalletAddress - identifier: string; -} -``` - -
diff --git a/site/docs/pages/xmtpkit/introduction.mdx b/site/docs/pages/xmtpkit/introduction.mdx new file mode 100644 index 0000000000..2f8921208f --- /dev/null +++ b/site/docs/pages/xmtpkit/introduction.mdx @@ -0,0 +1,14 @@ +--- +title: Introduction to XMTP Kit · OnchainKit +deescription: Introduction to XMTP Kit +--- + +# Introduction to XMTP Kit + +XMTP Kit is designed to be modular and flexible, allowing developers to use only the parts of the protocol that they need. + +To assist you in engaging with XMTP, here is the XMTP Kit which includes: + +- [XMTP Kit](/xmtpkit/introduction) + - Utilities: + - [`getXmtpFrameMessage`](/xmtpkit/get-xmtp-frame-message) diff --git a/site/docs/pages/xmtpkit/is-xmtp-frame-request.mdx b/site/docs/pages/xmtpkit/is-xmtp-frame-request.mdx new file mode 100644 index 0000000000..6691ba2f2c --- /dev/null +++ b/site/docs/pages/xmtpkit/is-xmtp-frame-request.mdx @@ -0,0 +1,3 @@ +# isXmtpFrameRequest + +isXmtpFrameRequest diff --git a/site/sidebar.ts b/site/sidebar.ts index 7c536be1cf..846225620e 100644 --- a/site/sidebar.ts +++ b/site/sidebar.ts @@ -90,4 +90,23 @@ export const sidebar = [ }, ], }, + { + text: 'XMTP Kit', + items: [ + { text: 'Introduction', link: '/xmtpkit/introduction' }, + { + text: 'Utilities', + items: [ + { + text: 'getXmtpFrameMessage', + link: '/xmtpkit/get-xmtp-frame-message', + }, + { + text: 'isXmtpFrameRequest', + link: '/xmtpkit/is-xmtp-frame-request', + }, + ], + }, + ], + }, ] as const satisfies Sidebar; diff --git a/src/core/index.ts b/src/core/index.ts new file mode 100644 index 0000000000..f5376de2df --- /dev/null +++ b/src/core/index.ts @@ -0,0 +1,17 @@ +// 🌲☀️🌲 +export { getEASAttestations } from './getEASAttestations'; +export { getFrameHtmlResponse } from './getFrameHtmlResponse'; +export { getFrameMetadata } from './getFrameMetadata'; +export { getFrameMessage } from './getFrameMessage'; +export { getMockFrameRequest } from './getMockFrameRequest'; +export type { + FrameButtonMetadata, + FrameImageMetadata, + FrameInputMetadata, + FrameMetadataReact, + FrameMetadataType, + FrameRequest, + FrameValidationData, + MockFrameRequest, + MockFrameRequestOptions, +} from './types'; diff --git a/src/xmtp/validation.test.ts b/src/xmtp/getXmtpFrameMessage.test.ts similarity index 76% rename from src/xmtp/validation.test.ts rename to src/xmtp/getXmtpFrameMessage.test.ts index 5c8490d1bf..49d860bcd3 100644 --- a/src/xmtp/validation.test.ts +++ b/src/xmtp/getXmtpFrameMessage.test.ts @@ -1,4 +1,4 @@ -import { getXmtpFrameMessage, isXmtpFrameRequest } from './validation'; +import { getXmtpFrameMessage } from './getXmtpFrameMessage'; const FIXTURES = { valid: { @@ -58,42 +58,3 @@ describe('xmtp validation', () => { expect(invalidResult.message).toBeUndefined(); }); }); - -describe('isXmtpFrameRequest', () => { - it('should return true for requests with the correct client protocol', () => { - expect( - isXmtpFrameRequest({ - clientProtocol: 'xmtp@2024-02-09', - untrustedData: {}, - trustedData: {}, - }), - ).toBe(true); - }); - - it('should return false for farcaster requests', () => { - expect( - isXmtpFrameRequest({ - untrustedData: {}, - trustedData: {}, - }), - ).toBe(false); - }); - - it('should return false for other client protocols', () => { - expect( - isXmtpFrameRequest({ - clientProtocol: 'lens@v1', - untrustedData: {}, - trustedData: {}, - }), - ); - }); - - it('should return false for malformed requests', () => { - expect( - isXmtpFrameRequest({ - clientProtocol: 'xmtp@2024-02-09', - }), - ).toBe(false); - }); -}); diff --git a/src/xmtp/validation.ts b/src/xmtp/getXmtpFrameMessage.ts similarity index 76% rename from src/xmtp/validation.ts rename to src/xmtp/getXmtpFrameMessage.ts index 9b519379b0..b93b600034 100644 --- a/src/xmtp/validation.ts +++ b/src/xmtp/getXmtpFrameMessage.ts @@ -26,12 +26,3 @@ export async function getXmtpFrameMessage(payload: XmtpOpenFramesRequest) { }; } } - -export function isXmtpFrameRequest(payload: any): payload is XmtpOpenFramesRequest { - return ( - !!payload && - !!payload.untrustedData && - !!payload.trustedData && - !!payload.clientProtocol?.startsWith('xmtp@') - ); -} diff --git a/src/xmtp/index.ts b/src/xmtp/index.ts index b5c7da6be2..316a58e555 100644 --- a/src/xmtp/index.ts +++ b/src/xmtp/index.ts @@ -1 +1,2 @@ -export { getXmtpFrameMessage, isXmtpFrameRequest } from './validation'; +export { getXmtpFrameMessage } from './getXmtpFrameMessage'; +export { isXmtpFrameRequest } from './isXmtpFrameRequest'; diff --git a/src/xmtp/isXmtpFrameRequest.test.ts b/src/xmtp/isXmtpFrameRequest.test.ts new file mode 100644 index 0000000000..e5c973f011 --- /dev/null +++ b/src/xmtp/isXmtpFrameRequest.test.ts @@ -0,0 +1,40 @@ +import { isXmtpFrameRequest } from './isXmtpFrameRequest'; + +describe('isXmtpFrameRequest', () => { + it('should return true for requests with the correct client protocol', () => { + expect( + isXmtpFrameRequest({ + clientProtocol: 'xmtp@2024-02-09', + untrustedData: {}, + trustedData: {}, + }), + ).toBe(true); + }); + + it('should return false for farcaster requests', () => { + expect( + isXmtpFrameRequest({ + untrustedData: {}, + trustedData: {}, + }), + ).toBe(false); + }); + + it('should return false for other client protocols', () => { + expect( + isXmtpFrameRequest({ + clientProtocol: 'lens@v1', + untrustedData: {}, + trustedData: {}, + }), + ); + }); + + it('should return false for malformed requests', () => { + expect( + isXmtpFrameRequest({ + clientProtocol: 'xmtp@2024-02-09', + }), + ).toBe(false); + }); +}); diff --git a/src/xmtp/isXmtpFrameRequest.ts b/src/xmtp/isXmtpFrameRequest.ts new file mode 100644 index 0000000000..00cbd4cba0 --- /dev/null +++ b/src/xmtp/isXmtpFrameRequest.ts @@ -0,0 +1,10 @@ +import { XmtpOpenFramesRequest } from '@xmtp/frames-validator'; + +export function isXmtpFrameRequest(payload: any): payload is XmtpOpenFramesRequest { + return ( + !!payload && + !!payload.untrustedData && + !!payload.trustedData && + !!payload.clientProtocol?.startsWith('xmtp@') + ); +}