@farcaster/frame-host-react-native 0.0.53 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@farcaster/frame-host-react-native",
3
- "version": "0.0.53",
3
+ "version": "0.1.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "https://github.com/farcasterxyz/frames.git",
7
+ "url": "https://github.com/farcasterxyz/miniapps.git",
8
8
  "directory": "packages/frame-host-react-native"
9
9
  },
10
10
  "main": "dist/index.js",
@@ -18,7 +18,7 @@
18
18
  "react-native": "^0.76.5",
19
19
  "react-native-webview": "^13.13.5",
20
20
  "typescript": "^5.8.3",
21
- "@farcaster/tsconfig": "0.0.5"
21
+ "@farcaster/tsconfig": "0.1.0"
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": ">=18.0.0",
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "ox": "^0.4.4",
29
- "@farcaster/frame-host": "0.0.53"
29
+ "@farcaster/miniapp-host-react-native": "0.1.0"
30
30
  },
31
31
  "scripts": {
32
32
  "clean": "rm -rf dist",
package/src/index.ts CHANGED
@@ -1,3 +1,10 @@
1
- export * from '@farcaster/frame-host'
2
- export * from './webview.ts'
3
- export * from './webviewAdapter.ts'
1
+ // Deprecation warning
2
+ if (typeof console !== 'undefined' && console.warn) {
3
+ console.warn(
4
+ '[DEPRECATION WARNING] @farcaster/frame-host-react-native is deprecated. Please migrate to @farcaster/miniapp-host-react-native. ' +
5
+ 'See https://github.com/farcasterxyz/frames/blob/main/MIGRATION.md for migration guide.',
6
+ )
7
+ }
8
+
9
+ // Re-export everything from miniapp-host-react-native
10
+ export * from '@farcaster/miniapp-host-react-native'
package/dist/webview.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import type { HostEndpoint } from '@farcaster/frame-host';
2
- import type { RefObject } from 'react';
3
- import type WebView from 'react-native-webview';
4
- import type { WebViewMessageEvent } from 'react-native-webview';
5
- export declare const SYMBOL_IGNORING_RPC_RESPONSE_ERROR: symbol;
6
- export type WebViewEndpoint = HostEndpoint & {
7
- /**
8
- * Manually distribute events to listeners as an alternative to `document.addEventHandler` which is unavailable in React Native.
9
- */
10
- onMessage: (e: WebViewMessageEvent) => void;
11
- };
12
- /**
13
- * An endpoint of communicating with WebView
14
- */
15
- export declare function createWebViewRpcEndpoint(ref: RefObject<WebView | null>, domain: string): WebViewEndpoint;
package/dist/webview.js DELETED
@@ -1,103 +0,0 @@
1
- export const SYMBOL_IGNORING_RPC_RESPONSE_ERROR = Symbol();
2
- /**
3
- * An endpoint of communicating with WebView
4
- */
5
- export function createWebViewRpcEndpoint(ref, domain) {
6
- const listeners = [];
7
- return {
8
- addEventListener: (type, listener) => {
9
- if (type !== 'message') {
10
- throw Error(`Got an unexpected event type "${type}". Expected "message".`);
11
- }
12
- listeners.push(listener);
13
- },
14
- removeEventListener: (type, listener) => {
15
- if (type !== 'message') {
16
- throw Error(`Got an unexpected event type "${type}". Expected "message".`);
17
- }
18
- listeners.splice(listeners.findIndex((l) => l === listener));
19
- },
20
- postMessage: (data) => {
21
- if (!ref.current) {
22
- if ('value' in data &&
23
- data.value === SYMBOL_IGNORING_RPC_RESPONSE_ERROR) {
24
- return;
25
- }
26
- throw Error('Failed to return RPC response to WebView via postMessage');
27
- }
28
- console.debug('[webview:res]', data);
29
- const dataStr = JSON.stringify(data);
30
- return ref.current.injectJavaScript(`
31
- if (location.origin === 'https://${domain}' || location.origin === 'https://www.${domain}') {
32
- console.debug('[webview:res]', ${dataStr});
33
- document.dispatchEvent(new MessageEvent('FarcasterFrameCallback', { data: ${dataStr} }));
34
- } else {
35
- console.debug('[webview:emit]', 'invalid origin, ignoring')
36
- }
37
- `);
38
- },
39
- onMessage: (e) => {
40
- const originDomain = new URL(e.nativeEvent.url).hostname;
41
- const allowedDomains = [domain, `www.${domain}`];
42
- if (!allowedDomains.includes(originDomain)) {
43
- console.warn('Invalid message domain, ignoring');
44
- return;
45
- }
46
- const data = JSON.parse(e.nativeEvent.data);
47
- console.debug('[webview:req]', data);
48
- const messageEvent = new MessageEvent(data);
49
- for (const l of listeners) {
50
- if (typeof l === 'function') {
51
- // Actually, messageEvent doesn't satisfy Event interface,
52
- // but it satisfies the minimum properties that Comlink's listener requires.
53
- l(messageEvent);
54
- }
55
- else {
56
- l.handleEvent(messageEvent);
57
- }
58
- }
59
- },
60
- emit: (data) => {
61
- if (!ref.current) {
62
- throw Error('Failed to send Event to WebView via postMessage');
63
- }
64
- console.debug('[webview:emit]', data);
65
- const dataStr = JSON.stringify(data);
66
- return ref.current.injectJavaScript(`
67
- if (location.origin === 'https://${domain}' || location.origin === 'https://www.${domain}') {
68
- console.debug('[webview:emit]', ${dataStr});
69
- document.dispatchEvent(new MessageEvent('FarcasterFrameEvent', { data: ${dataStr} }));
70
- } else {
71
- console.debug('[webview:emit]', 'invalid origin, ignoring')
72
- }
73
- `);
74
- },
75
- emitEthProvider: (event, params) => {
76
- if (!ref.current) {
77
- throw Error('Failed to send EthProvider Event to WebView via postMessage');
78
- }
79
- console.debug('[emit:ethProvider]', event, params);
80
- const wireEvent = { event, params };
81
- const dataStr = JSON.stringify(wireEvent);
82
- return ref.current.injectJavaScript(`
83
- if (location.origin === 'https://${domain}' || location.origin === 'https://www.${domain}') {
84
- console.debug('[webview:emit:ethProvider]', ${dataStr});
85
- document.dispatchEvent(new MessageEvent('FarcasterFrameEthProviderEvent', { data: ${dataStr} }));
86
- } else {
87
- console.debug('[webview:emit:ethProvider]', 'invalid origin, ignoring')
88
- }
89
- `);
90
- },
91
- };
92
- }
93
- /**
94
- * Standard MessageEvent is unavailable in React Native since it's part of HTML Standard.
95
- * Instead, implement our own MessageEvent with the minimum properties required by Comlink implementation.
96
- */
97
- class MessageEvent {
98
- data;
99
- origin = 'ReactNativeWebView';
100
- constructor(data) {
101
- this.data = data;
102
- }
103
- }
@@ -1,30 +0,0 @@
1
- import type { FrameHost } from '@farcaster/frame-host';
2
- import type { Provider } from 'ox/Provider';
3
- import { type RefObject } from 'react';
4
- import type WebView from 'react-native-webview';
5
- import type { WebViewMessageEvent } from 'react-native-webview';
6
- import { type WebViewEndpoint } from './webview.ts';
7
- /**
8
- * Returns a handler of RPC message from WebView.
9
- */
10
- export declare function useWebViewRpcAdapter({ webViewRef, domain, sdk, ethProvider, debug, }: {
11
- webViewRef: RefObject<WebView>;
12
- domain: string;
13
- sdk: Omit<FrameHost, 'ethProviderRequestV2'>;
14
- ethProvider?: Provider;
15
- debug?: boolean;
16
- }): {
17
- onMessage: (event: WebViewMessageEvent) => void;
18
- emit: ((event: import("@farcaster/frame-core").FrameClientEvent) => void) | undefined;
19
- emitEthProvider: import("@farcaster/frame-core").EmitEthProvider | undefined;
20
- };
21
- export declare function useWebViewRpcEndpoint(webViewRef: RefObject<WebView | null>, domain: string): {
22
- endpoint: WebViewEndpoint | undefined;
23
- onMessage: (event: WebViewMessageEvent) => void;
24
- };
25
- export declare function useExposeWebViewToEndpoint({ endpoint, sdk, ethProvider, debug, }: {
26
- endpoint: WebViewEndpoint | undefined;
27
- sdk: Omit<FrameHost, 'ethProviderRequestV2'>;
28
- ethProvider?: Provider;
29
- debug?: boolean;
30
- }): void;
@@ -1,58 +0,0 @@
1
- import { exposeToEndpoint, useExposeToEndpoint } from '@farcaster/frame-host';
2
- import { useCallback, useEffect, useMemo, useState, } from 'react';
3
- import { createWebViewRpcEndpoint } from "./webview.js";
4
- /**
5
- * Returns a handler of RPC message from WebView.
6
- */
7
- export function useWebViewRpcAdapter({ webViewRef, domain, sdk, ethProvider, debug = false, }) {
8
- const [endpoint, setEndpoint] = useState();
9
- const onMessage = useCallback((e) => {
10
- endpoint?.onMessage(e);
11
- }, [endpoint]);
12
- useEffect(() => {
13
- const newEndpoint = createWebViewRpcEndpoint(webViewRef, domain);
14
- setEndpoint(newEndpoint);
15
- const cleanup = exposeToEndpoint({
16
- endpoint: newEndpoint,
17
- sdk,
18
- ethProvider,
19
- frameOrigin: 'ReactNativeWebView',
20
- debug,
21
- });
22
- return () => {
23
- cleanup?.();
24
- setEndpoint(undefined);
25
- };
26
- }, [webViewRef, domain, sdk, ethProvider, debug]);
27
- return useMemo(() => ({
28
- onMessage,
29
- emit: endpoint?.emit,
30
- emitEthProvider: endpoint?.emitEthProvider,
31
- }), [onMessage, endpoint]);
32
- }
33
- export function useWebViewRpcEndpoint(webViewRef, domain) {
34
- const [endpoint, setEndpoint] = useState();
35
- const onMessage = useCallback((e) => {
36
- endpoint?.onMessage(e);
37
- }, [endpoint]);
38
- useEffect(() => {
39
- const newEndpoint = createWebViewRpcEndpoint(webViewRef, domain);
40
- setEndpoint(newEndpoint);
41
- return () => {
42
- setEndpoint(undefined);
43
- };
44
- }, [webViewRef, domain]);
45
- return useMemo(() => ({
46
- endpoint,
47
- onMessage,
48
- }), [endpoint, onMessage]);
49
- }
50
- export function useExposeWebViewToEndpoint({ endpoint, sdk, ethProvider, debug = false, }) {
51
- useExposeToEndpoint({
52
- endpoint,
53
- sdk,
54
- frameOrigin: 'ReactNativeWebView',
55
- ethProvider,
56
- debug,
57
- });
58
- }
package/src/webview.ts DELETED
@@ -1,126 +0,0 @@
1
- import type { HostEndpoint } from '@farcaster/frame-host'
2
-
3
- import type { RefObject } from 'react'
4
- import type WebView from 'react-native-webview'
5
- import type { WebViewMessageEvent } from 'react-native-webview'
6
-
7
- export const SYMBOL_IGNORING_RPC_RESPONSE_ERROR: symbol = Symbol()
8
-
9
- export type WebViewEndpoint = HostEndpoint & {
10
- /**
11
- * Manually distribute events to listeners as an alternative to `document.addEventHandler` which is unavailable in React Native.
12
- */
13
- onMessage: (e: WebViewMessageEvent) => void
14
- }
15
-
16
- /**
17
- * An endpoint of communicating with WebView
18
- */
19
- export function createWebViewRpcEndpoint(
20
- ref: RefObject<WebView | null>,
21
- domain: string,
22
- ): WebViewEndpoint {
23
- const listeners: EventListenerOrEventListenerObject[] = []
24
- return {
25
- addEventListener: (type, listener) => {
26
- if (type !== 'message') {
27
- throw Error(
28
- `Got an unexpected event type "${type}". Expected "message".`,
29
- )
30
- }
31
- listeners.push(listener)
32
- },
33
- removeEventListener: (type, listener) => {
34
- if (type !== 'message') {
35
- throw Error(
36
- `Got an unexpected event type "${type}". Expected "message".`,
37
- )
38
- }
39
- listeners.splice(listeners.findIndex((l) => l === listener))
40
- },
41
- postMessage: (data) => {
42
- if (!ref.current) {
43
- if (
44
- 'value' in data &&
45
- data.value === SYMBOL_IGNORING_RPC_RESPONSE_ERROR
46
- ) {
47
- return
48
- }
49
- throw Error('Failed to return RPC response to WebView via postMessage')
50
- }
51
- console.debug('[webview:res]', data)
52
- const dataStr = JSON.stringify(data)
53
- return ref.current.injectJavaScript(`
54
- if (location.origin === 'https://${domain}' || location.origin === 'https://www.${domain}') {
55
- console.debug('[webview:res]', ${dataStr});
56
- document.dispatchEvent(new MessageEvent('FarcasterFrameCallback', { data: ${dataStr} }));
57
- } else {
58
- console.debug('[webview:emit]', 'invalid origin, ignoring')
59
- }
60
- `)
61
- },
62
- onMessage: (e) => {
63
- const originDomain = new URL(e.nativeEvent.url).hostname
64
- const allowedDomains = [domain, `www.${domain}`]
65
- if (!allowedDomains.includes(originDomain)) {
66
- console.warn('Invalid message domain, ignoring')
67
- return
68
- }
69
-
70
- const data = JSON.parse(e.nativeEvent.data)
71
- console.debug('[webview:req]', data)
72
- const messageEvent = new MessageEvent(data)
73
- for (const l of listeners) {
74
- if (typeof l === 'function') {
75
- // Actually, messageEvent doesn't satisfy Event interface,
76
- // but it satisfies the minimum properties that Comlink's listener requires.
77
- l(messageEvent as unknown as Event)
78
- } else {
79
- l.handleEvent(messageEvent as unknown as Event)
80
- }
81
- }
82
- },
83
- emit: (data) => {
84
- if (!ref.current) {
85
- throw Error('Failed to send Event to WebView via postMessage')
86
- }
87
- console.debug('[webview:emit]', data)
88
- const dataStr = JSON.stringify(data)
89
- return ref.current.injectJavaScript(`
90
- if (location.origin === 'https://${domain}' || location.origin === 'https://www.${domain}') {
91
- console.debug('[webview:emit]', ${dataStr});
92
- document.dispatchEvent(new MessageEvent('FarcasterFrameEvent', { data: ${dataStr} }));
93
- } else {
94
- console.debug('[webview:emit]', 'invalid origin, ignoring')
95
- }
96
- `)
97
- },
98
- emitEthProvider: (event, params) => {
99
- if (!ref.current) {
100
- throw Error(
101
- 'Failed to send EthProvider Event to WebView via postMessage',
102
- )
103
- }
104
- console.debug('[emit:ethProvider]', event, params)
105
- const wireEvent = { event, params }
106
- const dataStr = JSON.stringify(wireEvent)
107
- return ref.current.injectJavaScript(`
108
- if (location.origin === 'https://${domain}' || location.origin === 'https://www.${domain}') {
109
- console.debug('[webview:emit:ethProvider]', ${dataStr});
110
- document.dispatchEvent(new MessageEvent('FarcasterFrameEthProviderEvent', { data: ${dataStr} }));
111
- } else {
112
- console.debug('[webview:emit:ethProvider]', 'invalid origin, ignoring')
113
- }
114
- `)
115
- },
116
- }
117
- }
118
-
119
- /**
120
- * Standard MessageEvent is unavailable in React Native since it's part of HTML Standard.
121
- * Instead, implement our own MessageEvent with the minimum properties required by Comlink implementation.
122
- */
123
- class MessageEvent {
124
- public origin = 'ReactNativeWebView'
125
- constructor(public data: unknown) {}
126
- }
@@ -1,117 +0,0 @@
1
- import type { FrameHost } from '@farcaster/frame-host'
2
- import { exposeToEndpoint, useExposeToEndpoint } from '@farcaster/frame-host'
3
- import type { Provider } from 'ox/Provider'
4
- import {
5
- type RefObject,
6
- useCallback,
7
- useEffect,
8
- useMemo,
9
- useState,
10
- } from 'react'
11
- import type WebView from 'react-native-webview'
12
- import type { WebViewMessageEvent, WebViewProps } from 'react-native-webview'
13
- import { type WebViewEndpoint, createWebViewRpcEndpoint } from './webview.ts'
14
-
15
- /**
16
- * Returns a handler of RPC message from WebView.
17
- */
18
- export function useWebViewRpcAdapter({
19
- webViewRef,
20
- domain,
21
- sdk,
22
- ethProvider,
23
- debug = false,
24
- }: {
25
- webViewRef: RefObject<WebView>
26
- domain: string
27
- sdk: Omit<FrameHost, 'ethProviderRequestV2'>
28
- ethProvider?: Provider
29
- debug?: boolean
30
- }) {
31
- const [endpoint, setEndpoint] = useState<WebViewEndpoint>()
32
-
33
- const onMessage: WebViewProps['onMessage'] = useCallback(
34
- (e: WebViewMessageEvent) => {
35
- endpoint?.onMessage(e)
36
- },
37
- [endpoint],
38
- )
39
-
40
- useEffect(() => {
41
- const newEndpoint = createWebViewRpcEndpoint(webViewRef, domain)
42
- setEndpoint(newEndpoint)
43
-
44
- const cleanup = exposeToEndpoint({
45
- endpoint: newEndpoint,
46
- sdk,
47
- ethProvider,
48
- frameOrigin: 'ReactNativeWebView',
49
- debug,
50
- })
51
-
52
- return () => {
53
- cleanup?.()
54
- setEndpoint(undefined)
55
- }
56
- }, [webViewRef, domain, sdk, ethProvider, debug])
57
-
58
- return useMemo(
59
- () => ({
60
- onMessage,
61
- emit: endpoint?.emit,
62
- emitEthProvider: endpoint?.emitEthProvider,
63
- }),
64
- [onMessage, endpoint],
65
- )
66
- }
67
-
68
- export function useWebViewRpcEndpoint(
69
- webViewRef: RefObject<WebView | null>,
70
- domain: string,
71
- ) {
72
- const [endpoint, setEndpoint] = useState<WebViewEndpoint>()
73
-
74
- const onMessage: WebViewProps['onMessage'] = useCallback(
75
- (e: WebViewMessageEvent) => {
76
- endpoint?.onMessage(e)
77
- },
78
- [endpoint],
79
- )
80
-
81
- useEffect(() => {
82
- const newEndpoint = createWebViewRpcEndpoint(webViewRef, domain)
83
- setEndpoint(newEndpoint)
84
-
85
- return () => {
86
- setEndpoint(undefined)
87
- }
88
- }, [webViewRef, domain])
89
-
90
- return useMemo(
91
- () => ({
92
- endpoint,
93
- onMessage,
94
- }),
95
- [endpoint, onMessage],
96
- )
97
- }
98
-
99
- export function useExposeWebViewToEndpoint({
100
- endpoint,
101
- sdk,
102
- ethProvider,
103
- debug = false,
104
- }: {
105
- endpoint: WebViewEndpoint | undefined
106
- sdk: Omit<FrameHost, 'ethProviderRequestV2'>
107
- ethProvider?: Provider
108
- debug?: boolean
109
- }) {
110
- useExposeToEndpoint({
111
- endpoint,
112
- sdk,
113
- frameOrigin: 'ReactNativeWebView',
114
- ethProvider,
115
- debug,
116
- })
117
- }