@farcaster/snap 1.4.1 → 1.5.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.
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Named color palette for snaps. Snap authors specify a name; the client maps
3
+ * it to a hex value appropriate for its current light/dark mode.
4
+ *
5
+ * Light-mode hex values (used by emulator):
6
+ * gray=#8F8F8F blue=#006BFF red=#FC0036 amber=#FFAE00
7
+ * green=#28A948 teal=#00AC96 purple=#8B5CF6 pink=#F32782
8
+ *
9
+ * Dark-mode hex values (for reference; client-owned):
10
+ * gray=#8F8F8F blue=#006FFE red=#F13342 amber=#FFAE00
11
+ * green=#00AC3A teal=#00AA96 purple=#A78BFA pink=#F12B82
12
+ */
13
+ export declare const PALETTE_COLOR: {
14
+ readonly gray: "gray";
15
+ readonly blue: "blue";
16
+ readonly red: "red";
17
+ readonly amber: "amber";
18
+ readonly green: "green";
19
+ readonly teal: "teal";
20
+ readonly purple: "purple";
21
+ readonly pink: "pink";
22
+ };
23
+ export declare const PALETTE_COLOR_ACCENT: "accent";
24
+ export declare const DEFAULT_THEME_ACCENT: "purple";
25
+ export declare const PALETTE_COLOR_VALUES: readonly ["gray", "blue", "red", "amber", "green", "teal", "purple", "pink"];
26
+ export type PaletteColor = (typeof PALETTE_COLOR_VALUES)[number];
27
+ /** Light-mode hex for each palette color (emulator / reference client). */
28
+ export declare const PALETTE_LIGHT_HEX: Record<PaletteColor, string>;
29
+ /** Dark-mode hex for each palette color (reference). */
30
+ export declare const PALETTE_DARK_HEX: Record<PaletteColor, string>;
31
+ export declare const PROGRESS_COLOR_VALUES: readonly ["accent", "gray", "blue", "red", "amber", "green", "teal", "purple", "pink"];
32
+ export declare const BAR_CHART_COLOR_VALUES: readonly ["accent", "gray", "blue", "red", "amber", "green", "teal", "purple", "pink"];
package/dist/colors.js ADDED
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Named color palette for snaps. Snap authors specify a name; the client maps
3
+ * it to a hex value appropriate for its current light/dark mode.
4
+ *
5
+ * Light-mode hex values (used by emulator):
6
+ * gray=#8F8F8F blue=#006BFF red=#FC0036 amber=#FFAE00
7
+ * green=#28A948 teal=#00AC96 purple=#8B5CF6 pink=#F32782
8
+ *
9
+ * Dark-mode hex values (for reference; client-owned):
10
+ * gray=#8F8F8F blue=#006FFE red=#F13342 amber=#FFAE00
11
+ * green=#00AC3A teal=#00AA96 purple=#A78BFA pink=#F12B82
12
+ */
13
+ export const PALETTE_COLOR = {
14
+ gray: "gray",
15
+ blue: "blue",
16
+ red: "red",
17
+ amber: "amber",
18
+ green: "green",
19
+ teal: "teal",
20
+ purple: "purple",
21
+ pink: "pink",
22
+ };
23
+ export const PALETTE_COLOR_ACCENT = "accent";
24
+ export const DEFAULT_THEME_ACCENT = PALETTE_COLOR.purple;
25
+ export const PALETTE_COLOR_VALUES = [
26
+ PALETTE_COLOR.gray,
27
+ PALETTE_COLOR.blue,
28
+ PALETTE_COLOR.red,
29
+ PALETTE_COLOR.amber,
30
+ PALETTE_COLOR.green,
31
+ PALETTE_COLOR.teal,
32
+ PALETTE_COLOR.purple,
33
+ PALETTE_COLOR.pink,
34
+ ];
35
+ /** Light-mode hex for each palette color (emulator / reference client). */
36
+ export const PALETTE_LIGHT_HEX = {
37
+ gray: "#8F8F8F",
38
+ blue: "#006BFF",
39
+ red: "#FC0036",
40
+ amber: "#FFAE00",
41
+ green: "#28A948",
42
+ teal: "#00AC96",
43
+ purple: "#8B5CF6",
44
+ pink: "#F32782",
45
+ };
46
+ /** Dark-mode hex for each palette color (reference). */
47
+ export const PALETTE_DARK_HEX = {
48
+ gray: "#8F8F8F",
49
+ blue: "#006FFE",
50
+ red: "#F13342",
51
+ amber: "#FFAE00",
52
+ green: "#00AC3A",
53
+ teal: "#00AA96",
54
+ purple: "#A78BFA",
55
+ pink: "#F12B82",
56
+ };
57
+ export const PROGRESS_COLOR_VALUES = [
58
+ PALETTE_COLOR_ACCENT,
59
+ ...PALETTE_COLOR_VALUES,
60
+ ];
61
+ export const BAR_CHART_COLOR_VALUES = [
62
+ PALETTE_COLOR_ACCENT,
63
+ ...PALETTE_COLOR_VALUES,
64
+ ];
@@ -38,36 +38,6 @@ export declare const SPACER_SIZE: {
38
38
  readonly large: "large";
39
39
  };
