@farcaster/frame-core 0.0.0-canary-20250430150627

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.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -0
  3. package/dist/actions/AddFrame.d.ts +36 -0
  4. package/dist/actions/AddFrame.js +57 -0
  5. package/dist/actions/ComposeCast.d.ts +32 -0
  6. package/dist/actions/ComposeCast.js +2 -0
  7. package/dist/actions/Ready.d.ts +13 -0
  8. package/dist/actions/Ready.js +6 -0
  9. package/dist/actions/SendToken.d.ts +48 -0
  10. package/dist/actions/SendToken.js +2 -0
  11. package/dist/actions/SignIn.d.ts +41 -0
  12. package/dist/actions/SignIn.js +47 -0
  13. package/dist/actions/SwapToken.d.ts +46 -0
  14. package/dist/actions/SwapToken.js +2 -0
  15. package/dist/actions/ViewProfile.d.ts +4 -0
  16. package/dist/actions/ViewProfile.js +2 -0
  17. package/dist/actions/ViewToken.d.ts +4 -0
  18. package/dist/actions/ViewToken.js +2 -0
  19. package/dist/actions/index.d.ts +8 -0
  20. package/dist/actions/index.js +44 -0
  21. package/dist/context.d.ts +72 -0
  22. package/dist/context.js +2 -0
  23. package/dist/errors.d.ts +13 -0
  24. package/dist/errors.js +12 -0
  25. package/dist/index.d.ts +7 -0
  26. package/dist/index.js +46 -0
  27. package/dist/internal/types.d.ts +8 -0
  28. package/dist/internal/types.js +2 -0
  29. package/dist/manifest.d.ts +101 -0
  30. package/dist/manifest.js +2 -0
  31. package/dist/schemas/embeds.d.ts +243 -0
  32. package/dist/schemas/embeds.js +32 -0
  33. package/dist/schemas/events.d.ts +131 -0
  34. package/dist/schemas/events.js +25 -0
  35. package/dist/schemas/index.d.ts +5 -0
  36. package/dist/schemas/index.js +21 -0
  37. package/dist/schemas/manifest.d.ts +208 -0
  38. package/dist/schemas/manifest.js +61 -0
  39. package/dist/schemas/notifications.d.ts +60 -0
  40. package/dist/schemas/notifications.js +23 -0
  41. package/dist/schemas/shared.d.ts +39 -0
  42. package/dist/schemas/shared.js +58 -0
  43. package/dist/types.d.ts +60 -0
  44. package/dist/types.js +21 -0
  45. package/dist/wallet/ethereum.d.ts +47 -0
  46. package/dist/wallet/ethereum.js +2 -0
  47. package/dist/wallet/index.d.ts +1 -0
  48. package/dist/wallet/index.js +37 -0
  49. package/esm/actions/AddFrame.d.ts +36 -0
  50. package/esm/actions/AddFrame.js +19 -0
  51. package/esm/actions/ComposeCast.d.ts +32 -0
  52. package/esm/actions/ComposeCast.js +1 -0
  53. package/esm/actions/Ready.d.ts +13 -0
  54. package/esm/actions/Ready.js +3 -0
  55. package/esm/actions/SendToken.d.ts +48 -0
  56. package/esm/actions/SendToken.js +1 -0
  57. package/esm/actions/SignIn.d.ts +41 -0
  58. package/esm/actions/SignIn.js +10 -0
  59. package/esm/actions/SwapToken.d.ts +46 -0
  60. package/esm/actions/SwapToken.js +1 -0
  61. package/esm/actions/ViewProfile.d.ts +4 -0
  62. package/esm/actions/ViewProfile.js +1 -0
  63. package/esm/actions/ViewToken.d.ts +4 -0
  64. package/esm/actions/ViewToken.js +1 -0
  65. package/esm/actions/index.d.ts +8 -0
  66. package/esm/actions/index.js +8 -0
  67. package/esm/context.d.ts +72 -0
  68. package/esm/context.js +1 -0
  69. package/esm/errors.d.ts +13 -0
  70. package/esm/errors.js +8 -0
  71. package/esm/index.d.ts +7 -0
  72. package/esm/index.js +7 -0
  73. package/esm/internal/types.d.ts +8 -0
  74. package/esm/internal/types.js +1 -0
  75. package/esm/manifest.d.ts +101 -0
  76. package/esm/manifest.js +1 -0
  77. package/esm/schemas/embeds.d.ts +243 -0
  78. package/esm/schemas/embeds.js +28 -0
  79. package/esm/schemas/events.d.ts +131 -0
  80. package/esm/schemas/events.js +22 -0
  81. package/esm/schemas/index.d.ts +5 -0
  82. package/esm/schemas/index.js +5 -0
  83. package/esm/schemas/manifest.d.ts +208 -0
  84. package/esm/schemas/manifest.js +58 -0
  85. package/esm/schemas/notifications.d.ts +60 -0
  86. package/esm/schemas/notifications.js +20 -0
  87. package/esm/schemas/shared.d.ts +39 -0
  88. package/esm/schemas/shared.js +54 -0
  89. package/esm/tsconfig.tsbuildinfo +1 -0
  90. package/esm/types.d.ts +60 -0
  91. package/esm/types.js +3 -0
  92. package/esm/wallet/ethereum.d.ts +47 -0
  93. package/esm/wallet/ethereum.js +1 -0
  94. package/esm/wallet/index.d.ts +1 -0
  95. package/esm/wallet/index.js +1 -0
  96. package/package.json +41 -0
  97. package/src/actions/AddFrame.ts +51 -0
  98. package/src/actions/ComposeCast.ts +36 -0
  99. package/src/actions/Ready.ts +15 -0
  100. package/src/actions/SendToken.ts +57 -0
  101. package/src/actions/SignIn.ts +51 -0
  102. package/src/actions/SwapToken.ts +54 -0
  103. package/src/actions/ViewProfile.ts +5 -0
  104. package/src/actions/ViewToken.ts +5 -0
  105. package/src/actions/index.ts +8 -0
  106. package/src/context.ts +90 -0
  107. package/src/errors.ts +21 -0
  108. package/src/index.ts +7 -0
  109. package/src/internal/types.ts +20 -0
  110. package/src/manifest.ts +113 -0
  111. package/src/schemas/embeds.ts +44 -0
  112. package/src/schemas/events.ts +41 -0
  113. package/src/schemas/index.ts +5 -0
  114. package/src/schemas/manifest.ts +68 -0
  115. package/src/schemas/notifications.ts +33 -0
  116. package/src/schemas/shared.ts +81 -0
  117. package/src/types.ts +95 -0
  118. package/src/wallet/ethereum.ts +65 -0
  119. package/src/wallet/index.ts +1 -0
