@farcaster/frame-sdk 0.0.22 → 0.0.24

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/dist/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import type { EventEmitter } from "eventemitter3";
2
- import type { Provider } from "ox";
3
- import type { FrameContext, AddFrame, ReadyOptions, SignIn, FrameNotificationDetails, AddFrameRejectedReason } from "@farcaster/frame-core";
1
+ import type { AddFrame, FrameContext, FrameNotificationDetails, ReadyOptions, SetPrimaryButtonOptions, SignIn } from '@farcaster/frame-core';
2
+ import type { EventEmitter } from 'eventemitter3';
3
+ import type { Provider } from 'ox';
4
4
  declare global {
5
5
  interface Window {
6
6
  ReactNativeWebView: {
@@ -9,7 +9,7 @@ declare global {
9
9
  }
10
10
  }
11
11
  /** Combines members of an intersection into a readable type. */
12
- export type Compute<type> = {
12
+ type Compute<type> = {
13
13
  [key in keyof type]: type[key];
14
14
  } & unknown;
15
15
  export type EventMap = {
@@ -17,8 +17,8 @@ export type EventMap = {
17
17
  frameAdded: ({ notificationDetails, }: {
18
18
  notificationDetails?: FrameNotificationDetails;
19
19
  }) => void;
20
- frameAddRejected: ({ reason }: {
21
- reason: AddFrameRejectedReason;
20
+ frameAddRejected: ({ reason, }: {
21
+ reason: AddFrame.AddFrameRejectedReason;
22
22
  }) => void;
23
23
  frameRemoved: () => void;
24
24
  notificationsEnabled: ({ notificationDetails, }: {
@@ -27,12 +27,7 @@ export type EventMap = {
27
27
  notificationsDisabled: () => void;
28
28
  };
29
29
  export type Emitter = Compute<EventEmitter<EventMap>>;
30
- export type SetPrimaryButton = (options: {
31
- text: string;
32
- loading?: boolean;
33
- disabled?: boolean;
34
- hidden?: boolean;
35
- }) => Promise<void>;
30
+ type SetPrimaryButton = (options: SetPrimaryButtonOptions) => Promise<void>;
36
31
  export type FrameSDK = {
37
32
  context: Promise<FrameContext>;
38
33
  actions: {
@@ -41,9 +36,10 @@ export type FrameSDK = {
41
36
  signIn: SignIn.SignIn;
42
37
  close: () => Promise<void>;
43
38
  setPrimaryButton: SetPrimaryButton;
44
- addFrame: AddFrame;
39
+ addFrame: AddFrame.AddFrame;
45
40
  };
46
41
  wallet: {
47
42
  ethProvider: Provider.Provider;
48
43
  };
49
44
  } & Emitter;
45
+ export {};
package/package.json CHANGED
@@ -1,21 +1,22 @@
1
1
  {
2
2
  "name": "@farcaster/frame-sdk",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "main": "dist/index.js",
5
5
  "files": [
6
6
  "dist",
7
7
  "src"
8
8
  ],
9
9
  "devDependencies": {
10
- "esbuild": "^0.24.0",
11
- "typescript": "^5.6.3",
10
+ "esbuild": "^0.24.2",
11
+ "mipd": "^0.0.7",
12
+ "typescript": "^5.7.2",
12
13
  "@farcaster/tsconfig": "0.0.2"
13
14
  },
14
15
  "dependencies": {
15
16
  "comlink": "^4.4.2",
16
17
  "eventemitter3": "^5.0.1",
17
- "ox": "^0.4.0",
18
- "@farcaster/frame-core": "0.0.21"
18
+ "ox": "^0.4.4",
19
+ "@farcaster/frame-core": "0.0.22"
19
20
  },
20
21
  "scripts": {
21
22
  "clean": "rm -rf dist",
package/src/endpoint.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type Endpoint, windowEndpoint } from "comlink";
1
+ import { type Endpoint, windowEndpoint } from 'comlink'
2
2
 
3
3
  const mockEndpoint: Endpoint = {
4
4
  postMessage() {
@@ -10,25 +10,25 @@ const mockEndpoint: Endpoint = {
10
10
  removeEventListener: () => {
11
11
  // noop
12
12
  },
13
- };
13
+ }
14
14
 
15
15
  const webViewEndpoint: Endpoint = {
16
16
  postMessage: (data: unknown) => {
17
- console.debug("[webview:req]", data);
18
- window.ReactNativeWebView.postMessage(JSON.stringify(data));
17
+ console.debug('[webview:req]', data)
18
+ window.ReactNativeWebView.postMessage(JSON.stringify(data))
19
19
  },
20
20
  addEventListener: (_, listener, ...args) => {
21
- document.addEventListener("FarcasterFrameCallback", listener, ...args);
21
+ document.addEventListener('FarcasterFrameCallback', listener, ...args)
22
22
  },
23
23
  removeEventListener: (_, listener) => {
24
- document.removeEventListener("FarcasterFrameCallback", listener);
24
+ document.removeEventListener('FarcasterFrameCallback', listener)
25
25
  },
26
- };
26
+ }
27
27
 
28
28
  export const endpoint = (() => {
29
29
  // No actions are actually gonna take place during SSR, thus it's safe to return mocked endpoint
30
- if (typeof window === "undefined") return mockEndpoint;
30
+ if (typeof window === 'undefined') return mockEndpoint
31
31
  return window?.ReactNativeWebView
32
32
  ? webViewEndpoint
33
- : windowEndpoint(window?.parent ?? window);
34
- })();
33
+ : windowEndpoint(window?.parent ?? window)
34
+ })()
package/src/frameHost.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { wrap } from "comlink";
2
- import { endpoint } from "./endpoint";
3
- import { WireFrameHost } from "@farcaster/frame-core";
1
+ import type { WireFrameHost } from '@farcaster/frame-core'
2
+ import { wrap } from 'comlink'
3
+ import { endpoint } from './endpoint'
4
4
 
5
- export const frameHost = wrap<WireFrameHost>(endpoint);
5
+ export const frameHost = wrap<WireFrameHost>(endpoint)
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { sdk } from "./sdk";
1
+ import { sdk } from './sdk'
2
2
 
3
- export * from "./sdk";
4
- export * from "@farcaster/frame-core";
3
+ export * from './sdk'
4
+ export * from '@farcaster/frame-core'
5
5
 
6
- export default sdk;
6
+ export default sdk
package/src/provider.ts CHANGED
@@ -1,35 +1,44 @@
1
- import { Provider, RpcRequest, RpcResponse } from "ox";
2
- import { frameHost } from "./frameHost";
3
- import { EthProviderWireEvent } from "@farcaster/frame-core";
1
+ import type {
2
+ EthProviderWireEvent,
3
+ FrameClientEvent,
4
+ } from '@farcaster/frame-core'
5
+ import type {
6
+ AnnounceProviderParameters,
7
+ AnnounceProviderReturnType,
8
+ EIP1193Provider,
9
+ EIP6963ProviderDetail,
10
+ } from 'mipd'
11
+ import { Provider, RpcRequest, RpcResponse } from 'ox'
12
+ import { frameHost } from './frameHost'
4
13
 
5
- const emitter = Provider.createEmitter();
6
- const store = RpcRequest.createStore();
14
+ const emitter = Provider.createEmitter()
15
+ const store = RpcRequest.createStore()
7
16
 
8
17
  type GenericProviderRpcError = {
9
- code: number;
10
- details?: string;
11
- };
18
+ code: number
19
+ details?: string
20
+ }
12
21
 
13
- export function toProviderRpcError({
22
+ function toProviderRpcError({
14
23
  code,
15
24
  details,
16
25
  }: GenericProviderRpcError): Provider.ProviderRpcError {
17
26
  switch (code) {
18
27
  case 4001:
19
- return new Provider.UserRejectedRequestError();
28
+ return new Provider.UserRejectedRequestError()
20
29
  case 4100:
21
- return new Provider.UnauthorizedError();
30
+ return new Provider.UnauthorizedError()
22
31
  case 4200:
23
- return new Provider.UnsupportedMethodError();
32
+ return new Provider.UnsupportedMethodError()
24
33
  case 4900:
25
- return new Provider.DisconnectedError();
34
+ return new Provider.DisconnectedError()
26
35
  case 4901:
27
- return new Provider.ChainDisconnectedError();
36
+ return new Provider.ChainDisconnectedError()
28
37
  default:
29
38
  return new Provider.ProviderRpcError(
30
39
  code,
31
- details ?? "Unknown provider RPC error",
32
- );
40
+ details ?? 'Unknown provider RPC error',
41
+ )
33
42
  }
34
43
  }
35
44
 
@@ -37,63 +46,114 @@ export const provider: Provider.Provider = Provider.from({
37
46
  ...emitter,
38
47
  async request(args) {
39
48
  // @ts-expect-error
40
- const request = store.prepare(args);
49
+ const request = store.prepare(args)
41
50
 
42
51
  try {
43
52
  const response = await frameHost
44
53
  .ethProviderRequestV2(request)
45
- .then((res) => RpcResponse.parse(res, { request, raw: true }));
54
+ .then((res) => RpcResponse.parse(res, { request, raw: true }))
46
55
 
47
56
  if (response.error) {
48
- throw toProviderRpcError(response.error);
57
+ throw toProviderRpcError(response.error)
49
58
  }
50
59
 
51
- return response.result;
60
+ return response.result
52
61
  } catch (e) {
53
62
  // ethProviderRequestV2 not supported, fall back to v1
54
63
  if (
55
64
  e instanceof Error &&
56
65
  e.message.match(/cannot read property 'apply'/i)
57
66
  ) {
58
- return await frameHost.ethProviderRequest(request);
67
+ return await frameHost.ethProviderRequest(request)
59
68
  }
60
69
 
61
70
  if (
62
71
  e instanceof Provider.ProviderRpcError ||
63
72
  e instanceof RpcResponse.BaseError
64
73
  ) {
65
- throw e;
74
+ throw e
66
75
  }
67
76
 
68
77
  throw new RpcResponse.InternalError({
69
78
  message: e instanceof Error ? e.message : undefined,
70
- });
79
+ })
71
80
  }
72
81
  },
73
- });
82
+ })
83
+
84
+ function announceProvider(
85
+ detail: AnnounceProviderParameters,
86
+ ): AnnounceProviderReturnType {
87
+ const event: CustomEvent<EIP6963ProviderDetail> = new CustomEvent(
88
+ 'eip6963:announceProvider',
89
+ { detail: Object.freeze(detail) },
90
+ )
91
+
92
+ window.dispatchEvent(event)
93
+
94
+ const handler = () => window.dispatchEvent(event)
95
+ window.addEventListener('eip6963:requestProvider', handler)
96
+ return () => window.removeEventListener('eip6963:requestProvider', handler)
97
+ }
74
98
 
75
99
  // Required to pass SSR
76
- if (typeof document !== "undefined") {
100
+ if (typeof document !== 'undefined') {
101
+ // forward eip6963:requestProvider events to the host
102
+ document.addEventListener('eip6963:requestProvider', () => {
103
+ frameHost.eip6963RequestProvider()
104
+ })
105
+
77
106
  // react native webview events
78
- document.addEventListener("FarcasterFrameEthProviderEvent", (event) => {
107
+ document.addEventListener('FarcasterFrameEthProviderEvent', (event) => {
79
108
  if (event instanceof MessageEvent) {
80
- const ethProviderEvent = event.data as EthProviderWireEvent;
109
+ const ethProviderEvent = event.data as EthProviderWireEvent
81
110
  // @ts-expect-error
82
- emitter.emit(ethProviderEvent.event, ...ethProviderEvent.params);
111
+ emitter.emit(ethProviderEvent.event, ...ethProviderEvent.params)
83
112
  }
84
- });
113
+ })
114
+
115
+ document.addEventListener('FarcasterFrameEvent', (event) => {
116
+ if (event instanceof MessageEvent) {
117
+ const frameEvent = event.data as FrameClientEvent
118
+ if (frameEvent.event === 'eip6963:announceProvider') {
119
+ announceProvider({
120
+ info: frameEvent.info,
121
+ provider: provider as EIP1193Provider,
122
+ })
123
+ }
124
+ }
125
+ })
85
126
  }
86
127
 
87
128
  // Required to pass SSR
88
- if (typeof window !== "undefined") {
129
+ if (typeof window !== 'undefined') {
130
+ // forward eip6963:requestProvider events to the host
131
+ window.addEventListener('eip6963:requestProvider', () => {
132
+ frameHost.eip6963RequestProvider()
133
+ })
134
+
89
135
  // web events
90
- window.addEventListener("message", (event) => {
136
+ window.addEventListener('message', (event) => {
91
137
  if (event instanceof MessageEvent) {
92
- if (event.data.type === "frameEthProviderEvent") {
93
- const ethProviderEvent = event.data as EthProviderWireEvent;
138
+ if (event.data.type === 'frameEthProviderEvent') {
139
+ const ethProviderEvent = event.data as EthProviderWireEvent
94
140
  // @ts-expect-error
95
- emitter.emit(ethProviderEvent.event, ...ethProviderEvent.params);
141
+ emitter.emit(ethProviderEvent.event, ...ethProviderEvent.params)
142
+ }
143
+ }
144
+ })
145
+
146
+ window.addEventListener('message', (event) => {
147
+ if (event instanceof MessageEvent) {
148
+ if (event.data.type === 'frameEvent') {
149
+ const frameEvent = event.data.event as FrameClientEvent
150
+ if (frameEvent.event === 'eip6963:announceProvider') {
151
+ announceProvider({
152
+ info: frameEvent.info,
153
+ provider: provider as EIP1193Provider,
154
+ })
155
+ }
96
156
  }
97
157
  }
98
- });
158
+ })
99
159
  }
package/src/sdk.ts CHANGED
@@ -1,21 +1,21 @@
1
- import { EventEmitter } from "eventemitter3";
2
- import { FrameSDK, Emitter, EventMap } from "./types";
3
- import { frameHost } from "./frameHost";
4
- import { provider } from "./provider";
5
- import { FrameClientEvent, SignIn } from "@farcaster/frame-core";
1
+ import { AddFrame, type FrameClientEvent, SignIn } from '@farcaster/frame-core'
2
+ import { EventEmitter } from 'eventemitter3'
3
+ import { frameHost } from './frameHost'
4
+ import { provider } from './provider'
5
+ import type { Emitter, EventMap, FrameSDK } from './types'
6
6
 
7
7
  export function createEmitter(): Emitter {
8
- const emitter = new EventEmitter<EventMap>();
8
+ const emitter = new EventEmitter<EventMap>()
9
9
 
10
10
  return {
11
11
  get eventNames() {
12
- return emitter.eventNames.bind(emitter);
12
+ return emitter.eventNames.bind(emitter)
13
13
  },
14
14
  get listenerCount() {
15
- return emitter.listenerCount.bind(emitter);
15
+ return emitter.listenerCount.bind(emitter)
16
16
  },
17
17
  get listeners() {
18
- return emitter.listeners.bind(emitter);
18
+ return emitter.listeners.bind(emitter)
19
19
  },
20
20
  addListener: emitter.addListener.bind(emitter),
21
21
  emit: emitter.emit.bind(emitter),
@@ -24,10 +24,10 @@ export function createEmitter(): Emitter {
24
24
  once: emitter.once.bind(emitter),
25
25
  removeAllListeners: emitter.removeAllListeners.bind(emitter),
26
26
  removeListener: emitter.removeListener.bind(emitter),
27
- };
27
+ }
28
28
  }
29
29
 
30
- const emitter = createEmitter();
30
+ const emitter = createEmitter()
31
31
 
32
32
  export const sdk: FrameSDK = {
33
33
  ...emitter,
@@ -37,80 +37,94 @@ export const sdk: FrameSDK = {
37
37
  ready: frameHost.ready.bind(frameHost),
38
38
  close: frameHost.close.bind(frameHost),
39
39
  signIn: async (options) => {
40
- const response = await frameHost.signIn(options);
41
- console.log(response);
40
+ const response = await frameHost.signIn(options)
42
41
  if (response.result) {
43
- return response.result;
42
+ return response.result
44
43
  }
45
44
 
46
- if (response.error.type === "rejected_by_user") {
47
- throw new SignIn.RejectedByUser();
45
+ if (response.error.type === 'rejected_by_user') {
46
+ throw new SignIn.RejectedByUser()
48
47
  }
49
48
 
50
- throw new Error("Unreachable");
49
+ throw new Error('Unreachable')
51
50
  },
52
51
  openUrl: (url: string) => {
53
- return frameHost.openUrl(url.trim());
52
+ return frameHost.openUrl(url.trim())
53
+ },
54
+ addFrame: async () => {
55
+ const response = await frameHost.addFrame()
56
+ if (response.result) {
57
+ return response.result
58
+ }
59
+
60
+ if (response.error.type === 'invalid_domain_manifest') {
61
+ throw new AddFrame.InvalidDomainManifest()
62
+ }
63
+
64
+ if (response.error.type === 'rejected_by_user') {
65
+ throw new AddFrame.RejectedByUser()
66
+ }
67
+
68
+ throw new Error('Unreachable')
54
69
  },
55
- addFrame: frameHost.addFrame.bind(frameHost),
56
70
  },
57
71
  wallet: {
58
72
  ethProvider: provider,
59
73
  },
60
- };
74
+ }
61
75
 
62
76
  // Required to pass SSR
63
- if (typeof document !== "undefined") {
77
+ if (typeof document !== 'undefined') {
64
78
  // react native webview events
65
- document.addEventListener("FarcasterFrameEvent", (event) => {
79
+ document.addEventListener('FarcasterFrameEvent', (event) => {
66
80
  if (event instanceof MessageEvent) {
67
- const frameEvent = event.data as FrameClientEvent;
68
- if (frameEvent.event === "primary_button_clicked") {
69
- emitter.emit("primaryButtonClicked");
70
- } else if (frameEvent.event === "frame_added") {
71
- emitter.emit("frameAdded", {
81
+ const frameEvent = event.data as FrameClientEvent
82
+ if (frameEvent.event === 'primary_button_clicked') {
83
+ emitter.emit('primaryButtonClicked')
84
+ } else if (frameEvent.event === 'frame_added') {
85
+ emitter.emit('frameAdded', {
72
86
  notificationDetails: frameEvent.notificationDetails,
73
- });
74
- } else if (frameEvent.event === "frame_add_rejected") {
75
- emitter.emit("frameAddRejected", { reason: frameEvent.reason });
76
- } else if (frameEvent.event === "frame_removed") {
77
- emitter.emit("frameRemoved");
78
- } else if (frameEvent.event === "notifications_enabled") {
79
- emitter.emit("notificationsEnabled", {
87
+ })
88
+ } else if (frameEvent.event === 'frame_add_rejected') {
89
+ emitter.emit('frameAddRejected', { reason: frameEvent.reason })
90
+ } else if (frameEvent.event === 'frame_removed') {
91
+ emitter.emit('frameRemoved')
92
+ } else if (frameEvent.event === 'notifications_enabled') {
93
+ emitter.emit('notificationsEnabled', {
80
94
  notificationDetails: frameEvent.notificationDetails,
81
- });
82
- } else if (frameEvent.event === "notifications_disabled") {
83
- emitter.emit("notificationsDisabled");
95
+ })
96
+ } else if (frameEvent.event === 'notifications_disabled') {
97
+ emitter.emit('notificationsDisabled')
84
98
  }
85
99
  }
86
- });
100
+ })
87
101
  }
88
102
 
89
103
  // Required to pass SSR
90
- if (typeof window !== "undefined") {
104
+ if (typeof window !== 'undefined') {
91
105
  // web events
92
- window.addEventListener("message", (event) => {
106
+ window.addEventListener('message', (event) => {
93
107
  if (event instanceof MessageEvent) {
94
- if (event.data.type === "frameEvent") {
95
- const frameEvent = event.data.event as FrameClientEvent;
96
- if (frameEvent.event === "primary_button_clicked") {
97
- emitter.emit("primaryButtonClicked");
98
- } else if (frameEvent.event === "frame_added") {
99
- emitter.emit("frameAdded", {
108
+ if (event.data.type === 'frameEvent') {
109
+ const frameEvent = event.data.event as FrameClientEvent
110
+ if (frameEvent.event === 'primary_button_clicked') {
111
+ emitter.emit('primaryButtonClicked')
112
+ } else if (frameEvent.event === 'frame_added') {
113
+ emitter.emit('frameAdded', {
100
114
  notificationDetails: frameEvent.notificationDetails,
101
- });
102
- } else if (frameEvent.event === "frame_add_rejected") {
103
- emitter.emit("frameAddRejected", { reason: frameEvent.reason });
104
- } else if (frameEvent.event === "frame_removed") {
105
- emitter.emit("frameRemoved");
106
- } else if (frameEvent.event === "notifications_enabled") {
107
- emitter.emit("notificationsEnabled", {
115
+ })
116
+ } else if (frameEvent.event === 'frame_add_rejected') {
117
+ emitter.emit('frameAddRejected', { reason: frameEvent.reason })
118
+ } else if (frameEvent.event === 'frame_removed') {
119
+ emitter.emit('frameRemoved')
120
+ } else if (frameEvent.event === 'notifications_enabled') {
121
+ emitter.emit('notificationsEnabled', {
108
122
  notificationDetails: frameEvent.notificationDetails,
109
- });
110
- } else if (frameEvent.event === "notifications_disabled") {
111
- emitter.emit("notificationsDisabled");
123
+ })
124
+ } else if (frameEvent.event === 'notifications_disabled') {
125
+ emitter.emit('notificationsDisabled')
112
126
  }
113
127
  }
114
128
  }
115
- });
129
+ })
116
130
  }
package/src/types.ts CHANGED
@@ -1,64 +1,61 @@
1
- import type { EventEmitter } from "eventemitter3";
2
- import type { Provider } from "ox";
3
1
  import type {
4
- FrameContext,
5
2
  AddFrame,
3
+ FrameContext,
4
+ FrameNotificationDetails,
6
5
  ReadyOptions,
6
+ SetPrimaryButtonOptions,
7
7
  SignIn,
8
- FrameNotificationDetails,
9
- AddFrameRejectedReason,
10
- } from "@farcaster/frame-core";
8
+ } from '@farcaster/frame-core'
9
+ import type { EventEmitter } from 'eventemitter3'
10
+ import type { Provider } from 'ox'
11
11
 
12
12
  declare global {
13
13
  interface Window {
14
14
  // Exposed by react-native-webview
15
15
  ReactNativeWebView: {
16
- postMessage: (message: string) => void;
17
- };
16
+ postMessage: (message: string) => void
17
+ }
18
18
  }
19
19
  }
20
20
 
21
21
  /** Combines members of an intersection into a readable type. */
22
22
  // https://twitter.com/mattpocockuk/status/1622730173446557697?s=20&t=v01xkqU3KO0Mg
23
- export type Compute<type> = { [key in keyof type]: type[key] } & unknown;
23
+ type Compute<type> = { [key in keyof type]: type[key] } & unknown
24
24
 
25
25
  export type EventMap = {
26
- primaryButtonClicked: () => void;
26
+ primaryButtonClicked: () => void
27
27
  frameAdded: ({
28
28
  notificationDetails,
29
29
  }: {
30
- notificationDetails?: FrameNotificationDetails;
31
- }) => void;
32
- frameAddRejected: ({ reason }: { reason: AddFrameRejectedReason }) => void;
33
- frameRemoved: () => void;
30
+ notificationDetails?: FrameNotificationDetails
31
+ }) => void
32
+ frameAddRejected: ({
33
+ reason,
34
+ }: { reason: AddFrame.AddFrameRejectedReason }) => void
35
+ frameRemoved: () => void
34
36
  notificationsEnabled: ({
35
37
  notificationDetails,
36
38
  }: {
37
- notificationDetails: FrameNotificationDetails;
38
- }) => void;
39
- notificationsDisabled: () => void;
40
- };
39
+ notificationDetails: FrameNotificationDetails
40
+ }) => void
41
+ notificationsDisabled: () => void
42
+ }
41
43
 
42
- export type Emitter = Compute<EventEmitter<EventMap>>;
44
+ export type Emitter = Compute<EventEmitter<EventMap>>
43
45
 
44
- export type SetPrimaryButton = (options: {
45
- text: string;
46
- loading?: boolean;
47
- disabled?: boolean;
48
- hidden?: boolean;
49
- }) => Promise<void>;
46
+ type SetPrimaryButton = (options: SetPrimaryButtonOptions) => Promise<void>
50
47
 
51
48
  export type FrameSDK = {
52
- context: Promise<FrameContext>;
49
+ context: Promise<FrameContext>
53
50
  actions: {
54
- ready: (options?: Partial<ReadyOptions>) => Promise<void>;
55
- openUrl: (url: string) => Promise<void>;
56
- signIn: SignIn.SignIn;
57
- close: () => Promise<void>;
58
- setPrimaryButton: SetPrimaryButton;
59
- addFrame: AddFrame;
60
- };
51
+ ready: (options?: Partial<ReadyOptions>) => Promise<void>
52
+ openUrl: (url: string) => Promise<void>
53
+ signIn: SignIn.SignIn
54
+ close: () => Promise<void>
55
+ setPrimaryButton: SetPrimaryButton
56
+ addFrame: AddFrame.AddFrame
57
+ }
61
58
  wallet: {
62
- ethProvider: Provider.Provider;
63
- };
64
- } & Emitter;
59
+ ethProvider: Provider.Provider
60
+ }
61
+ } & Emitter