40
40
  export declare const SPACER_SIZE_VALUES: readonly ["small", "medium", "large"];
41
- /**
42
- * Named color palette for snaps. Snap authors specify a name; the client maps
43
- * it to a hex value appropriate for its current light/dark mode.
44
- *
45
- * Light-mode hex values (used by emulator):
46
- * gray=#8F8F8F blue=#006BFF red=#FC0036 amber=#FFAE00
47
- * green=#28A948 teal=#00AC96 purple=#8B5CF6 pink=#F32782
48
- *
49
- * Dark-mode hex values (for reference; client-owned):
50
- * gray=#8F8F8F blue=#006FFE red=#F13342 amber=#FFAE00
51
- * green=#00AC3A teal=#00AA96 purple=#A78BFA pink=#F12B82
52
- */
53
- export declare const PALETTE_COLOR: {
54
- readonly gray: "gray";
55
- readonly blue: "blue";
56
- readonly red: "red";
57
- readonly amber: "amber";
58
- readonly green: "green";
59
- readonly teal: "teal";
60
- readonly purple: "purple";
61
- readonly pink: "pink";
62
- };
63
- export declare const PALETTE_COLOR_ACCENT: "accent";
64
- export declare const PALETTE_COLOR_VALUES: readonly ["gray", "blue", "red", "amber", "green", "teal", "purple", "pink"];
65
- export type PaletteColor = (typeof PALETTE_COLOR_VALUES)[number];
66
- /** Light-mode hex for each palette color (emulator / reference client). */
67
- export declare const PALETTE_LIGHT_HEX: Record<PaletteColor, string>;
68
- /** Dark-mode hex for each palette color (reference). */
69
- export declare const PALETTE_DARK_HEX: Record<PaletteColor, string>;
70
- export declare const PROGRESS_COLOR_VALUES: readonly ["accent", "gray", "blue", "red", "amber", "green", "teal", "purple", "pink"];
71
41
  export declare const LIST_STYLE_VALUES: readonly ["ordered", "unordered", "plain"];
72
42
  export declare const DEFAULT_LIST_STYLE: "ordered";
73
43
  export declare const GRID_CELL_SIZE_VALUES: readonly ["auto", "square"];