@@ -0,0 +1,68 @@
1
+ import { z } from 'zod'
2
+ import {
3
+ buttonTitleSchema,
4
+ createSimpleStringSchema,
5
+ encodedJsonFarcasterSignatureSchema,
6
+ frameNameSchema,
7
+ hexColorSchema,
8
+ secureUrlSchema,
9
+ } from './shared'
10
+
11
+ const primaryCategorySchema = z.enum([
12
+ 'games',
13
+ 'social',
14
+ 'finance',
15
+ 'utility',
16
+ 'productivity',
17
+ 'health-fitness',
18
+ 'news-media',
19
+ 'music',
20
+ 'shopping',
21
+ 'education',
22
+ 'developer-tools',
23
+ 'entertainment',
24
+ 'art-creativity',
25
+ ])
26
+
27
+ export const domainFrameConfigSchema = z.object({
28
+ // 0.0.0 and 0.0.1 are not technically part of the spec but kept for
29
+ // backwards compatibilty. next should always resolve to the most recent
30
+ // schema version.
31
+ version: z.union([
32
+ z.literal('0.0.0'),
33
+ z.literal('0.0.1'),
34
+ z.literal('1'),
35
+ z.literal('next'),
36
+ ]),
37
+ name: frameNameSchema,
38
+ iconUrl: secureUrlSchema,
39
+ homeUrl: secureUrlSchema,
40
+ /** deprecated, set ogImageUrl instead */
41
+ imageUrl: secureUrlSchema.optional(),
42
+ /** deprecated, will rely on fc:frame meta tag */
43
+ buttonTitle: buttonTitleSchema.optional(),
44
+ splashImageUrl: secureUrlSchema.optional(),
45
+ splashBackgroundColor: hexColorSchema.optional(),
46
+ webhookUrl: secureUrlSchema.optional(),
47
+ /** see: https://github.com/farcasterxyz/miniapps/discussions/191 */
48
+ subtitle: createSimpleStringSchema({ max: 30 }).optional(),
49
+ description: createSimpleStringSchema({ max: 170 }).optional(),
50
+ screenshotUrls: z.array(secureUrlSchema).max(3).optional(),
51
+ primaryCategory: primaryCategorySchema.optional(),
52
+ tags: z
53
+ .array(createSimpleStringSchema({ max: 20, noSpaces: true }))
54
+ .max(5)
55
+ .optional(),
56
+ heroImageUrl: secureUrlSchema.optional(),
57
+ tagline: createSimpleStringSchema({ max: 30 }).optional(),
58
+ ogTitle: createSimpleStringSchema({ max: 30 }).optional(),
59
+ ogDescription: createSimpleStringSchema({ max: 100 }).optional(),
60
+ ogImageUrl: secureUrlSchema.optional(),
61
+ /** see: https://github.com/farcasterxyz/miniapps/discussions/204 */
62
+ noindex: z.boolean().optional(),
63
+ })
64
+
65
+ export const domainManifestSchema = z.object({
66
+ accountAssociation: encodedJsonFarcasterSignatureSchema,
67
+ frame: domainFrameConfigSchema.optional(),
68
+ })
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod'
2
+ import { secureUrlSchema } from './shared'
3
+
4
+ export const notificationDetailsSchema = z.object({
5
+ url: z.string(),
6
+ token: z.string(),
7
+ })
8
+
9
+ export type FrameNotificationDetails = z.infer<typeof notificationDetailsSchema>
10
+
11
+ export const sendNotificationRequestSchema = z.object({
12
+ notificationId: z.string().max(128),
13
+ title: z.string().max(32),
14
+ body: z.string().max(128),
15
+ targetUrl: secureUrlSchema,
16
+ tokens: z.string().array().max(100),
17
+ })
18
+
19
+ export type SendNotificationRequest = z.infer<
20
+ typeof sendNotificationRequestSchema
21
+ >
22
+
23
+ export const sendNotificationResponseSchema = z.object({
24
+ result: z.object({
25
+ successfulTokens: z.array(z.string()),
26
+ invalidTokens: z.array(z.string()),
27
+ rateLimitedTokens: z.array(z.string()),
28
+ }),
29
+ })
30
+
31
+ export type SendNotificationResponse = z.infer<
32
+ typeof sendNotificationResponseSchema
33
+ >
@@ -0,0 +1,81 @@
1
+ import { z } from 'zod'
2
+
3
+ const SPECIAL_CHARS_PATTERN = /[@#$%^&*+=\/\\|~«»]/
4
+ const REPEATED_PUNCTUATION_PATTERN = /(!{2,}|\?{2,}|-{2,})/
5
+
6
+ // Unicode ranges for emoji detection:
7
+ // \u{1F300}-\u{1F9FF} - Miscellaneous Symbols, Pictographs, Emoticons, Transport, Map, and Supplemental
8
+ // \u{2702}-\u{27B0} - Dingbats
9
+ // \u{2600}-\u{26FF} - Miscellaneous Symbols
10
+ // \u{2B00}-\u{2BFF} - Miscellaneous Symbols and Arrows
11
+ const EMOJI_PATTERN =
12
+ /[\u{1F300}-\u{1F9FF}]|[\u{2702}-\u{27B0}]|[\u{2600}-\u{26FF}]|[\u{2B00}-\u{2BFF}]/u
13
+
14
+ export const createSimpleStringSchema = ({
15
+ max,
16
+ noSpaces,
17
+ }: { max?: number; noSpaces?: boolean } = {}) => {
18
+ const stringValidations = noSpaces
19
+ ? z
20
+ .string()
21
+ .max(max ?? Number.POSITIVE_INFINITY)
22
+ .regex(/^\S*$/, 'Spaces are not allowed')
23
+ : z.string().max(max ?? Number.POSITIVE_INFINITY)
24
+
25
+ return stringValidations
26
+ .refine((value) => !EMOJI_PATTERN.test(value), {
27
+ message: 'Emojis and symbols are not allowed',
28
+ })
29
+ .refine((value) => !SPECIAL_CHARS_PATTERN.test(value), {
30
+ message:
31
+ 'Special characters (@, #, $, %, ^, &, *, +, =, /, \\, |, ~, «, ») are not allowed',
32
+ })
33
+ .refine((value) => !REPEATED_PUNCTUATION_PATTERN.test(value), {
34
+ message: 'Repeated punctuations (!!, ??, --) are not allowed',
35
+ })
36
+ }
37
+
38
+ export const secureUrlSchema = z
39
+ .string()
40
+ .url()
41
+ .startsWith('https://', { message: 'Must be an https url' })
42
+ .max(1024)
43
+
44
+ export const frameNameSchema = z.string().max(32)
45
+ export const buttonTitleSchema = z.string().max(32)
46
+
47
+ const CAIP_19_REGEX =
48
+ /^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}\/(?:[-a-z0-9]{3,8}:[-.%a-zA-Z0-9]{1,128}(?:\/[-.%a-zA-Z0-9]{1,78})?|native)$/
49
+
50
+ export const caip19TokenSchema = z
51
+ .string()
52
+ .regex(CAIP_19_REGEX, { message: 'Invalid CAIP-19 asset ID' })
53
+
54
+ export const hexColorSchema = z
55
+ .string()
56
+ .regex(/^#([0-9A-F]{3}|[0-9A-F]{6})$/i, {
57
+ message:
58
+ 'Invalid hex color code. It should be in the format #RRGGBB or #RGB.',
59
+ })
60
+
61
+ export const aspectRatioSchema = z.union([z.literal('1:1'), z.literal('3:2')])
62
+
63
+ export const encodedJsonFarcasterSignatureSchema = z.object({
64
+ header: z.string(),
65
+ payload: z.string(),
66
+ signature: z.string(),
67
+ })
68
+
69
+ export type EncodedJsonFarcasterSignatureSchema = z.infer<
70
+ typeof encodedJsonFarcasterSignatureSchema
71
+ >
72
+
73
+ export const jsonFarcasterSignatureHeaderSchema = z.object({
74
+ fid: z.number(),
75
+ type: z.literal('app_key'),
76
+ key: z.string().startsWith('0x'),
77
+ })
78
+
79
+ export type JsonFarcasterSignatureHeaderSchema = z.infer<
80
+ typeof jsonFarcasterSignatureHeaderSchema
81
+ >
package/src/types.ts ADDED
@@ -0,0 +1,95 @@
1
+ import type {
2
+ AddFrame,
3
+ ComposeCast,
4
+ Ready,
5
+ SendToken,
6
+ SignIn,
7
+ SwapToken,
8
+ ViewProfile,
9
+ ViewToken,
10
+ } from './actions'
11
+ import type { FrameContext } from './context'
12
+ import type {
13
+ EventFrameAdded,
14
+ EventFrameRemoved,
15
+ EventNotificationsDisabled,
16
+ EventNotificationsEnabled,
17
+ } from './schemas'
18
+ import type { Ethereum } from './wallet'
19
+
20
+ export type SetPrimaryButtonOptions = {
21
+ text: string
22
+ loading?: boolean
23
+ disabled?: boolean
24
+ hidden?: boolean
25
+ }
26
+
27
+ // start backwards compat, remove in 1.0
28
+ export * from './wallet/ethereum'
29
+ export { DEFAULT_READY_OPTIONS, ReadyOptions } from './actions/Ready'
30
+ export type SignInOptions = SignIn.SignInOptions
31
+ // end backwards compat
32
+
33
+ export type SetPrimaryButton = (options: SetPrimaryButtonOptions) => void
34
+
35
+ export type WireFrameHost = {
36
+ context: FrameContext
37
+ close: () => void
38
+ ready: Ready.Ready
39
+ openUrl: (url: string) => void
40
+ signIn: SignIn.WireSignIn
41
+ setPrimaryButton: SetPrimaryButton
42
+ ethProviderRequest: Ethereum.EthProvideRequest
43
+ ethProviderRequestV2: Ethereum.RpcTransport
44
+ eip6963RequestProvider: () => void
45
+ addFrame: AddFrame.WireAddFrame
46
+ viewProfile: ViewProfile.ViewProfile
47
+ viewToken: ViewToken.ViewToken
48
+ sendToken: SendToken.SendToken
49
+ swapToken: SwapToken.SwapToken
50
+ composeCast: <close extends boolean | undefined = undefined>(
51
+ options: ComposeCast.Options<close>,
52
+ ) => Promise<ComposeCast.Result<close>>
53
+ }
54
+
55
+ export type FrameHost = {
56
+ context: FrameContext
57
+ close: () => void
58
+ ready: Ready.Ready
59
+ openUrl: (url: string) => void
60
+ signIn: SignIn.SignIn
61
+ setPrimaryButton: SetPrimaryButton
62
+ ethProviderRequest: Ethereum.EthProvideRequest
63
+ ethProviderRequestV2: Ethereum.RpcTransport
64
+ /**
65
+ * Receive forwarded eip6963:requestProvider events from the frame document.
66
+ * Hosts must emit an EventEip6963AnnounceProvider in response.
67
+ */
68
+ eip6963RequestProvider: () => void
69
+ addFrame: AddFrame.AddFrame
70
+ viewProfile: ViewProfile.ViewProfile
71
+ viewToken: ViewToken.ViewToken
72
+ sendToken: SendToken.SendToken
73
+ swapToken: SwapToken.SwapToken
74
+ composeCast: <close extends boolean | undefined = undefined>(
75
+ options: ComposeCast.Options<close>,
76
+ ) => Promise<ComposeCast.Result<close>>
77
+ }
78
+
79
+ export type EventFrameAddRejected = {
80
+ event: 'frame_add_rejected'
81
+ reason: AddFrame.AddFrameRejectedReason
82
+ }
83
+
84
+ export type EventPrimaryButtonClicked = {
85
+ event: 'primary_button_clicked'
86
+ }
87
+
88
+ export type FrameClientEvent =
89
+ | EventFrameAdded
90
+ | EventFrameAddRejected
91
+ | EventFrameRemoved
92
+ | EventNotificationsEnabled
93
+ | EventNotificationsDisabled
94
+ | EventPrimaryButtonClicked
95
+ | Ethereum.EventEip6963AnnounceProvider
@@ -0,0 +1,65 @@
1
+ import type * as Address from 'ox/Address'
2
+ import type * as Provider from 'ox/Provider'
3
+ import type * as RpcRequest from 'ox/RpcRequest'
4
+ import type * as RpcResponse from 'ox/RpcResponse'
5
+ import type * as RpcSchema from 'ox/RpcSchema'
6
+
7
+ export type EthProvideRequest<
8
+ schema extends RpcSchema.Generic = RpcSchema.Default,
9
+ > = Provider.RequestFn<schema>
10
+
11
+ export type FrameEthProviderEventData = {
12
+ type: 'frame_eth_provider_event'
13
+ } & EthProviderWireEvent
14
+
15
+ export type RpcTransport = (
16
+ request: RpcRequest.RpcRequest,
17
+ ) => Promise<RpcResponse.RpcResponse>
18
+
19
+ export type ProviderRpcError = {
20
+ code: number
21
+ details?: string
22
+ message?: string
23
+ }
24
+
25
+ export type EthProviderWireEvent =
26
+ | {
27
+ event: 'accountsChanged'
28
+ params: [readonly Address.Address[]]
29
+ }
30
+ | {
31
+ event: 'chainChanged'
32
+ params: [string]
33
+ }
34
+ | {
35
+ event: 'connect'
36
+ params: [Provider.ConnectInfo]
37
+ }
38
+ | {
39
+ event: 'disconnect'
40
+ params: [ProviderRpcError]
41
+ }
42
+ | {
43
+ event: 'message'
44
+ params: [Provider.Message]
45
+ }
46
+
47
+ export type EmitEthProvider = <event extends EthProviderWireEvent['event']>(
48
+ event: event,
49
+ params: Extract<EthProviderWireEvent, { event: event }>['params'],
50
+ ) => void
51
+
52
+ /**
53
+ * Metadata of the EIP-1193 Provider.
54
+ */
55
+ export interface EIP6963ProviderInfo {
56
+ icon: `data:image/${string}` // RFC-2397
57
+ name: string
58
+ rdns: string
59
+ uuid: string
60
+ }
61
+
62
+ export type EventEip6963AnnounceProvider = {
63
+ event: 'eip6963:announceProvider'
64
+ info: EIP6963ProviderInfo
65
+ }
@@ -0,0 +1 @@
1
+ export * as Ethereum from './ethereum'