Skip to content

Commit fa40d01

Browse files
committed
feat: add custom post metadata type
1 parent 09b6ed2 commit fa40d01

File tree

7 files changed

+110
-1
lines changed

7 files changed

+110
-1
lines changed

jsonschemas/schema.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
{
2828
"$ref": "#/$defs/MintMetadata"
2929
},
30+
{
31+
"$ref": "#/$defs/CustomMetadata"
32+
},
3033
{
3134
"$ref": "#/$defs/SpaceMetadata"
3235
},
@@ -78,7 +81,8 @@
7881
"SHORT_VIDEO",
7982
"3D",
8083
"STORY",
81-
"SPACE"
84+
"SPACE",
85+
"CUSTOM"
8286
]
8387
},
8488
"AnyMedia": {
@@ -2306,6 +2310,9 @@
23062310
],
23072311
"additionalProperties": true
23082312
},
2313+
"CustomMetadata": {
2314+
"$ref": "posts/custom/3.0.0.json"
2315+
},
23092316
"SpaceMetadata": {
23102317
"type": "object",
23112318
"properties": {

scripts/build.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
MetadataIdSchema,
4040
MetadataLicenseTypeSchema,
4141
MintSchema,
42+
CustomSchema,
4243
NamespaceMetadataSchema,
4344
NamespaceRuleMetadataSchema,
4445
Nft721MetadataAttributeSchema,
@@ -77,6 +78,7 @@ const schemas = new Map<string, z.ZodSchema<unknown>>([
7778
['posts/link/3.0.0.json', LinkSchema],
7879
['posts/livestream/3.0.0.json', LiveStreamSchema],
7980
['posts/mint/3.0.0.json', MintSchema],
81+
['posts/custom/3.0.0.json', CustomSchema],
8082
['posts/space/3.0.0.json', SpaceSchema],
8183
['posts/story/3.0.0.json', StorySchema],
8284
['posts/text-only/3.0.0.json', TextOnlySchema],
@@ -216,6 +218,7 @@ async function generateUmbrellaSchema() {
216218
LinkMetadata: LinkSchema,
217219
LiveStreamMetadata: LiveStreamSchema,
218220
MintMetadata: MintSchema,
221+
CustomMetadata: CustomSchema,
219222
SpaceMetadata: SpaceSchema,
220223
TextOnlyMetadata: TextOnlySchema,
221224
StoryMetadata: StorySchema,

src/builders/posts.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ import {
2828
type MintMetadata,
2929
type MintMetadataDetails,
3030
MintSchema,
31+
type CustomMetadata,
32+
type CustomMetadataDetails,
33+
CustomSchema,
3134
PostMainFocus,
3235
PostMetadataSchemaId,
3336
type SpaceMetadata,
@@ -652,6 +655,46 @@ export function mint({
652655
);
653656
}
654657

658+
/**
659+
* @private
660+
* @privateRemarks MUST stay very @private to produce usable docs
661+
*/
662+
type CustomDetails = InputForPostMetadataDetails<CustomMetadataDetails>;
663+
/**
664+
* All {@link CustomMetadataDetails} fields with:
665+
* - `id` defaults to a UUID
666+
* - `locale` defaults to `en`
667+
* - `mainContentFocus` automatically set to `PostSchemaId.CUSTOM_LATEST`
668+
*/
669+
export type CustomOptions = CustomDetails & {
670+
/**
671+
* All the {@link NftMetadata} fields.
672+
*/
673+
nft?: NftDetails;
674+
};
675+
/**
676+
* Creates a valid CustomMetadata.
677+
*/
678+
export function custom({
679+
nft,
680+
locale = DEFAULT_LOCALE,
681+
id = v4(),
682+
...others
683+
}: CustomOptions): CustomMetadata {
684+
return evaluate(
685+
CustomSchema.safeParse({
686+
$schema: PostMetadataSchemaId.CUSTOM_LATEST,
687+
...nft,
688+
lens: {
689+
id,
690+
locale,
691+
mainContentFocus: PostMainFocus.CUSTOM,
692+
...others,
693+
},
694+
}),
695+
);
696+
}
697+
655698
/**
656699
* @private
657700
* @privateRemarks MUST stay very @private to produce usable docs

src/post/CustomSchema.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { z } from 'zod';
2+
3+
import { NonEmptyStringSchema, type Signature } from '../primitives.js';
4+
import type { NftMetadata } from '../tokens/eip721.js';
5+
import { PostMainFocus } from './PostMainFocus.js';
6+
import { PostMetadataSchemaId } from './PostMetadataSchemaId.js';
7+
import {
8+
mainContentFocus,
9+
metadataDetailsWith,
10+
postWith,
11+
type PostMetadataCommon,
12+
} from './common';
13+
14+
export type CustomMetadataDetails = PostMetadataCommon & {
15+
/**
16+
* The main focus of the post.
17+
*/
18+
mainContentFocus: PostMainFocus.CUSTOM;
19+
/**
20+
* A JSON string containing any custom data.
21+
*/
22+
value: string;
23+
};
24+
25+
const CustomMetadataDetailsSchema: z.ZodType<CustomMetadataDetails, z.ZodTypeDef, object> =
26+
metadataDetailsWith({
27+
mainContentFocus: mainContentFocus(PostMainFocus.CUSTOM),
28+
29+
value: NonEmptyStringSchema.describe('A JSON string containing any custom data.'),
30+
});
31+
32+
export type CustomMetadata = NftMetadata & {
33+
/**
34+
* The schema id.
35+
*/
36+
$schema: PostMetadataSchemaId.CUSTOM_LATEST;
37+
/**
38+
* The metadata details.
39+
*/
40+
lens: CustomMetadataDetails;
41+
/**
42+
* A cryptographic signature of the `lens` data.
43+
*/
44+
signature?: Signature;
45+
};
46+
47+
export const CustomSchema = postWith({
48+
$schema: z.literal(PostMetadataSchemaId.CUSTOM_LATEST),
49+
lens: CustomMetadataDetailsSchema,
50+
});

src/post/PostMainFocus.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export enum PostMainFocus {
2020
THREE_D = '3D',
2121
STORY = 'STORY',
2222
SPACE = 'SPACE',
23+
CUSTOM = 'CUSTOM',
2324
}
2425

2526
export const PostMainFocusSchema = z.nativeEnum(PostMainFocus);

src/post/PostMetadataSchemaId.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ export enum PostMetadataSchemaId {
2121
TRANSACTION_LATEST = `${location}/transaction/3.0.0.json`,
2222
TEXT_ONLY_LATEST = `${location}/text-only/3.0.0.json`,
2323
VIDEO_LATEST = `${location}/video/3.0.0.json`,
24+
CUSTOM_LATEST = `${location}/custom/3.0.0.json`,
2425
}

src/post/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export * from './ImageSchema.js';
1111
export * from './LinkSchema.js';
1212
export * from './LiveStreamSchema.js';
1313
export * from './MintSchema.js';
14+
export * from './CustomSchema.js';
1415
export * from './PostMainFocus.js';
1516
export * from './PostMetadataSchemaId.js';
1617
export * from './SpaceSchema.js';
@@ -30,6 +31,7 @@ import { type ImageMetadata, ImageSchema } from './ImageSchema.js';
3031
import { type LinkMetadata, LinkSchema } from './LinkSchema.js';
3132
import { type LiveStreamMetadata, LiveStreamSchema } from './LiveStreamSchema.js';
3233
import { type MintMetadata, MintSchema } from './MintSchema.js';
34+
import { type CustomMetadata, CustomSchema } from './CustomSchema.js';
3335
import { type SpaceMetadata, SpaceSchema } from './SpaceSchema.js';
3436
import { type StoryMetadata, StorySchema } from './StorySchema.js';
3537
import { type TextOnlyMetadata, TextOnlySchema } from './TextOnlySchema.js';
@@ -82,6 +84,7 @@ export type PostMetadata = ShapeCheck<
8284
| LinkMetadata
8385
| LiveStreamMetadata
8486
| MintMetadata
87+
| CustomMetadata
8588
| SpaceMetadata
8689
| TextOnlyMetadata
8790
| StoryMetadata
@@ -124,6 +127,7 @@ export const PostMetadataSchema: z.ZodType<PostMetadata, z.ZodTypeDef, object> =
124127
LinkSchema,
125128
LiveStreamSchema,
126129
MintSchema,
130+
CustomSchema,
127131
SpaceSchema,
128132
TextOnlySchema,
129133
StorySchema,

0 commit comments

Comments
 (0)