@farcaster/frame-core 0.0.0-canary-20250509164556 → 0.0.0-canary-20250510204457

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/src/solana.ts ADDED
@@ -0,0 +1,82 @@
1
+ import type {
2
+ Connection as SolanaConnection,
3
+ SendOptions as SolanaSendOptions,
4
+ Transaction as SolanaTransaction,
5
+ VersionedTransaction as SolanaVersionedTransaction,
6
+ } from '@solana/web3.js'
7
+
8
+ export type { SolanaConnection }
9
+
10
+ export type SolanaCombinedTransaction =
11
+ | SolanaTransaction
12
+ | SolanaVersionedTransaction
13
+
14
+ export type SolanaConnectRequestArguments = {
15
+ method: 'connect'
16
+ }
17
+ export type SolanaSignMessageRequestArguments = {
18
+ method: 'signMessage'
19
+ params: {
20
+ message: string
21
+ }
22
+ }
23
+ export type SolanaSignAndSendTransactionRequestArguments = {
24
+ method: 'signAndSendTransaction'
25
+ params: {
26
+ transaction: SolanaCombinedTransaction
27
+ connection: SolanaConnection
28
+ options?: SolanaSendOptions
29
+ }
30
+ }
31
+ export type SolanaSignTransactionRequestArguments<
32
+ T extends SolanaCombinedTransaction = SolanaTransaction,
33
+ > = {
34
+ method: 'signTransaction'
35
+ params: {
36
+ transaction: T
37
+ }
38
+ }
39
+
40
+ export type SolanaRequestFn = ((
41
+ request: SolanaConnectRequestArguments,
42
+ ) => Promise<{ publicKey: string }>) &
43
+ ((request: SolanaSignMessageRequestArguments) => Promise<{
44
+ signature: string
45
+ }>) &
46
+ ((request: SolanaSignAndSendTransactionRequestArguments) => Promise<{
47
+ signature: string
48
+ }>) &
49
+ (<T extends SolanaCombinedTransaction>(
50
+ request: SolanaSignTransactionRequestArguments<T>,
51
+ ) => Promise<{ signedTransaction: T }>)
52
+
53
+ export interface SolanaWalletProvider {
54
+ request: SolanaRequestFn
55
+
56
+ signMessage(message: string): Promise<{ signature: string }>
57
+ signTransaction<T extends SolanaCombinedTransaction>(
58
+ transaction: T,
59
+ ): Promise<{ signedTransaction: T }>
60
+ signAndSendTransaction(input: {
61
+ transaction: SolanaCombinedTransaction
62
+ connection: SolanaConnection
63
+ }): Promise<{ signature: string }>
64
+ }
65
+
66
+ export const createSolanaWalletProvider = (
67
+ request: SolanaRequestFn,
68
+ ): SolanaWalletProvider => ({
69
+ request,
70
+ signMessage: (msg: string) =>
71
+ request({ method: 'signMessage', params: { message: msg } }),
72
+ signTransaction: <T extends SolanaCombinedTransaction>(transaction: T) =>
73
+ request({ method: 'signTransaction', params: { transaction } }),
74
+ signAndSendTransaction: (input: {
75
+ transaction: SolanaCombinedTransaction
76
+ connection: SolanaConnection
77
+ }) =>
78
+ request({
79
+ method: 'signAndSendTransaction',
80
+ params: input,
81
+ }),
82
+ })
package/src/types.ts CHANGED
@@ -9,13 +9,13 @@ import type {
9
9
  ViewToken,
10
10
  } from './actions'
11
11
  import type { FrameContext } from './context'
12
- import type { ShareStateProvider } from './funcs'
13
12
  import type {
14
13
  EventFrameAdded,
15
14
  EventFrameRemoved,
16
15
  EventNotificationsDisabled,
17
16
  EventNotificationsEnabled,
18
17
  } from './schemas'
18
+ import type { SolanaRequestFn } from './solana'
19
19
  import type { Ethereum } from './wallet'
20
20
 
