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@')
+ );
+}