@@ -92,7 +62,6 @@ export declare const BUTTON_STYLE: {
92
62
  export declare const BUTTON_STYLE_VALUES: readonly ["primary", "secondary"];
93
63
  export declare const BUTTON_LAYOUT_VALUES: readonly ["stack", "row", "grid"];
94
64
  export declare const DEFAULT_BUTTON_LAYOUT: "stack";
95
- export declare const BAR_CHART_COLOR_VALUES: readonly ["accent", "gray", "blue", "red", "amber", "green", "teal", "purple", "pink"];
96
65
  export declare const EFFECT_VALUES: readonly ["confetti"];
97
66
  export declare const GROUP_LAYOUT_VALUES: readonly ["row"];
98
67
  /** Only valid as `page.elements`: vertical container for the page body (matches json-render trees). */
@@ -119,8 +88,6 @@ export declare const HTTPS_PREFIX: "https://";
119
88
  export declare const HTTP_PREFIX: "http://";
120
89
  /** 6-digit hex only (#RRGGBB); used for grid cell backgrounds (free hex). */
121
90
  export declare const HEX_COLOR_6_RE: RegExp;
122
- /** Default snap accent when `page.theme` or `page.theme.accent` is omitted (SPEC.md). */
123
- export declare const DEFAULT_THEME_ACCENT: "purple";
124
91
  export declare const TEXT_CONTENT_MAX: {
125
92
  readonly title: 80;
126
93
  readonly body: 160;
package/dist/constants.js CHANGED
@@ -53,65 +53,6 @@ export const SPACER_SIZE_VALUES = [
53
53
  SPACER_SIZE.medium,
54
54
  SPACER_SIZE.large,
55
55
  ];
56
- /**
57
- * Named color palette for snaps. Snap authors specify a name; the client maps
58
- * it to a hex value appropriate for its current light/dark mode.
59
- *
60
- * Light-mode hex values (used by emulator):
61
- * gray=#8F8F8F blue=#006BFF red=#FC0036 amber=#FFAE00
62
- * green=#28A948 teal=#00AC96 purple=#8B5CF6 pink=#F32782
63
- *
64
- * Dark-mode hex values (for reference; client-owned):
65
- * gray=#8F8F8F blue=#006FFE red=#F13342 amber=#FFAE00
66
- * green=#00AC3A teal=#00AA96 purple=#A78BFA pink=#F12B82
67
- */
68
- export const PALETTE_COLOR = {
69
- gray: "gray",
70
- blue: "blue",
71
- red: "red",
72
- amber: "amber",
73
- green: "green",
74
- teal: "teal",
75
- purple: "purple",
76
- pink: "pink",
77
- };
78
- export const PALETTE_COLOR_ACCENT = "accent";
79
- export const PALETTE_COLOR_VALUES = [
80
- PALETTE_COLOR.gray,
81
- PALETTE_COLOR.blue,
82
- PALETTE_COLOR.red,
83
- PALETTE_COLOR.amber,
84
- PALETTE_COLOR.green,
85
- PALETTE_COLOR.teal,
86
- PALETTE_COLOR.purple,
87
- PALETTE_COLOR.pink,
88
- ];
89
- /** Light-mode hex for each palette color (emulator / reference client). */
90
- export const PALETTE_LIGHT_HEX = {
91
- gray: "#8F8F8F",
92
- blue: "#006BFF",
93
- red: "#FC0036",
94
- amber: "#FFAE00",
95
- green: "#28A948",
96
- teal: "#00AC96",
97
- purple: "#8B5CF6",
98
- pink: "#F32782",
99
- };
100
- /** Dark-mode hex for each palette color (reference). */
101
- export const PALETTE_DARK_HEX = {
102
- gray: "#8F8F8F",
103
- blue: "#006FFE",
104
- red: "#F13342",
105
- amber: "#FFAE00",
106
- green: "#00AC3A",
107
- teal: "#00AA96",
108
- purple: "#A78BFA",
109
- pink: "#F12B82",
110
- };
111
- export const PROGRESS_COLOR_VALUES = [
112
- PALETTE_COLOR_ACCENT,
113
- ...PALETTE_COLOR_VALUES,
114
- ];
115
56
  export const LIST_STYLE_VALUES = ["ordered", "unordered", "plain"];
116
57
  export const DEFAULT_LIST_STYLE = "ordered";
117
58
  export const GRID_CELL_SIZE_VALUES = ["auto", "square"];
@@ -148,10 +89,6 @@ export const BUTTON_STYLE_VALUES = [
148
89
  ];
149
90
  export const BUTTON_LAYOUT_VALUES = ["stack", "row", "grid"];
150
91
  export const DEFAULT_BUTTON_LAYOUT = BUTTON_LAYOUT_VALUES[0];
151
- export const BAR_CHART_COLOR_VALUES = [
152
- PALETTE_COLOR_ACCENT,
153
- ...PALETTE_COLOR_VALUES,
154
- ];
155
92
  export const EFFECT_VALUES = ["confetti"];
156
93
  export const GROUP_LAYOUT_VALUES = ["row"];
157
94
  /** Only valid as `page.elements`: vertical container for the page body (matches json-render trees). */
@@ -177,8 +114,6 @@ export const HTTPS_PREFIX = "https://";
177
114
  export const HTTP_PREFIX = "http://";
178
115
  /** 6-digit hex only (#RRGGBB); used for grid cell backgrounds (free hex). */
179
116
  export const HEX_COLOR_6_RE = /^#[0-9a-fA-F]{6}$/;
180
- /** Default snap accent when `page.theme` or `page.theme.accent` is omitted (SPEC.md). */
181
- export const DEFAULT_THEME_ACCENT = PALETTE_COLOR.purple;
182
117
  export const TEXT_CONTENT_MAX = {
183
118
  [TEXT_STYLE.title]: 80,
184
119
  [TEXT_STYLE.body]: 160,
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- export { POST_GRID_TAP_KEY, PAGE_ROOT_TYPE, ELEMENT_TYPE, MEDIA_TYPE, DEFAULT_THEME_ACCENT, DEFAULT_LIST_STYLE, DEFAULT_SLIDER_STEP, PALETTE_COLOR, PALETTE_COLOR_ACCENT, PALETTE_COLOR_VALUES, PALETTE_LIGHT_HEX, PALETTE_DARK_HEX, type PaletteColor, } from "./constants.js";
2
- export { snapResponseSchema, firstPageResponseSchema, payloadSchema, type Button, type Element, type Elements, type GroupChildElement, type SnapAction, type SnapPageElementInput, type SnapContext, type SnapResponse, type SnapHandlerResult, type SnapFunction, type SnapPayload, } from "./schemas.js";
1
+ export { POST_GRID_TAP_KEY, PAGE_ROOT_TYPE, ELEMENT_TYPE, MEDIA_TYPE, DEFAULT_LIST_STYLE, DEFAULT_SLIDER_STEP, } from "./constants.js";
2
+ export { DEFAULT_THEME_ACCENT, PALETTE_COLOR, PALETTE_COLOR_ACCENT, PALETTE_COLOR_VALUES, PALETTE_LIGHT_HEX, PALETTE_DARK_HEX, type PaletteColor, } from "./colors.js";
3
+ export { ACTION_TYPE_GET, ACTION_TYPE_POST, snapResponseSchema, firstPageResponseSchema, payloadSchema, createDefaultDataStore, type Button, type Element, type Elements, type GroupChildElement, type SnapAction, type SnapPageElementInput, type SnapContext, type SnapResponse, type SnapHandlerResult, type SnapFunction, type SnapPayload, type DataStoreValue, type SnapDataStore, type SnapDataStoreOperations, } from "./schemas.js";
3
4
  export { validateSnapResponse, validateFirstPageResponse, type ValidationResult, } from "./validator.js";
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
- export { POST_GRID_TAP_KEY, PAGE_ROOT_TYPE, ELEMENT_TYPE, MEDIA_TYPE, DEFAULT_THEME_ACCENT, DEFAULT_LIST_STYLE, DEFAULT_SLIDER_STEP, PALETTE_COLOR, PALETTE_COLOR_ACCENT, PALETTE_COLOR_VALUES, PALETTE_LIGHT_HEX, PALETTE_DARK_HEX, } from "./constants.js";
2
- export { snapResponseSchema, firstPageResponseSchema, payloadSchema, } from "./schemas.js";
1
+ export { POST_GRID_TAP_KEY, PAGE_ROOT_TYPE, ELEMENT_TYPE, MEDIA_TYPE, DEFAULT_LIST_STYLE, DEFAULT_SLIDER_STEP, } from "./constants.js";
2
+ export { DEFAULT_THEME_ACCENT, PALETTE_COLOR, PALETTE_COLOR_ACCENT, PALETTE_COLOR_VALUES, PALETTE_LIGHT_HEX, PALETTE_DARK_HEX, } from "./colors.js";
3
+ export { ACTION_TYPE_GET, ACTION_TYPE_POST, snapResponseSchema, firstPageResponseSchema, payloadSchema, createDefaultDataStore, } from "./schemas.js";
3
4
  export { validateSnapResponse, validateFirstPageResponse, } from "./validator.js";
package/dist/schemas.d.ts CHANGED
@@ -1536,9 +1536,21 @@ export declare const snapActionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1536
1536
  type: z.ZodLiteral<"post">;
1537
1537
  }, z.core.$strict>], "type">;
1538
1538
  export type SnapAction = z.infer<typeof snapActionSchema>;
1539
+ export type DataStoreValue = string | number | boolean | null | DataStoreValue[] | {
1540
+ [key: string]: DataStoreValue;
1541
+ };
1542
+ export type SnapDataStoreOperations = {
1543
+ get(key: string): Promise<DataStoreValue | null>;
1544
+ set(key: string, value: DataStoreValue): Promise<void>;
1545
+ };
1546
+ export type SnapDataStore = SnapDataStoreOperations & {
1547
+ withLock<T>(fn: (store: SnapDataStoreOperations) => Promise<T>): Promise<T>;
1548
+ };
1549
+ export declare function createDefaultDataStore(): SnapDataStore;
1539
1550
  export type SnapContext = {
1540
1551
  action: SnapAction;
1541
1552
  request: Request;
1553
+ data: SnapDataStore;
1542
1554
  };
1543
1555
  export type SnapFunction = (ctx: SnapContext) => Promise<SnapHandlerResult>;
1544
1556
  export {};
package/dist/schemas.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
- import { BAR_CHART_COLOR_VALUES, BUTTON_ACTION, BUTTON_ACTION_VALUES, BUTTON_GROUP_STYLE, BUTTON_GROUP_STYLE_VALUES, BUTTON_LAYOUT_VALUES, BUTTON_STYLE_VALUES, DEFAULT_BUTTON_LAYOUT, DEFAULT_LIST_STYLE, DEFAULT_SLIDER_STEP, DEFAULT_THEME_ACCENT, EFFECT_VALUES, ELEMENT_TYPE, GRID_CELL_SIZE_VALUES, GRID_GAP_VALUES, GROUP_LAYOUT_VALUES, HEX_COLOR_6_RE, HTTP_PREFIX, HTTPS_PREFIX, IMAGE_ASPECT_VALUES, INTERACTIVE_ELEMENT_TYPES, LIMITS, LIST_STYLE_VALUES, MEDIA_ELEMENT_TYPES, PAGE_ROOT_TYPE, PALETTE_COLOR_VALUES, PROGRESS_COLOR_VALUES, SLIDER_STEP_ALIGN_EPS, SPACER_SIZE, SPACER_SIZE_VALUES, SPEC_VERSION, TEXT_ALIGN_VALUES, TEXT_CONTENT_MAX, TEXT_STYLE, TEXT_STYLE_VALUES, } from "./constants.js";
2
+ import { BUTTON_ACTION, BUTTON_ACTION_VALUES, BUTTON_GROUP_STYLE, BUTTON_GROUP_STYLE_VALUES, BUTTON_LAYOUT_VALUES, BUTTON_STYLE_VALUES, DEFAULT_BUTTON_LAYOUT, DEFAULT_LIST_STYLE, DEFAULT_SLIDER_STEP, EFFECT_VALUES, ELEMENT_TYPE, GRID_CELL_SIZE_VALUES, GRID_GAP_VALUES, GROUP_LAYOUT_VALUES, HEX_COLOR_6_RE, HTTP_PREFIX, HTTPS_PREFIX, IMAGE_ASPECT_VALUES, INTERACTIVE_ELEMENT_TYPES, LIMITS, LIST_STYLE_VALUES, MEDIA_ELEMENT_TYPES, PAGE_ROOT_TYPE, SLIDER_STEP_ALIGN_EPS, SPACER_SIZE, SPACER_SIZE_VALUES, SPEC_VERSION, TEXT_ALIGN_VALUES, TEXT_CONTENT_MAX, TEXT_STYLE, TEXT_STYLE_VALUES, } from "./constants.js";
3
+ import { BAR_CHART_COLOR_VALUES, DEFAULT_THEME_ACCENT, PALETTE_COLOR_VALUES, PROGRESS_COLOR_VALUES, } from "./colors.js";
3
4
  /**
4
5
  * post/link/mini_app targets must be HTTPS in production; allow HTTP only for
5
6
  * loopback hosts so local snap servers (e.g. http://localhost:3014/snap) validate.
@@ -457,3 +458,17 @@ export const snapActionSchema = z.discriminatedUnion("type", [
457
458
  snapGetActionSchema,
458
459
  snapPostActionSchema,
459
460
  ]);
461
+ export function createDefaultDataStore() {
462
+ const err = new Error("Data store is not configured. Use withUpstash() from @farcaster/snap-upstash or provide a data store implementation.");
463
+ return {
464
+ get(_key) {
465
+ return Promise.reject(err);
466
+ },
467
+ set(_key, _value) {
468
+ return Promise.reject(err);
469
+ },
470
+ withLock(_fn) {
471
+ return Promise.reject(err);
472
+ },
473
+ };
474
+ }
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
- import { BAR_CHART_COLOR_VALUES, LIMITS, PALETTE_COLOR_VALUES, } from "../constants.js";
2
+ import { LIMITS } from "../constants.js";
3
+ import { BAR_CHART_COLOR_VALUES, PALETTE_COLOR_VALUES } from "../colors.js";
3
4
  export const barChartProps = z.object({
4
5
  bars: z
5
6
  .array(z.object({
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { PROGRESS_COLOR_VALUES } from "../constants.js";
2
+ import { PROGRESS_COLOR_VALUES } from "../colors.js";
3
3
  export const progressProps = z.object({
4
4
  value: z.number(),
5
5
  max: z.number(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farcaster/snap",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "Farcaster Snaps 🫰",
5
5
  "repository": {
6
6
  "type": "git",
package/src/colors.ts ADDED
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Named color palette for snaps. Snap authors specify a name; the client maps
3
+ * it to a hex value appropriate for its current light/dark mode.
4
+ *
5
+ * Light-mode hex values (used by emulator):
6
+ * gray=#8F8F8F blue=#006BFF red=#FC0036 amber=#FFAE00
7
+ * green=#28A948 teal=#00AC96 purple=#8B5CF6 pink=#F32782
8
+ *
9
+ * Dark-mode hex values (for reference; client-owned):
10
+ * gray=#8F8F8F blue=#006FFE red=#F13342 amber=#FFAE00
11
+ * green=#00AC3A teal=#00AA96 purple=#A78BFA pink=#F12B82
12
+ */
13
+ export const PALETTE_COLOR = {
14
+ gray: "gray",
15
+ blue: "blue",
16
+ red: "red",
17
+ amber: "amber",
18
+ green: "green",
19
+ teal: "teal",
20
+ purple: "purple",
21
+ pink: "pink",
22
+ } as const;
23
+
24
+ export const PALETTE_COLOR_ACCENT = "accent" as const;
25
+
26
+ export const DEFAULT_THEME_ACCENT = PALETTE_COLOR.purple;
27
+
28
+ export const PALETTE_COLOR_VALUES = [
29
+ PALETTE_COLOR.gray,
30
+ PALETTE_COLOR.blue,
31
+ PALETTE_COLOR.red,
32
+ PALETTE_COLOR.amber,
33
+ PALETTE_COLOR.green,
34
+ PALETTE_COLOR.teal,
35
+ PALETTE_COLOR.purple,
36
+ PALETTE_COLOR.pink,
37
+ ] as const;
38
+
39
+ export type PaletteColor = (typeof PALETTE_COLOR_VALUES)[number];
40
+
41
+ /** Light-mode hex for each palette color (emulator / reference client). */
42
+ export const PALETTE_LIGHT_HEX: Record<PaletteColor, string> = {
43
+ gray: "#8F8F8F",
44
+ blue: "#006BFF",
45
+ red: "#FC0036",
46
+ amber: "#FFAE00",
47
+ green: "#28A948",
48
+ teal: "#00AC96",
49
+ purple: "#8B5CF6",
50
+ pink: "#F32782",
51
+ };
52
+
53
+ /** Dark-mode hex for each palette color (reference). */
54
+ export const PALETTE_DARK_HEX: Record<PaletteColor, string> = {
55
+ gray: "#8F8F8F",
56
+ blue: "#006FFE",
57
+ red: "#F13342",
58
+ amber: "#FFAE00",
59
+ green: "#00AC3A",
60
+ teal: "#00AA96",
61
+ purple: "#A78BFA",
62
+ pink: "#F12B82",
63
+ };
64
+
65
+ export const PROGRESS_COLOR_VALUES = [
66
+ PALETTE_COLOR_ACCENT,
67
+ ...PALETTE_COLOR_VALUES,
68
+ ] as const;
69
+
70
+ export const BAR_CHART_COLOR_VALUES = [
71
+ PALETTE_COLOR_ACCENT,
72
+ ...PALETTE_COLOR_VALUES,
73
+ ] as const;
package/src/constants.ts CHANGED
@@ -62,73 +62,6 @@ export const SPACER_SIZE_VALUES = [
62
62
  SPACER_SIZE.large,
63
63
  ] as const;
64
64
 
65
- /**
66
- * Named color palette for snaps. Snap authors specify a name; the client maps
67
- * it to a hex value appropriate for its current light/dark mode.
68
- *
69
- * Light-mode hex values (used by emulator):
70
- * gray=#8F8F8F blue=#006BFF red=#FC0036 amber=#FFAE00
71
- * green=#28A948 teal=#00AC96 purple=#8B5CF6 pink=#F32782
72
- *
73
- * Dark-mode hex values (for reference; client-owned):
74
- * gray=#8F8F8F blue=#006FFE red=#F13342 amber=#FFAE00
75
- * green=#00AC3A teal=#00AA96 purple=#A78BFA pink=#F12B82
76
- */
77
- export const PALETTE_COLOR = {
78
- gray: "gray",
79
- blue: "blue",
80
- red: "red",
81
- amber: "amber",
82
- green: "green",
83
- teal: "teal",
84
- purple: "purple",
85
- pink: "pink",
86
- } as const;
87
-
88
- export const PALETTE_COLOR_ACCENT = "accent" as const;
89
-
90
- export const PALETTE_COLOR_VALUES = [
91
- PALETTE_COLOR.gray,
92
- PALETTE_COLOR.blue,
93
- PALETTE_COLOR.red,
94
- PALETTE_COLOR.amber,
95
- PALETTE_COLOR.green,
96
- PALETTE_COLOR.teal,
97
- PALETTE_COLOR.purple,
98
- PALETTE_COLOR.pink,
99
- ] as const;
100
-
101
- export type PaletteColor = (typeof PALETTE_COLOR_VALUES)[number];
102
-
103
- /** Light-mode hex for each palette color (emulator / reference client). */
104
- export const PALETTE_LIGHT_HEX: Record<PaletteColor, string> = {
105
- gray: "#8F8F8F",
106
- blue: "#006BFF",
107
- red: "#FC0036",
108
- amber: "#FFAE00",
109
- green: "#28A948",
110
- teal: "#00AC96",
111
- purple: "#8B5CF6",
112
- pink: "#F32782",
113
- };
114
-
115
- /** Dark-mode hex for each palette color (reference). */
116
- export const PALETTE_DARK_HEX: Record<PaletteColor, string> = {
117
- gray: "#8F8F8F",
118
- blue: "#006FFE",
119
- red: "#F13342",
120
- amber: "#FFAE00",
121
- green: "#00AC3A",
122
- teal: "#00AA96",
123
- purple: "#A78BFA",
124
- pink: "#F12B82",
125
- };
126
-
127
- export const PROGRESS_COLOR_VALUES = [
128
- PALETTE_COLOR_ACCENT,
129
- ...PALETTE_COLOR_VALUES,
130
- ] as const;
131
-
132
65
  export const LIST_STYLE_VALUES = ["ordered", "unordered", "plain"] as const;
133
66
 
134
67
  export const DEFAULT_LIST_STYLE = "ordered" as const;
@@ -175,11 +108,6 @@ export const BUTTON_STYLE_VALUES = [
175
108
  export const BUTTON_LAYOUT_VALUES = ["stack", "row", "grid"] as const;
176
109
  export const DEFAULT_BUTTON_LAYOUT = BUTTON_LAYOUT_VALUES[0];
177
110
 
178
- export const BAR_CHART_COLOR_VALUES = [
179
- PALETTE_COLOR_ACCENT,
180
- ...PALETTE_COLOR_VALUES,
181
- ] as const;
182
-
183
111
  export const EFFECT_VALUES = ["confetti"] as const;
184
112
 
185
113
  export const GROUP_LAYOUT_VALUES = ["row"] as const;
@@ -213,9 +141,6 @@ export const HTTP_PREFIX = "http://" as const;
213
141
  /** 6-digit hex only (#RRGGBB); used for grid cell backgrounds (free hex). */
214
142
  export const HEX_COLOR_6_RE = /^#[0-9a-fA-F]{6}$/;
215
143
 
216
- /** Default snap accent when `page.theme` or `page.theme.accent` is omitted (SPEC.md). */
217
- export const DEFAULT_THEME_ACCENT = PALETTE_COLOR.purple;
218
-
219
144
  export const TEXT_CONTENT_MAX = {
220
145
  [TEXT_STYLE.title]: 80,
221
146
  [TEXT_STYLE.body]: 160,
package/src/index.ts CHANGED
@@ -3,20 +3,25 @@ export {
3
3
  PAGE_ROOT_TYPE,
4
4
  ELEMENT_TYPE,
5
5
  MEDIA_TYPE,
6
- DEFAULT_THEME_ACCENT,
7
6
  DEFAULT_LIST_STYLE,
8
7
  DEFAULT_SLIDER_STEP,
8
+ } from "./constants";
9
+ export {
10
+ DEFAULT_THEME_ACCENT,
9
11
  PALETTE_COLOR,
10
12
  PALETTE_COLOR_ACCENT,
11
13
  PALETTE_COLOR_VALUES,
12
14
  PALETTE_LIGHT_HEX,
13
15
  PALETTE_DARK_HEX,
14
16
  type PaletteColor,
15
- } from "./constants";
17
+ } from "./colors";
16
18
  export {
19
+ ACTION_TYPE_GET,
20
+ ACTION_TYPE_POST,
17
21
  snapResponseSchema,
18
22
  firstPageResponseSchema,
19
23
  payloadSchema,
24
+ createDefaultDataStore,
20
25
  type Button,
21
26
  type Element,
22
27
  type Elements,
@@ -28,6 +33,9 @@ export {
28
33
  type SnapHandlerResult,
29
34
  type SnapFunction,
30
35
  type SnapPayload,
36
+ type DataStoreValue,
37
+ type SnapDataStore,
38
+ type SnapDataStoreOperations,
31
39
  } from "./schemas";
32
40
  export {
33
41
  validateSnapResponse,
package/src/schemas.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { z } from "zod";
2
2
  import {
3
- BAR_CHART_COLOR_VALUES,
4
3
  BUTTON_ACTION,
5
4
  BUTTON_ACTION_VALUES,
6
5
  BUTTON_GROUP_STYLE,
@@ -10,7 +9,6 @@ import {
10
9
  DEFAULT_BUTTON_LAYOUT,
11
10
  DEFAULT_LIST_STYLE,
12
11
  DEFAULT_SLIDER_STEP,
13
- DEFAULT_THEME_ACCENT,
14
12
  EFFECT_VALUES,
15
13
  ELEMENT_TYPE,
16
14
  GRID_CELL_SIZE_VALUES,
@@ -25,8 +23,6 @@ import {
25
23
  LIST_STYLE_VALUES,
26
24
  MEDIA_ELEMENT_TYPES,
27
25
  PAGE_ROOT_TYPE,
28
- PALETTE_COLOR_VALUES,
29
- PROGRESS_COLOR_VALUES,
30
26
  SLIDER_STEP_ALIGN_EPS,
31
27
  SPACER_SIZE,
32
28
  SPACER_SIZE_VALUES,
@@ -36,6 +32,12 @@ import {
36
32
  TEXT_STYLE,
37
33
  TEXT_STYLE_VALUES,
38
34
  } from "./constants";
35
+ import {
36
+ BAR_CHART_COLOR_VALUES,
37
+ DEFAULT_THEME_ACCENT,
38
+ PALETTE_COLOR_VALUES,
39
+ PROGRESS_COLOR_VALUES,
40
+ } from "./colors";
39
41
 
40
42
  /**
41
43
  * post/link/mini_app targets must be HTTPS in production; allow HTTP only for
@@ -578,9 +580,44 @@ export const snapActionSchema = z.discriminatedUnion("type", [
578
580
 
579
581
  export type SnapAction = z.infer<typeof snapActionSchema>;
580
582
 
583
+ export type DataStoreValue =
584
+ | string
585
+ | number
586
+ | boolean
587
+ | null
588
+ | DataStoreValue[]
589
+ | { [key: string]: DataStoreValue };
590
+
591
+ export type SnapDataStoreOperations = {
592
+ get(key: string): Promise<DataStoreValue | null>;
593
+ set(key: string, value: DataStoreValue): Promise<void>;
594
+ };
595
+
596
+ export type SnapDataStore = SnapDataStoreOperations & {
597
+ withLock<T>(fn: (store: SnapDataStoreOperations) => Promise<T>): Promise<T>;
598
+ };
599
+
600
+ export function createDefaultDataStore(): SnapDataStore {
601
+ const err = new Error(
602
+ "Data store is not configured. Use withUpstash() from @farcaster/snap-upstash or provide a data store implementation.",
603
+ );
604
+ return {
605
+ get(_key: string): Promise<never> {
606
+ return Promise.reject(err);
607
+ },
608
+ set(_key: string, _value: DataStoreValue): Promise<never> {
609
+ return Promise.reject(err);
610
+ },
611
+ withLock<T>(_fn: (store: SnapDataStoreOperations) => Promise<T>): Promise<never> {
612
+ return Promise.reject(err);
613
+ },
614
+ };
615
+ }
616
+
581
617
  export type SnapContext = {
582
618
  action: SnapAction;
583
619
  request: Request;
620
+ data: SnapDataStore;
584
621
  };
585
622
 
586
623
  export type SnapFunction = (ctx: SnapContext) => Promise<SnapHandlerResult>;
@@ -1,9 +1,6 @@
1
1
  import { z } from "zod";
2
- import {
3
- BAR_CHART_COLOR_VALUES,
4
- LIMITS,
5
- PALETTE_COLOR_VALUES,
6
- } from "../constants.js";
2
+ import { LIMITS } from "../constants.js";
3
+ import { BAR_CHART_COLOR_VALUES, PALETTE_COLOR_VALUES } from "../colors.js";
7
4
 
8
5
  export const barChartProps = z.object({
9
6
  bars: z
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { PROGRESS_COLOR_VALUES } from "../constants.js";
2
+ import { PROGRESS_COLOR_VALUES } from "../colors.js";
3
3
 
4
4
  export const progressProps = z.object({
5
5
  value: z.number(),