21
21
  export type SetPrimaryButtonOptions = {
@@ -43,6 +43,7 @@ export type WireFrameHost = {
43
43
  ethProviderRequest: Ethereum.EthProvideRequest
44
44
  ethProviderRequestV2: Ethereum.RpcTransport
45
45
  eip6963RequestProvider: () => void
46
+ solanaProviderRequest?: SolanaRequestFn
46
47
  addFrame: AddFrame.WireAddFrame
47
48
  viewProfile: ViewProfile.ViewProfile
48
49
  viewToken: ViewToken.ViewToken
@@ -51,7 +52,6 @@ export type WireFrameHost = {
51
52
  composeCast: <close extends boolean | undefined = undefined>(
52
53
  options: ComposeCast.Options<close>,
53
54
  ) => Promise<ComposeCast.Result<close>>
54
- setShareStateProvider: (fn: ShareStateProvider) => void
55
55
  }
56
56
 
57
57
  export type FrameHost = {
@@ -68,6 +68,7 @@ export type FrameHost = {
68
68
  * Hosts must emit an EventEip6963AnnounceProvider in response.
69
69
  */
70
70
  eip6963RequestProvider: () => void
71
+ solanaProviderRequest?: SolanaRequestFn
71
72
  addFrame: AddFrame.AddFrame
72
73
  viewProfile: ViewProfile.ViewProfile
73
74
  viewToken: ViewToken.ViewToken
@@ -76,7 +77,6 @@ export type FrameHost = {
76
77
  composeCast: <close extends boolean | undefined = undefined>(
77
78
  options: ComposeCast.Options<close>,
78
79
  ) => Promise<ComposeCast.Result<close>>
79
- setShareStateProvider: (fn: ShareStateProvider) => void
80
80
  }
81
81
 
82
82
  export type EventFrameAddRejected = {
package/dist/funcs.d.ts DELETED
@@ -1,20 +0,0 @@
1
- import type { z } from 'zod';
2
- import type { sharedStateSchema } from './schemas/funcs';
3
- /**
4
- * State used by the host when constructing the mini app URL to be shared.
5
- *
6
- * path: The path to be added to the mini app URL when shared. Added either to
7
- * the `homeUrl` specified in the manifest or the URL of an mini app embed
8
- * shared on the feed.
9
- *
10
- * e.g. `'/specific/miniapp/screen'` (can set `window.location.pathname` directly).
11
- *
12
- * params: Query parms to be added to the mini app URL when shared. Compatible with
13
- * URLSearchParams constructor parameters.
14
- *
15
- * Either a key-value pair e.g. `{ foo: 'bar' }`, a string e.g. `'foo=bar'`,
16
- * or an array of arrays e.g. `[['foo', 'bar'], ['baz', 'qux']]`
17
- * (can set `window.location.search` directly).
18
- */
19
- export type ShareState = z.infer<typeof sharedStateSchema>;
20
- export type ShareStateProvider = () => ShareState | Promise<ShareState>;
package/dist/funcs.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,11 +0,0 @@
1
- import { z } from 'zod';
2
- export declare const sharedStateSchema: z.ZodObject<{
3
- path: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
4
- params: z.ZodOptional<z.ZodUnion<[z.ZodRecord<z.ZodString, z.ZodString>, z.ZodEffects<z.ZodString, string, string>, z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">]>>;
5
- }, "strip", z.ZodTypeAny, {
6
- params?: string | Record<string, string> | string[][] | undefined;
7
- path?: string | undefined;
8
- }, {
9
- params?: string | Record<string, string> | string[][] | undefined;
10
- path?: string | undefined;
11
- }>;
@@ -1,78 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sharedStateSchema = void 0;
4
- const zod_1 = require("zod");
5
- const isUrlEncoded = (val) => {
6
- if (val === '')
7
- return true;
8
- try {
9
- return encodeURIComponent(decodeURIComponent(val)) === val;
10
- }
11
- catch (e) {
12
- return false;
13
- }
14
- };
15
- exports.sharedStateSchema = zod_1.z.object({
16
- path: zod_1.z
17
- .string()
18
- .refine((pathStr) => {
19
- if (pathStr === '')
20
- return true;
21
- if (!pathStr.startsWith('/'))
22
- return false;
23
- if (pathStr.includes('?') || pathStr.includes('#'))
24
- return false;
25
- if (pathStr === '/') {
26
- return true;
27
- }
28
- const segments = pathStr.substring(1).split('/');
29
- for (let i = 0; i < segments.length; i++) {
30
- const segment = segments[i];
31
- if (segment === '') {
32
- if (i < segments.length - 1) {
33
- return false;
34
- }
35
- return true;
36
- }
37
- if (!isUrlEncoded(segment)) {
38
- return false;
39
- }
40
- }
41
- return true;
42
- }, {
43
- message: 'Path must be a valid URL-encoded path string, starting with / (e.g., /foo/bar), or an empty string. Consecutive slashes (e.g., /foo//bar) are not allowed.',
44
- })
45
- .optional(),
46
- params: zod_1.z
47
- .union([
48
- zod_1.z.record(zod_1.z.string(), zod_1.z.string()),
49
- zod_1.z.string().refine((queryStr) => {
50
- const str = queryStr.startsWith('?')
51
- ? queryStr.substring(1)
52
- : queryStr;
53
- if (str === '')
54
- return true;
55
- if (str.includes('&&')) {
56
- if (str !== '&&')
57
- return false;
58
- }
59
- const pairs = str.split('&');
60
- for (const pair of pairs) {
61
- const parts = pair.split('=', 2);
62
- const key = parts[0];
63
- if (!isUrlEncoded(key))
64
- return false;
65
- if (parts.length > 1) {
66
- const value = parts[1];
67
- if (!isUrlEncoded(value))
68
- return false;
69
- }
70
- }
71
- return true;
72
- }, {
73
- message: "Query string must be a valid URL-encoded query string (e.g., 'foo=bar%20baz&key=val' or '?name=value'). Both keys and values must be URL-encoded.",
74
- }),
75
- zod_1.z.array(zod_1.z.array(zod_1.z.string())),
76
- ])
77
- .optional(),
78
- });
package/esm/funcs.d.ts DELETED
@@ -1,20 +0,0 @@
1
- import type { z } from 'zod';
2
- import type { sharedStateSchema } from './schemas/funcs';
3
- /**
4
- * State used by the host when constructing the mini app URL to be shared.
5
- *
6
- * path: The path to be added to the mini app URL when shared. Added either to
7
- * the `homeUrl` specified in the manifest or the URL of an mini app embed
8
- * shared on the feed.
9
- *
10
- * e.g. `'/specific/miniapp/screen'` (can set `window.location.pathname` directly).
11
- *
12
- * params: Query parms to be added to the mini app URL when shared. Compatible with
13
- * URLSearchParams constructor parameters.
14
- *
15
- * Either a key-value pair e.g. `{ foo: 'bar' }`, a string e.g. `'foo=bar'`,
16
- * or an array of arrays e.g. `[['foo', 'bar'], ['baz', 'qux']]`
17
- * (can set `window.location.search` directly).
18
- */
19
- export type ShareState = z.infer<typeof sharedStateSchema>;
20
- export type ShareStateProvider = () => ShareState | Promise<ShareState>;
package/esm/funcs.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,11 +0,0 @@
1
- import { z } from 'zod';
2
- export declare const sharedStateSchema: z.ZodObject<{
3
- path: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
4
- params: z.ZodOptional<z.ZodUnion<[z.ZodRecord<z.ZodString, z.ZodString>, z.ZodEffects<z.ZodString, string, string>, z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">]>>;
5
- }, "strip", z.ZodTypeAny, {
6
- params?: string | Record<string, string> | string[][] | undefined;
7
- path?: string | undefined;
8
- }, {
9
- params?: string | Record<string, string> | string[][] | undefined;
10
- path?: string | undefined;
11
- }>;
@@ -1,75 +0,0 @@
1
- import { z } from 'zod';
2
- const isUrlEncoded = (val) => {
3
- if (val === '')
4
- return true;
5
- try {
6
- return encodeURIComponent(decodeURIComponent(val)) === val;
7
- }
8
- catch (e) {
9
- return false;
10
- }
11
- };
12
- export const sharedStateSchema = z.object({
13
- path: z
14
- .string()
15
- .refine((pathStr) => {
16
- if (pathStr === '')
17
- return true;
18
- if (!pathStr.startsWith('/'))
19
- return false;
20
- if (pathStr.includes('?') || pathStr.includes('#'))
21
- return false;
22
- if (pathStr === '/') {
23
- return true;
24
- }
25
- const segments = pathStr.substring(1).split('/');
26
- for (let i = 0; i < segments.length; i++) {
27
- const segment = segments[i];
28
- if (segment === '') {
29
- if (i < segments.length - 1) {
30
- return false;
31
- }
32
- return true;
33
- }
34
- if (!isUrlEncoded(segment)) {
35
- return false;
36
- }
37
- }
38
- return true;
39
- }, {
40
- message: 'Path must be a valid URL-encoded path string, starting with / (e.g., /foo/bar), or an empty string. Consecutive slashes (e.g., /foo//bar) are not allowed.',
41
- })
42
- .optional(),
43
- params: z
44
- .union([
45
- z.record(z.string(), z.string()),
46
- z.string().refine((queryStr) => {
47
- const str = queryStr.startsWith('?')
48
- ? queryStr.substring(1)
49
- : queryStr;
50
- if (str === '')
51
- return true;
52
- if (str.includes('&&')) {
53
- if (str !== '&&')
54
- return false;
55
- }
56
- const pairs = str.split('&');
57
- for (const pair of pairs) {
58
- const parts = pair.split('=', 2);
59
- const key = parts[0];
60
- if (!isUrlEncoded(key))
61
- return false;
62
- if (parts.length > 1) {
63
- const value = parts[1];
64
- if (!isUrlEncoded(value))
65
- return false;
66
- }
67
- }
68
- return true;
69
- }, {
70
- message: "Query string must be a valid URL-encoded query string (e.g., 'foo=bar%20baz&key=val' or '?name=value'). Both keys and values must be URL-encoded.",
71
- }),
72
- z.array(z.array(z.string())),
73
- ])
74
- .optional(),
75
- });
package/src/funcs.ts DELETED
@@ -1,22 +0,0 @@
1
- import type { z } from 'zod'
2
- import type { sharedStateSchema } from './schemas/funcs'
3
-
4
- /**
5
- * State used by the host when constructing the mini app URL to be shared.
6
- *
7
- * path: The path to be added to the mini app URL when shared. Added either to
8
- * the `homeUrl` specified in the manifest or the URL of an mini app embed
9
- * shared on the feed.
10
- *
11
- * e.g. `'/specific/miniapp/screen'` (can set `window.location.pathname` directly).
12
- *
13
- * params: Query parms to be added to the mini app URL when shared. Compatible with
14
- * URLSearchParams constructor parameters.
15
- *
16
- * Either a key-value pair e.g. `{ foo: 'bar' }`, a string e.g. `'foo=bar'`,
17
- * or an array of arrays e.g. `[['foo', 'bar'], ['baz', 'qux']]`
18
- * (can set `window.location.search` directly).
19
- */
20
- export type ShareState = z.infer<typeof sharedStateSchema>
21
-
22
- export type ShareStateProvider = () => ShareState | Promise<ShareState>
@@ -1,83 +0,0 @@
1
- import { z } from 'zod'
2
-
3
- const isUrlEncoded = (val: string): boolean => {
4
- if (val === '') return true
5
- try {
6
- return encodeURIComponent(decodeURIComponent(val)) === val
7
- } catch (e) {
8
- return false
9
- }
10
- }
11
-
12
- export const sharedStateSchema = z.object({
13
- path: z
14
- .string()
15
- .refine(
16
- (pathStr) => {
17
- if (pathStr === '') return true
18
- if (!pathStr.startsWith('/')) return false
19
- if (pathStr.includes('?') || pathStr.includes('#')) return false
20
-
21
- if (pathStr === '/') {
22
- return true
23
- }
24
-
25
- const segments = pathStr.substring(1).split('/')
26
- for (let i = 0; i < segments.length; i++) {
27
- const segment = segments[i]
28
- if (segment === '') {
29
- if (i < segments.length - 1) {
30
- return false
31
- }
32
- return true
33
- }
34
- if (!isUrlEncoded(segment)) {
35
- return false
36
- }
37
- }
38
- return true
39
- },
40
- {
41
- message:
42
- 'Path must be a valid URL-encoded path string, starting with / (e.g., /foo/bar), or an empty string. Consecutive slashes (e.g., /foo//bar) are not allowed.',
43
- },
44
- )
45
- .optional(),
46
- params: z
47
- .union([
48
- z.record(z.string(), z.string()),
49
- z.string().refine(
50
- (queryStr) => {
51
- const str = queryStr.startsWith('?')
52
- ? queryStr.substring(1)
53
- : queryStr
54
- if (str === '') return true
55
-
56
- if (str.includes('&&')) {
57
- if (str !== '&&') return false
58
- }
59
-
60
- const pairs = str.split('&')
61
-
62
- for (const pair of pairs) {
63
- const parts = pair.split('=', 2)
64
- const key = parts[0]
65
-
66
- if (!isUrlEncoded(key)) return false
67
-
68
- if (parts.length > 1) {
69
- const value = parts[1]
70
- if (!isUrlEncoded(value)) return false
71
- }
72
- }
73
- return true
74
- },
75
- {
76
- message:
77
- "Query string must be a valid URL-encoded query string (e.g., 'foo=bar%20baz&key=val' or '?name=value'). Both keys and values must be URL-encoded.",
78
- },
79
- ),
80
- z.array(z.array(z.string())),
81
- ])
82
- .optional(),
83
- })