@adland/data 0.14.1 → 0.14.3
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/CHANGELOG.md +12 -0
- package/README.md +45 -177
- package/dist/index.cjs +8 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -6
- package/dist/index.d.ts +28 -6
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,217 +1,85 @@
|
|
|
1
1
|
# @adland/data
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Type-safe data schemas, validation, and metadata enrichment for [0xSlots](https://0xslots.org) ad types.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @adland/data
|
|
9
|
-
# or
|
|
10
|
-
pnpm add @adland/data
|
|
11
|
-
# or
|
|
12
|
-
yarn add @adland/data
|
|
13
9
|
```
|
|
14
10
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
### TypeScript Types
|
|
11
|
+
## Ad Types
|
|
18
12
|
|
|
19
|
-
|
|
13
|
+
| Type | Data | Metadata |
|
|
14
|
+
|------|------|----------|
|
|
15
|
+
| `link` | `{ url }` | title, description, image, icon |
|
|
16
|
+
| `cast` | `{ hash }` | username, pfpUrl, text, timestamp |
|
|
17
|
+
| `miniapp` | `{ url }` | icon, title, description, imageUrl |
|
|
18
|
+
| `token` | `{ address, chainId }` | name, symbol, decimals, logoURI |
|
|
19
|
+
| `farcasterProfile` | `{ fid }` | username, displayName, bio, pfpUrl |
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
import type { AdData, LinkAd, SwapAd } from "@adland/data";
|
|
21
|
+
## Usage
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
const linkAd: LinkAd = {
|
|
26
|
-
type: "link",
|
|
27
|
-
url: "https://example.com",
|
|
28
|
-
};
|
|
23
|
+
### Types
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
fromToken: "USDC",
|
|
33
|
-
toToken: "ETH",
|
|
34
|
-
amount: "100",
|
|
35
|
-
};
|
|
25
|
+
```ts
|
|
26
|
+
import type { AdData, AdType, LinkAd, CastAd } from "@adland/data";
|
|
36
27
|
```
|
|
37
28
|
|
|
38
|
-
###
|
|
29
|
+
### Form Validation
|
|
39
30
|
|
|
40
|
-
|
|
31
|
+
Each ad definition exposes a Zod schema — works directly with form libraries:
|
|
41
32
|
|
|
42
|
-
```
|
|
43
|
-
import { linkAdSchema, swapAdSchema, validateAdData } from "@adland/data";
|
|
44
|
-
import { useForm } from "react-hook-form";
|
|
33
|
+
```ts
|
|
45
34
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
35
|
+
import { linkAd } from "@adland/data";
|
|
46
36
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const form = useForm({
|
|
50
|
-
resolver: zodResolver(swapAdSchema),
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// ... rest of form
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Direct validation
|
|
57
|
-
const result = validateAdData(someData);
|
|
58
|
-
if (result.success) {
|
|
59
|
-
console.log("Valid ad data:", result.data);
|
|
60
|
-
} else {
|
|
61
|
-
console.error("Validation errors:", result.error);
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Combining Schemas
|
|
66
|
-
|
|
67
|
-
Zod makes it easy to extend and combine schemas:
|
|
68
|
-
|
|
69
|
-
```tsx
|
|
70
|
-
import { linkAdSchema } from "@adland/data";
|
|
71
|
-
import { z } from "zod";
|
|
72
|
-
|
|
73
|
-
// Extend a schema
|
|
74
|
-
const customLinkSchema = linkAdSchema.extend({
|
|
75
|
-
title: z.string(),
|
|
76
|
-
description: z.string().optional(),
|
|
37
|
+
const form = useForm({
|
|
38
|
+
resolver: zodResolver(linkAd.data),
|
|
77
39
|
});
|
|
78
|
-
|
|
79
|
-
// Combine schemas
|
|
80
|
-
const adWithMetadata = z.intersection(
|
|
81
|
-
linkAdSchema,
|
|
82
|
-
z.object({ metadata: z.record(z.unknown()) })
|
|
83
|
-
);
|
|
84
40
|
```
|
|
85
41
|
|
|
86
|
-
|
|
42
|
+
### Processing Pipeline
|
|
87
43
|
|
|
88
|
-
|
|
89
|
-
Basic link ad type.
|
|
44
|
+
Validate, verify against external sources, and enrich with metadata in one call:
|
|
90
45
|
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
type: "link";
|
|
94
|
-
url: string;
|
|
95
|
-
}
|
|
96
|
-
```
|
|
46
|
+
```ts
|
|
47
|
+
import { linkAd } from "@adland/data";
|
|
97
48
|
|
|
98
|
-
|
|
99
|
-
Farcaster cast link ad type.
|
|
49
|
+
const result = await linkAd.safeProcess({ url: "https://example.com" });
|
|
100
50
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
url: string;
|
|
51
|
+
if (result.success) {
|
|
52
|
+
console.log(result.data); // validated input
|
|
53
|
+
console.log(result.metadata); // { title, description, image, icon }
|
|
105
54
|
}
|
|
106
55
|
```
|
|
107
56
|
|
|
108
|
-
###
|
|
109
|
-
Farcaster mini app link ad type.
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
type MiniAppAd = {
|
|
113
|
-
type: "miniapp";
|
|
114
|
-
url: string;
|
|
115
|
-
}
|
|
116
|
-
```
|
|
57
|
+
### Registry
|
|
117
58
|
|
|
118
|
-
|
|
119
|
-
|
|
59
|
+
```ts
|
|
60
|
+
import { ads, getAd, validateAdData } from "@adland/data";
|
|
120
61
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
type: "token";
|
|
124
|
-
token: string; // Token address or symbol
|
|
125
|
-
}
|
|
62
|
+
const castDef = getAd("cast");
|
|
63
|
+
const result = validateAdData({ type: "cast", data: { hash: "0x..." } });
|
|
126
64
|
```
|
|
127
65
|
|
|
128
|
-
###
|
|
129
|
-
Token swap ad type.
|
|
66
|
+
### Farcaster Utilities
|
|
130
67
|
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
type: "swap";
|
|
134
|
-
fromToken: string; // Token address or symbol
|
|
135
|
-
toToken: string; // Token address or symbol
|
|
136
|
-
amount?: string; // Optional amount
|
|
137
|
-
}
|
|
138
|
-
```
|
|
68
|
+
```ts
|
|
69
|
+
import { parseAccountAssociation, FarcasterAPI } from "@adland/data";
|
|
139
70
|
|
|
140
|
-
|
|
71
|
+
const parsed = parseAccountAssociation(accountAssociation);
|
|
72
|
+
// => { fid, address, type, domain }
|
|
73
|
+
```
|
|
141
74
|
|
|
142
|
-
|
|
75
|
+
## How It Works
|
|
143
76
|
|
|
144
|
-
|
|
145
|
-
- `AdData` - Union type of all ad data objects (discriminated union)
|
|
146
|
-
- `LinkAd` - Link ad type
|
|
147
|
-
- `CastAd` - Cast ad type
|
|
148
|
-
- `MiniAppAd` - MiniApp ad type
|
|
149
|
-
- `TokenAd` - Token ad type
|
|
150
|
-
- `SwapAd` - Swap ad type
|
|
151
|
-
|
|
152
|
-
### Schemas
|
|
153
|
-
|
|
154
|
-
- `linkAdSchema` - Zod schema for link ads
|
|
155
|
-
- `castAdSchema` - Zod schema for cast ads
|
|
156
|
-
- `miniappAdSchema` - Zod schema for mini app ads
|
|
157
|
-
- `tokenAdSchema` - Zod schema for token ads
|
|
158
|
-
- `swapAdSchema` - Zod schema for swap ads
|
|
159
|
-
- `adDataSchema` - Discriminated union schema for all ad types
|
|
160
|
-
- `adSchemas` - Object containing all schemas
|
|
161
|
-
- `getAdSchema(type)` - Get schema for a specific ad type
|
|
162
|
-
- `getAllAdSchemas()` - Get all ad schemas
|
|
163
|
-
- `validateAdData(data)` - Validate ad data and return result
|
|
164
|
-
|
|
165
|
-
## Integration Examples
|
|
166
|
-
|
|
167
|
-
### React Hook Form
|
|
168
|
-
|
|
169
|
-
```tsx
|
|
170
|
-
import { useForm } from "react-hook-form";
|
|
171
|
-
import { zodResolver } from "@hookform/resolvers/zod";
|
|
172
|
-
import { swapAdSchema, type SwapAd } from "@adland/data";
|
|
173
|
-
|
|
174
|
-
function SwapForm() {
|
|
175
|
-
const form = useForm<SwapAd>({
|
|
176
|
-
resolver: zodResolver(swapAdSchema),
|
|
177
|
-
defaultValues: {
|
|
178
|
-
type: "swap",
|
|
179
|
-
fromToken: "",
|
|
180
|
-
toToken: "",
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
return (
|
|
185
|
-
<form onSubmit={form.handleSubmit(onSubmit)}>
|
|
186
|
-
{/* form fields */}
|
|
187
|
-
</form>
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
```
|
|
77
|
+
Each ad definition created with `defineAd()` provides:
|
|
191
78
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
import { swapAdSchema } from "@adland/data";
|
|
197
|
-
import { toFormikValidationSchema } from "zod-formik-adapter";
|
|
198
|
-
|
|
199
|
-
function SwapForm() {
|
|
200
|
-
return (
|
|
201
|
-
<Formik
|
|
202
|
-
validationSchema={toFormikValidationSchema(swapAdSchema)}
|
|
203
|
-
initialValues={{
|
|
204
|
-
type: "swap" as const,
|
|
205
|
-
fromToken: "",
|
|
206
|
-
toToken: "",
|
|
207
|
-
}}
|
|
208
|
-
onSubmit={handleSubmit}
|
|
209
|
-
>
|
|
210
|
-
{/* form */}
|
|
211
|
-
</Formik>
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
```
|
|
79
|
+
1. **Zod schema** — runtime data validation
|
|
80
|
+
2. **`verify(data)`** — checks validity against external sources (API, blockchain)
|
|
81
|
+
3. **`getMetadata(data)`** — fetches rich metadata (titles, images, etc.)
|
|
82
|
+
4. **`process(data)` / `safeProcess(data)`** — runs the full pipeline
|
|
215
83
|
|
|
216
84
|
## License
|
|
217
85
|
|
package/dist/index.cjs
CHANGED
|
@@ -8,6 +8,9 @@ var zod = require('zod');
|
|
|
8
8
|
var adlandApiUrl = process.env.NODE_ENV === "development" ? "http://localhost:3069" : "https://api.0xslots.org";
|
|
9
9
|
|
|
10
10
|
// src/core/ad-definition.ts
|
|
11
|
+
function withChoices(schema, choices) {
|
|
12
|
+
return Object.assign(schema, { choices });
|
|
13
|
+
}
|
|
11
14
|
function defineAd(def) {
|
|
12
15
|
return {
|
|
13
16
|
...def,
|
|
@@ -212,7 +215,10 @@ var tokenAd = defineAd({
|
|
|
212
215
|
type: "token",
|
|
213
216
|
data: zod.z.object({
|
|
214
217
|
address: zod.z.string().nonempty("Address is required"),
|
|
215
|
-
chainId:
|
|
218
|
+
chainId: withChoices(
|
|
219
|
+
zod.z.number().int().positive("Chain ID is required").refine((chainId) => [8453].includes(chainId), "Invalid chain ID"),
|
|
220
|
+
[{ label: "Base (8453)", value: 8453 }]
|
|
221
|
+
)
|
|
216
222
|
}),
|
|
217
223
|
metadata: zod.z.object({
|
|
218
224
|
name: zod.z.string().optional(),
|
|
@@ -410,5 +416,6 @@ exports.processAd = processAd;
|
|
|
410
416
|
exports.safeProcessAd = safeProcessAd;
|
|
411
417
|
exports.tokenAd = tokenAd;
|
|
412
418
|
exports.validateAdData = validateAdData;
|
|
419
|
+
exports.withChoices = withChoices;
|
|
413
420
|
//# sourceMappingURL=index.cjs.map
|
|
414
421
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/core/ad-definition.ts","../src/services/adland.api.ts","../src/ads/cast.ts","../src/ads/link.ts","../src/ads/miniapp.ts","../src/ads/token.ts","../src/ads/profile.ts","../src/farcaster.ts","../src/index.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["export const adlandApiUrl =\n process.env.NODE_ENV === \"development\"\n ? \"http://localhost:3069\"\n : \"https://api.0xslots.org\";\n\nexport const debug = true;\n","import { z } from \"zod\";\nimport { debug } from \"../constants\";\n\n/**\n * Ad Definition type\n * Represents a data contract + behavior for an ad type\n */\nexport type AdDefinition<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined = undefined,\n> = {\n /**\n * The literal type string for this ad (e.g., \"cast\", \"link\")\n */\n type: string;\n\n /**\n * The Zod schema for the ad's data field\n */\n data: TData;\n\n /**\n * Optional Zod schema for the ad's metadata field\n */\n metadata?: TMetadata;\n\n /**\n * Optional verification function that runs after parsing\n * Receives already-validated data\n */\n verify?: (data: z.infer<TData>) => Promise<void>;\n\n /**\n * Optional metadata enrichment function\n * Only available if metadata schema is defined\n */\n getMetadata?: (\n data: z.infer<TData>,\n ) => Promise<TMetadata extends z.ZodTypeAny ? z.infer<TMetadata> : never>;\n};\n\n/**\n * Typed helper to define an ad\n * Locks type inference and prevents widening\n * Adds a `process` method for convenience\n * @param def - Ad definition object\n * @returns The same definition with proper types and a process method\n */\nexport function defineAd<\n const TData extends z.ZodTypeAny,\n const TMetadata extends z.ZodTypeAny | undefined,\n>(\n def: AdDefinition<TData, TMetadata>,\n): AdDefinition<TData, TMetadata> & {\n /**\n * Process this ad through the full pipeline: parse → verify → getMetadata\n * @param input - Raw input data to process\n * @returns Processed data and optional metadata\n */\n process: (input: z.infer<TData>) => Promise<{\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n }>;\n /**\n * Safe version of process that returns a result object\n * @param input - Raw input data to process\n * @returns Result object with success flag and data or error\n */\n safeProcess: (input: z.infer<TData>) => Promise<{\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n }>;\n} {\n return {\n ...def,\n process: (input: z.infer<TData>) => processAd(def, input),\n safeProcess: (input: z.infer<TData>) => safeProcessAd(def, input),\n };\n}\n\n/**\n * Process an ad through the full pipeline: parse → verify → getMetadata\n * @param ad - Ad definition\n * @param input - Raw input data to process\n * @returns Processed data and optional metadata\n */\nexport async function processAd<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined,\n>(\n ad: AdDefinition<TData, TMetadata>,\n input: z.infer<TData>,\n): Promise<{\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n}> {\n if (debug) {\n console.log(\"processAd:input\", input);\n }\n // Parse and validate\n const data: z.infer<TData> = ad.data.parse(input);\n\n if (debug) {\n console.log(\"processAd:data\", data);\n }\n\n // Verify if function is provided\n if (ad.verify) {\n await ad.verify(input);\n }\n\n // Get metadata if function and schema are provided\n const metadata =\n ad.getMetadata && ad.metadata ? await ad.getMetadata(data) : undefined;\n\n return { data, metadata, type: ad.type } as {\n type: string;\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n };\n}\n\n/**\n * Safe version of processAd that returns a result object\n * @param ad - Ad definition\n * @param input - Raw input data to process\n * @returns Result object with success flag and data or error\n */\nexport async function safeProcessAd<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined,\n>(\n ad: AdDefinition<TData, TMetadata>,\n input: unknown,\n): Promise<{\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n}> {\n // Safe parse\n const parseResult = ad.data.safeParse(input);\n if (!parseResult.success) {\n return {\n success: false,\n error: parseResult.error,\n };\n }\n\n const data: z.infer<TData> = parseResult.data;\n\n // Verify if function is provided\n if (ad.verify) {\n try {\n await ad.verify(data);\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Verification failed\",\n };\n }\n }\n\n // Get metadata if function and schema are provided\n const metadata =\n ad.getMetadata && ad.metadata ? await ad.getMetadata(data) : undefined;\n\n return {\n success: true,\n data,\n metadata,\n } as {\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n };\n}\n","import { adlandApiUrl } from \"../constants\";\n\nclass AdlandAPI {\n constructor() {}\n\n async verifyCast({ hash }: { hash: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/cast`, {\n hash,\n });\n }\n\n async verifyMiniapp({ domain }: { domain: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/miniapp`, {\n domain,\n });\n }\n\n async getMiniappMetadata({ url }: { url: string }): Promise<{\n title: string;\n icon: string;\n description: string;\n imageUrl: string;\n }> {\n return this.get<{\n title: string;\n icon: string;\n description: string;\n imageUrl: string;\n }>(`${adlandApiUrl}/metadata/miniapp?url=${encodeURIComponent(url)}`);\n }\n\n async getLinkMetadata({ url }: { url: string }): Promise<{\n title: string;\n description: string;\n image: string;\n icon: string;\n }> {\n return this.get<{\n title: string;\n description: string;\n image: string;\n icon: string;\n }>(`${adlandApiUrl}/metadata/link?url=${encodeURIComponent(url)}`);\n }\n\n async getCastMetadata({ hash }: { hash: string }): Promise<{\n username: string;\n pfpUrl: string;\n text: string;\n timestamp: number;\n }> {\n return this.get<{\n username: string;\n pfpUrl: string;\n text: string;\n timestamp: number;\n }>(`${adlandApiUrl}/metadata/cast?hash=${encodeURIComponent(hash)}`);\n }\n\n async verifyFarcasterProfile({ fid }: { fid: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/profile`, {\n fid,\n });\n }\n\n async getFarcasterProfile({ fid }: { fid: string }): Promise<{\n pfpUrl: string;\n bio: string;\n username: string;\n displayName?: string;\n followers: number;\n following: number;\n pro: boolean;\n }> {\n return this.get<{\n pfpUrl: string;\n bio: string;\n username: string;\n displayName?: string;\n followers: number;\n following: number;\n pro: boolean;\n }>(`${adlandApiUrl}/metadata/profile?fid=${encodeURIComponent(fid)}`);\n }\n\n async verifyToken({\n address,\n chainId,\n }: {\n address: string;\n chainId: number;\n }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/token`, {\n address,\n chainId,\n });\n }\n\n async getTokenMetadata({\n address,\n chainId,\n }: {\n address: string;\n chainId: number;\n }): Promise<{\n name: string;\n symbol: string;\n decimals: number;\n logoURI: string;\n }> {\n return this.get<{\n name: string;\n symbol: string;\n decimals: number;\n logoURI: string;\n }>(\n `${adlandApiUrl}/metadata/token?address=${encodeURIComponent(address)}&chainId=${chainId}`,\n );\n }\n\n private async post<T>(url: string, body: object): Promise<T> {\n return fetch(url, {\n method: \"POST\",\n body: JSON.stringify(body),\n }).then((res) => res.json()) as T;\n }\n\n private async get<T>(url: string): Promise<T> {\n return fetch(url).then((res) => res.json()) as T;\n }\n}\n\nexport const adlandAPI = new AdlandAPI();\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * Cast Ad Definition\n * Represents a Farcaster cast ad with validation and verification\n */\nexport const castAd = defineAd({\n type: \"cast\",\n data: z.object({\n hash: z.string().nonempty(\"Hash is required\"),\n }),\n metadata: z.object({\n username: z.string().optional(),\n pfpUrl: z.string().optional(),\n text: z.string().optional(),\n timestamp: z.number().optional(),\n }),\n async verify({ hash }) {\n if (!/^0x[0-9a-fA-F]{40}$/.test(hash)) {\n throw new Error(\"Invalid Farcaster cast hash\");\n }\n\n const res = await adlandAPI.verifyCast({ hash });\n if (!res.verified) {\n throw new Error(\"Cast hash verification failed\");\n }\n },\n async getMetadata({ hash }) {\n const cast = await adlandAPI.getCastMetadata({ hash });\n return {\n username: cast.username,\n pfpUrl: cast.pfpUrl,\n text: cast.text,\n timestamp: cast.timestamp,\n };\n },\n});\n\n/**\n * Type inference for CastAd data\n */\nexport type CastAdData = z.infer<typeof castAd.data>;\n\n/**\n * Type inference for CastAd metadata\n */\nexport type CastAdMetadata = z.infer<NonNullable<typeof castAd.metadata>>;\n\nexport type CastAd = {\n type: \"cast\";\n data: CastAdData;\n metadata: CastAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * Link Ad Definition\n * Represents a basic link ad with validation and verification\n */\nexport const linkAd = defineAd({\n type: \"link\",\n\n data: z.object({\n url: z.string().nonempty(\"URL is required\"),\n }),\n metadata: z.object({\n title: z.string().optional(),\n description: z.string().optional(),\n image: z.string().optional(),\n icon: z.string().optional(),\n }),\n async verify({ url }) {\n if (!url.startsWith(\"http\")) {\n throw new Error(\"Invalid link\");\n }\n },\n async getMetadata({ url }) {\n const metadata = await adlandAPI.getLinkMetadata({ url });\n return {\n title: metadata.title,\n description: metadata.description,\n image: metadata.image,\n icon: metadata.icon,\n };\n },\n});\n\n/**\n * Type inference for LinkAd data\n */\nexport type LinkAdData = z.infer<typeof linkAd.data>;\n\n/**\n * Type inference for LinkAd metadata\n */\nexport type LinkAdMetadata = z.infer<NonNullable<typeof linkAd.metadata>>;\n\nexport type LinkAd = {\n type: \"link\";\n data: LinkAdData;\n metadata: LinkAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * MiniApp Ad Definition\n * Represents a Farcaster mini app ad with validation and verification\n */\nexport const miniappAd = defineAd({\n type: \"miniapp\",\n\n data: z.object({\n url: z.string().nonempty(\"URL is required\"),\n }),\n\n metadata: z.object({\n icon: z.string().optional(),\n title: z.string().optional(),\n description: z.string().optional(),\n imageUrl: z.string().optional(),\n }),\n\n async verify({ url }) {\n const errorMessage = \"Miniapp domain verification failed\";\n const domain = url.split(\"//\")[1];\n console.log(\"verifyMiniapp:domain\", domain);\n if (!domain) {\n throw new Error(errorMessage);\n }\n const res = await adlandAPI.verifyMiniapp({ domain });\n console.log(\"verifyMiniapp:res\", res);\n if (!res.verified) {\n throw new Error(errorMessage);\n }\n },\n async getMetadata({ url }) {\n const res = await adlandAPI.getMiniappMetadata({ url });\n console.log(\"getMetadata:res\", res);\n return {\n icon: res.icon,\n title: res.title,\n description: res.description,\n imageUrl: res.imageUrl,\n };\n },\n});\n\n/**\n * Type inference for MiniAppAd data\n */\nexport type MiniAppAdData = z.infer<typeof miniappAd.data>;\n\n/**\n * Type inference for MiniAppAd metadata\n */\nexport type MiniAppAdMetadata = z.infer<NonNullable<typeof miniappAd.metadata>>;\n\nexport type MiniAppAd = {\n type: \"miniapp\";\n data: MiniAppAdData;\n metadata: MiniAppAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\nexport const tokenAd = defineAd({\n type: \"token\",\n data: z.object({\n address: z.string().nonempty(\"Address is required\"),\n chainId: z\n .number()\n .int()\n .positive(\"Chain ID is required\")\n .refine((chainId) => [8453].includes(chainId), \"Invalid chain ID\"),\n }),\n metadata: z.object({\n name: z.string().optional(),\n symbol: z.string().optional(),\n decimals: z.number().optional(),\n logoURI: z.string().optional(),\n }),\n async verify({ address, chainId }) {\n const res = await adlandAPI.verifyToken({ address, chainId });\n if (!res.verified) {\n throw new Error(\"Token verification failed\");\n }\n },\n async getMetadata({ address, chainId }) {\n const token = await adlandAPI.getTokenMetadata({ address, chainId });\n return {\n name: token.name,\n symbol: token.symbol,\n decimals: token.decimals,\n logoURI: token.logoURI,\n };\n },\n});\n\nexport type TokenAdData = z.infer<typeof tokenAd.data>;\nexport type TokenAdMetadata = z.infer<NonNullable<typeof tokenAd.metadata>>;\nexport type TokenAd = {\n type: \"token\";\n data: TokenAdData;\n metadata: TokenAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\nexport const farcasterProfileAd = defineAd({\n type: \"farcasterProfile\",\n data: z.object({\n fid: z.string().nonempty(\"Fid is required\"),\n }),\n metadata: z.object({\n pfpUrl: z.string().optional(),\n bio: z.string().optional(),\n username: z.string().optional(),\n displayName: z.string().optional(),\n followers: z.number().optional(),\n following: z.number().optional(),\n pro: z.boolean().optional(),\n }),\n async verify({ fid }) {\n const res = await adlandAPI.verifyFarcasterProfile({ fid });\n if (!res.verified) {\n throw new Error(\"Farcaster profile verification failed\");\n }\n },\n async getMetadata({ fid }) {\n const res = await adlandAPI.getFarcasterProfile({ fid });\n return {\n pfpUrl: res.pfpUrl,\n bio: res.bio,\n username: res.username,\n displayName: res.displayName,\n followers: res.followers,\n following: res.following,\n pro: res.pro,\n };\n },\n});\n\nexport type FarcasterProfileAdData = z.infer<typeof farcasterProfileAd.data>;\nexport type FarcasterProfileAdMetadata = z.infer<\n NonNullable<typeof farcasterProfileAd.metadata>\n>;\nexport type FarcasterProfileAd = {\n type: \"farcasterProfile\";\n data: FarcasterProfileAdData;\n metadata: FarcasterProfileAdMetadata;\n};\n","import { Manifest } from \"@farcaster/miniapp-sdk\";\n\n/**\n * Utility functions to parse accountAssociation from Mini App manifest\n *\n * The accountAssociation is a JSON Farcaster Signature (JFS) that contains:\n * - header: base64url encoded JSON with FID, type, and key (address)\n * - payload: base64url encoded JSON with domain\n * - signature: base64url encoded signature\n */\n\ninterface AccountAssociationHeader {\n fid: number;\n type: \"custody\" | \"auth\";\n key: string; // The address (e.g., \"0x...\")\n}\n\ninterface AccountAssociationPayload {\n domain: string;\n}\n\ninterface AccountAssociation {\n header: string; // base64url encoded\n payload: string; // base64url encoded\n signature: string; // base64url encoded\n}\n\nexport interface ParsedAccountAssociation {\n fid: number;\n address: string; // Ethereum address (0x...)\n type: \"custody\" | \"auth\";\n domain: string;\n}\n\n/**\n * Decode base64url encoded string to JSON object\n */\nfunction decodeBase64Url<T>(encoded: string): T {\n // Replace URL-safe characters with standard base64 characters\n let base64 = encoded.replace(/-/g, \"+\").replace(/_/g, \"/\");\n\n // Add padding if needed\n while (base64.length % 4) {\n base64 += \"=\";\n }\n\n // Node.js environment\n const decoded = Buffer.from(base64, \"base64\").toString(\"utf-8\");\n return JSON.parse(decoded) as T;\n}\n\n/**\n * Parse accountAssociation to extract FID and address\n *\n * @param accountAssociation - The accountAssociation object from manifest\n * @returns Parsed object with FID, address, type, and domain\n */\nexport function parseAccountAssociation(\n accountAssociation: AccountAssociation,\n): ParsedAccountAssociation {\n try {\n // Decode the header to get FID, type, and key (address)\n const header: AccountAssociationHeader = decodeBase64Url(\n accountAssociation.header,\n );\n\n // Decode the payload to get domain\n const payload: AccountAssociationPayload = decodeBase64Url(\n accountAssociation.payload,\n );\n\n return {\n fid: header.fid,\n address: header.key, // The key is the Ethereum address\n type: header.type,\n domain: payload.domain,\n };\n } catch (error) {\n throw new Error(\n `Failed to parse accountAssociation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n}\n\n/**\n * Fetch and parse accountAssociation from a manifest URL\n *\n * @param manifestUrl - URL to the manifest (e.g., \"https://example.com/.well-known/farcaster.json\")\n * @returns Parsed accountAssociation\n */\nexport async function fetchAndParseAccountAssociation(\n manifestUrl: string,\n): Promise<ParsedAccountAssociation> {\n try {\n const response = await fetch(manifestUrl);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch manifest: ${response.status} ${response.statusText}`,\n );\n }\n\n const manifest = (await response.json()) as any;\n\n if (!manifest.accountAssociation) {\n throw new Error(\"Manifest does not contain accountAssociation\");\n }\n\n return parseAccountAssociation(manifest.accountAssociation);\n } catch (error) {\n throw new Error(\n `Failed to fetch and parse accountAssociation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n}\n\nexport class FarcasterAPI {\n private readonly apiKey: string;\n\n constructor(apiKey: string) {\n this.apiKey = apiKey;\n }\n\n async getDomainManifest(domain: string) {\n const response = await fetch(\n `https://client.farcaster.xyz/v1/domain-manifest?domain=${domain}`,\n {\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n },\n },\n );\n if (!response.ok) {\n throw new Error(\n `Failed to fetch domain manifest: ${response.status} ${response.statusText}`,\n );\n }\n const data = (await response.json()) as {\n result: {\n state: {\n verified: boolean;\n updatedAt: number; // timestamp\n manifest: string;\n };\n };\n };\n\n console.log(\"FarcasterAPI:data\", data);\n\n return {\n ...data.result.state,\n manifest: JSON.parse(data.result.state.manifest) as Manifest.Manifest,\n };\n }\n}\n","import { z } from \"zod\";\nimport { castAd } from \"./ads/cast\";\nimport { linkAd } from \"./ads/link\";\nimport { miniappAd } from \"./ads/miniapp\";\nimport type { CastAd } from \"./ads/cast\";\nimport type { LinkAd } from \"./ads/link\";\nimport type { MiniAppAd } from \"./ads/miniapp\";\nimport type { TokenAd } from \"./ads/token\";\nimport type { FarcasterProfileAd } from \"./ads/profile\";\nimport { tokenAd } from \"./ads/token\";\nimport { farcasterProfileAd } from \"./ads/profile\";\n\n/**\n * Union type for all complete ad structures with type, data, and optional metadata\n */\nexport type AdData = CastAd | LinkAd | MiniAppAd | TokenAd | FarcasterProfileAd;\n\n/**\n * Registry of all ad definitions\n * Each entry is an AdDefinition object\n */\nexport const ads = {\n link: linkAd,\n cast: castAd,\n miniapp: miniappAd,\n token: tokenAd,\n farcasterProfile: farcasterProfileAd,\n} as const;\n\nexport const adTypes = [\n \"link\",\n \"cast\",\n \"miniapp\",\n \"token\",\n \"farcasterProfile\",\n] as const;\n\n/**\n * Type for ad definition keys\n */\nexport type AdType = keyof typeof ads;\n\n/**\n * Get ad definition by type\n */\nexport function getAd(type: AdType) {\n return ads[type];\n}\n/**\n * Validate ad data against any ad definition\n */\nexport function validateAdData(data: any): {\n success: boolean;\n data?: {\n type: AdType;\n data: unknown;\n };\n error?: z.ZodError | string;\n} {\n const dataType = data.type;\n if (!dataType || !adTypes.includes(dataType)) {\n return {\n success: false,\n error: \"Data does not match any known ad type\",\n };\n }\n const ad = getAd(data.type);\n\n const result = ad.data.safeParse(data.data);\n if (!result.success) {\n return {\n success: false,\n error: result.error,\n };\n }\n\n return {\n success: true,\n data: {\n type: dataType,\n data: result.data,\n },\n };\n}\n\n// Export all ad definitions\nexport * from \"./ads\";\n\n// Export core utilities\nexport * from \"./core/ad-definition\";\n\n// Export constants\nexport { adlandApiUrl } from \"./constants\";\n\n// Export Farcaster utilities\nexport * from \"./farcaster\";\n\n// Backward compatibility aliases\nexport const adDefinitions = ads;\nexport const adModels = ads;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/core/ad-definition.ts","../src/services/adland.api.ts","../src/ads/cast.ts","../src/ads/link.ts","../src/ads/miniapp.ts","../src/ads/token.ts","../src/ads/profile.ts","../src/farcaster.ts","../src/index.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["export const adlandApiUrl =\n process.env.NODE_ENV === \"development\"\n ? \"http://localhost:3069\"\n : \"https://api.0xslots.org\";\n\nexport const debug = true;\n","import type { z } from \"zod\";\nimport { debug } from \"../constants\";\n\nexport type FieldChoice<T> = { label: string; value: T };\n\n/**\n * Attach a list of allowed choices to any Zod schema as metadata.\n * The underlying schema and its validation are unchanged — this only\n * annotates the field so that form builders can render a <select>.\n */\nexport function withChoices<T extends z.ZodTypeAny>(\n schema: T,\n choices: ReadonlyArray<FieldChoice<z.infer<T>>>,\n): T & { choices: ReadonlyArray<FieldChoice<z.infer<T>>> } {\n return Object.assign(schema, { choices });\n}\n\n/**\n * Ad Definition type\n * Represents a data contract + behavior for an ad type\n */\nexport type AdDefinition<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined = undefined,\n> = {\n /**\n * The literal type string for this ad (e.g., \"cast\", \"link\")\n */\n type: string;\n\n /**\n * The Zod schema for the ad's data field\n */\n data: TData;\n\n /**\n * Optional Zod schema for the ad's metadata field\n */\n metadata?: TMetadata;\n\n /**\n * Optional verification function that runs after parsing\n * Receives already-validated data\n */\n verify?: (data: z.infer<TData>) => Promise<void>;\n\n /**\n * Optional metadata enrichment function\n * Only available if metadata schema is defined\n */\n getMetadata?: (\n data: z.infer<TData>,\n ) => Promise<TMetadata extends z.ZodTypeAny ? z.infer<TMetadata> : never>;\n};\n\n/**\n * Typed helper to define an ad\n * Locks type inference and prevents widening\n * Adds a `process` method for convenience\n * @param def - Ad definition object\n * @returns The same definition with proper types and a process method\n */\nexport function defineAd<\n const TData extends z.ZodTypeAny,\n const TMetadata extends z.ZodTypeAny | undefined,\n>(\n def: AdDefinition<TData, TMetadata>,\n): AdDefinition<TData, TMetadata> & {\n /**\n * Process this ad through the full pipeline: parse → verify → getMetadata\n * @param input - Raw input data to process\n * @returns Processed data and optional metadata\n */\n process: (input: z.infer<TData>) => Promise<{\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n }>;\n /**\n * Safe version of process that returns a result object\n * @param input - Raw input data to process\n * @returns Result object with success flag and data or error\n */\n safeProcess: (input: z.infer<TData>) => Promise<{\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n }>;\n} {\n return {\n ...def,\n process: (input: z.infer<TData>) => processAd(def, input),\n safeProcess: (input: z.infer<TData>) => safeProcessAd(def, input),\n };\n}\n\n/**\n * Process an ad through the full pipeline: parse → verify → getMetadata\n * @param ad - Ad definition\n * @param input - Raw input data to process\n * @returns Processed data and optional metadata\n */\nexport async function processAd<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined,\n>(\n ad: AdDefinition<TData, TMetadata>,\n input: z.infer<TData>,\n): Promise<{\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n}> {\n if (debug) {\n console.log(\"processAd:input\", input);\n }\n // Parse and validate\n const data: z.infer<TData> = ad.data.parse(input);\n\n if (debug) {\n console.log(\"processAd:data\", data);\n }\n\n // Verify if function is provided\n if (ad.verify) {\n await ad.verify(input);\n }\n\n // Get metadata if function and schema are provided\n const metadata =\n ad.getMetadata && ad.metadata ? await ad.getMetadata(data) : undefined;\n\n return { data, metadata, type: ad.type } as {\n type: string;\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n };\n}\n\n/**\n * Safe version of processAd that returns a result object\n * @param ad - Ad definition\n * @param input - Raw input data to process\n * @returns Result object with success flag and data or error\n */\nexport async function safeProcessAd<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined,\n>(\n ad: AdDefinition<TData, TMetadata>,\n input: unknown,\n): Promise<{\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n}> {\n // Safe parse\n const parseResult = ad.data.safeParse(input);\n if (!parseResult.success) {\n return {\n success: false,\n error: parseResult.error,\n };\n }\n\n const data: z.infer<TData> = parseResult.data;\n\n // Verify if function is provided\n if (ad.verify) {\n try {\n await ad.verify(data);\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Verification failed\",\n };\n }\n }\n\n // Get metadata if function and schema are provided\n const metadata =\n ad.getMetadata && ad.metadata ? await ad.getMetadata(data) : undefined;\n\n return {\n success: true,\n data,\n metadata,\n } as {\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n };\n}\n","import { adlandApiUrl } from \"../constants\";\n\nclass AdlandAPI {\n constructor() {}\n\n async verifyCast({ hash }: { hash: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/cast`, {\n hash,\n });\n }\n\n async verifyMiniapp({ domain }: { domain: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/miniapp`, {\n domain,\n });\n }\n\n async getMiniappMetadata({ url }: { url: string }): Promise<{\n title: string;\n icon: string;\n description: string;\n imageUrl: string;\n }> {\n return this.get<{\n title: string;\n icon: string;\n description: string;\n imageUrl: string;\n }>(`${adlandApiUrl}/metadata/miniapp?url=${encodeURIComponent(url)}`);\n }\n\n async getLinkMetadata({ url }: { url: string }): Promise<{\n title: string;\n description: string;\n image: string;\n icon: string;\n }> {\n return this.get<{\n title: string;\n description: string;\n image: string;\n icon: string;\n }>(`${adlandApiUrl}/metadata/link?url=${encodeURIComponent(url)}`);\n }\n\n async getCastMetadata({ hash }: { hash: string }): Promise<{\n username: string;\n pfpUrl: string;\n text: string;\n timestamp: number;\n }> {\n return this.get<{\n username: string;\n pfpUrl: string;\n text: string;\n timestamp: number;\n }>(`${adlandApiUrl}/metadata/cast?hash=${encodeURIComponent(hash)}`);\n }\n\n async verifyFarcasterProfile({ fid }: { fid: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/profile`, {\n fid,\n });\n }\n\n async getFarcasterProfile({ fid }: { fid: string }): Promise<{\n pfpUrl: string;\n bio: string;\n username: string;\n displayName?: string;\n followers: number;\n following: number;\n pro: boolean;\n }> {\n return this.get<{\n pfpUrl: string;\n bio: string;\n username: string;\n displayName?: string;\n followers: number;\n following: number;\n pro: boolean;\n }>(`${adlandApiUrl}/metadata/profile?fid=${encodeURIComponent(fid)}`);\n }\n\n async verifyToken({\n address,\n chainId,\n }: {\n address: string;\n chainId: number;\n }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/token`, {\n address,\n chainId,\n });\n }\n\n async getTokenMetadata({\n address,\n chainId,\n }: {\n address: string;\n chainId: number;\n }): Promise<{\n name: string;\n symbol: string;\n decimals: number;\n logoURI: string;\n }> {\n return this.get<{\n name: string;\n symbol: string;\n decimals: number;\n logoURI: string;\n }>(\n `${adlandApiUrl}/metadata/token?address=${encodeURIComponent(address)}&chainId=${chainId}`,\n );\n }\n\n private async post<T>(url: string, body: object): Promise<T> {\n return fetch(url, {\n method: \"POST\",\n body: JSON.stringify(body),\n }).then((res) => res.json()) as T;\n }\n\n private async get<T>(url: string): Promise<T> {\n return fetch(url).then((res) => res.json()) as T;\n }\n}\n\nexport const adlandAPI = new AdlandAPI();\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * Cast Ad Definition\n * Represents a Farcaster cast ad with validation and verification\n */\nexport const castAd = defineAd({\n type: \"cast\",\n data: z.object({\n hash: z.string().nonempty(\"Hash is required\"),\n }),\n metadata: z.object({\n username: z.string().optional(),\n pfpUrl: z.string().optional(),\n text: z.string().optional(),\n timestamp: z.number().optional(),\n }),\n async verify({ hash }) {\n if (!/^0x[0-9a-fA-F]{40}$/.test(hash)) {\n throw new Error(\"Invalid Farcaster cast hash\");\n }\n\n const res = await adlandAPI.verifyCast({ hash });\n if (!res.verified) {\n throw new Error(\"Cast hash verification failed\");\n }\n },\n async getMetadata({ hash }) {\n const cast = await adlandAPI.getCastMetadata({ hash });\n return {\n username: cast.username,\n pfpUrl: cast.pfpUrl,\n text: cast.text,\n timestamp: cast.timestamp,\n };\n },\n});\n\n/**\n * Type inference for CastAd data\n */\nexport type CastAdData = z.infer<typeof castAd.data>;\n\n/**\n * Type inference for CastAd metadata\n */\nexport type CastAdMetadata = z.infer<NonNullable<typeof castAd.metadata>>;\n\nexport type CastAd = {\n type: \"cast\";\n data: CastAdData;\n metadata: CastAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * Link Ad Definition\n * Represents a basic link ad with validation and verification\n */\nexport const linkAd = defineAd({\n type: \"link\",\n\n data: z.object({\n url: z.string().nonempty(\"URL is required\"),\n }),\n metadata: z.object({\n title: z.string().optional(),\n description: z.string().optional(),\n image: z.string().optional(),\n icon: z.string().optional(),\n }),\n async verify({ url }) {\n if (!url.startsWith(\"http\")) {\n throw new Error(\"Invalid link\");\n }\n },\n async getMetadata({ url }) {\n const metadata = await adlandAPI.getLinkMetadata({ url });\n return {\n title: metadata.title,\n description: metadata.description,\n image: metadata.image,\n icon: metadata.icon,\n };\n },\n});\n\n/**\n * Type inference for LinkAd data\n */\nexport type LinkAdData = z.infer<typeof linkAd.data>;\n\n/**\n * Type inference for LinkAd metadata\n */\nexport type LinkAdMetadata = z.infer<NonNullable<typeof linkAd.metadata>>;\n\nexport type LinkAd = {\n type: \"link\";\n data: LinkAdData;\n metadata: LinkAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * MiniApp Ad Definition\n * Represents a Farcaster mini app ad with validation and verification\n */\nexport const miniappAd = defineAd({\n type: \"miniapp\",\n\n data: z.object({\n url: z.string().nonempty(\"URL is required\"),\n }),\n\n metadata: z.object({\n icon: z.string().optional(),\n title: z.string().optional(),\n description: z.string().optional(),\n imageUrl: z.string().optional(),\n }),\n\n async verify({ url }) {\n const errorMessage = \"Miniapp domain verification failed\";\n const domain = url.split(\"//\")[1];\n console.log(\"verifyMiniapp:domain\", domain);\n if (!domain) {\n throw new Error(errorMessage);\n }\n const res = await adlandAPI.verifyMiniapp({ domain });\n console.log(\"verifyMiniapp:res\", res);\n if (!res.verified) {\n throw new Error(errorMessage);\n }\n },\n async getMetadata({ url }) {\n const res = await adlandAPI.getMiniappMetadata({ url });\n console.log(\"getMetadata:res\", res);\n return {\n icon: res.icon,\n title: res.title,\n description: res.description,\n imageUrl: res.imageUrl,\n };\n },\n});\n\n/**\n * Type inference for MiniAppAd data\n */\nexport type MiniAppAdData = z.infer<typeof miniappAd.data>;\n\n/**\n * Type inference for MiniAppAd metadata\n */\nexport type MiniAppAdMetadata = z.infer<NonNullable<typeof miniappAd.metadata>>;\n\nexport type MiniAppAd = {\n type: \"miniapp\";\n data: MiniAppAdData;\n metadata: MiniAppAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd, withChoices } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\nexport const tokenAd = defineAd({\n type: \"token\",\n data: z.object({\n address: z.string().nonempty(\"Address is required\"),\n chainId: withChoices(\n z\n .number()\n .int()\n .positive(\"Chain ID is required\")\n .refine((chainId) => [8453].includes(chainId), \"Invalid chain ID\"),\n [{ label: \"Base (8453)\", value: 8453 }],\n ),\n }),\n metadata: z.object({\n name: z.string().optional(),\n symbol: z.string().optional(),\n decimals: z.number().optional(),\n logoURI: z.string().optional(),\n }),\n async verify({ address, chainId }) {\n const res = await adlandAPI.verifyToken({ address, chainId });\n if (!res.verified) {\n throw new Error(\"Token verification failed\");\n }\n },\n async getMetadata({ address, chainId }) {\n const token = await adlandAPI.getTokenMetadata({ address, chainId });\n return {\n name: token.name,\n symbol: token.symbol,\n decimals: token.decimals,\n logoURI: token.logoURI,\n };\n },\n});\n\nexport type TokenAdData = z.infer<typeof tokenAd.data>;\nexport type TokenAdMetadata = z.infer<NonNullable<typeof tokenAd.metadata>>;\nexport type TokenAd = {\n type: \"token\";\n data: TokenAdData;\n metadata: TokenAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\nexport const farcasterProfileAd = defineAd({\n type: \"farcasterProfile\",\n data: z.object({\n fid: z.string().nonempty(\"Fid is required\"),\n }),\n metadata: z.object({\n pfpUrl: z.string().optional(),\n bio: z.string().optional(),\n username: z.string().optional(),\n displayName: z.string().optional(),\n followers: z.number().optional(),\n following: z.number().optional(),\n pro: z.boolean().optional(),\n }),\n async verify({ fid }) {\n const res = await adlandAPI.verifyFarcasterProfile({ fid });\n if (!res.verified) {\n throw new Error(\"Farcaster profile verification failed\");\n }\n },\n async getMetadata({ fid }) {\n const res = await adlandAPI.getFarcasterProfile({ fid });\n return {\n pfpUrl: res.pfpUrl,\n bio: res.bio,\n username: res.username,\n displayName: res.displayName,\n followers: res.followers,\n following: res.following,\n pro: res.pro,\n };\n },\n});\n\nexport type FarcasterProfileAdData = z.infer<typeof farcasterProfileAd.data>;\nexport type FarcasterProfileAdMetadata = z.infer<\n NonNullable<typeof farcasterProfileAd.metadata>\n>;\nexport type FarcasterProfileAd = {\n type: \"farcasterProfile\";\n data: FarcasterProfileAdData;\n metadata: FarcasterProfileAdMetadata;\n};\n","import { Manifest } from \"@farcaster/miniapp-sdk\";\n\n/**\n * Utility functions to parse accountAssociation from Mini App manifest\n *\n * The accountAssociation is a JSON Farcaster Signature (JFS) that contains:\n * - header: base64url encoded JSON with FID, type, and key (address)\n * - payload: base64url encoded JSON with domain\n * - signature: base64url encoded signature\n */\n\ninterface AccountAssociationHeader {\n fid: number;\n type: \"custody\" | \"auth\";\n key: string; // The address (e.g., \"0x...\")\n}\n\ninterface AccountAssociationPayload {\n domain: string;\n}\n\ninterface AccountAssociation {\n header: string; // base64url encoded\n payload: string; // base64url encoded\n signature: string; // base64url encoded\n}\n\nexport interface ParsedAccountAssociation {\n fid: number;\n address: string; // Ethereum address (0x...)\n type: \"custody\" | \"auth\";\n domain: string;\n}\n\n/**\n * Decode base64url encoded string to JSON object\n */\nfunction decodeBase64Url<T>(encoded: string): T {\n // Replace URL-safe characters with standard base64 characters\n let base64 = encoded.replace(/-/g, \"+\").replace(/_/g, \"/\");\n\n // Add padding if needed\n while (base64.length % 4) {\n base64 += \"=\";\n }\n\n // Node.js environment\n const decoded = Buffer.from(base64, \"base64\").toString(\"utf-8\");\n return JSON.parse(decoded) as T;\n}\n\n/**\n * Parse accountAssociation to extract FID and address\n *\n * @param accountAssociation - The accountAssociation object from manifest\n * @returns Parsed object with FID, address, type, and domain\n */\nexport function parseAccountAssociation(\n accountAssociation: AccountAssociation,\n): ParsedAccountAssociation {\n try {\n // Decode the header to get FID, type, and key (address)\n const header: AccountAssociationHeader = decodeBase64Url(\n accountAssociation.header,\n );\n\n // Decode the payload to get domain\n const payload: AccountAssociationPayload = decodeBase64Url(\n accountAssociation.payload,\n );\n\n return {\n fid: header.fid,\n address: header.key, // The key is the Ethereum address\n type: header.type,\n domain: payload.domain,\n };\n } catch (error) {\n throw new Error(\n `Failed to parse accountAssociation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n}\n\n/**\n * Fetch and parse accountAssociation from a manifest URL\n *\n * @param manifestUrl - URL to the manifest (e.g., \"https://example.com/.well-known/farcaster.json\")\n * @returns Parsed accountAssociation\n */\nexport async function fetchAndParseAccountAssociation(\n manifestUrl: string,\n): Promise<ParsedAccountAssociation> {\n try {\n const response = await fetch(manifestUrl);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch manifest: ${response.status} ${response.statusText}`,\n );\n }\n\n const manifest = (await response.json()) as any;\n\n if (!manifest.accountAssociation) {\n throw new Error(\"Manifest does not contain accountAssociation\");\n }\n\n return parseAccountAssociation(manifest.accountAssociation);\n } catch (error) {\n throw new Error(\n `Failed to fetch and parse accountAssociation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n}\n\nexport class FarcasterAPI {\n private readonly apiKey: string;\n\n constructor(apiKey: string) {\n this.apiKey = apiKey;\n }\n\n async getDomainManifest(domain: string) {\n const response = await fetch(\n `https://client.farcaster.xyz/v1/domain-manifest?domain=${domain}`,\n {\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n },\n },\n );\n if (!response.ok) {\n throw new Error(\n `Failed to fetch domain manifest: ${response.status} ${response.statusText}`,\n );\n }\n const data = (await response.json()) as {\n result: {\n state: {\n verified: boolean;\n updatedAt: number; // timestamp\n manifest: string;\n };\n };\n };\n\n console.log(\"FarcasterAPI:data\", data);\n\n return {\n ...data.result.state,\n manifest: JSON.parse(data.result.state.manifest) as Manifest.Manifest,\n };\n }\n}\n","import { z } from \"zod\";\nimport { castAd } from \"./ads/cast\";\nimport { linkAd } from \"./ads/link\";\nimport { miniappAd } from \"./ads/miniapp\";\nimport type { CastAd } from \"./ads/cast\";\nimport type { LinkAd } from \"./ads/link\";\nimport type { MiniAppAd } from \"./ads/miniapp\";\nimport type { TokenAd } from \"./ads/token\";\nimport type { FarcasterProfileAd } from \"./ads/profile\";\nimport { tokenAd } from \"./ads/token\";\nimport { farcasterProfileAd } from \"./ads/profile\";\n\n/**\n * Union type for all complete ad structures with type, data, and optional metadata\n */\nexport type AdData = CastAd | LinkAd | MiniAppAd | TokenAd | FarcasterProfileAd;\n\n/**\n * Registry of all ad definitions\n * Each entry is an AdDefinition object\n */\nexport const ads = {\n link: linkAd,\n cast: castAd,\n miniapp: miniappAd,\n token: tokenAd,\n farcasterProfile: farcasterProfileAd,\n} as const;\n\nexport const adTypes = [\n \"link\",\n \"cast\",\n \"miniapp\",\n \"token\",\n \"farcasterProfile\",\n] as const;\n\n/**\n * Type for ad definition keys\n */\nexport type AdType = keyof typeof ads;\n\n/**\n * Get ad definition by type\n */\nexport function getAd(type: AdType) {\n return ads[type];\n}\n/**\n * Validate ad data against any ad definition\n */\nexport function validateAdData(data: any): {\n success: boolean;\n data?: {\n type: AdType;\n data: unknown;\n };\n error?: z.ZodError | string;\n} {\n const dataType = data.type;\n if (!dataType || !adTypes.includes(dataType)) {\n return {\n success: false,\n error: \"Data does not match any known ad type\",\n };\n }\n const ad = getAd(data.type);\n\n const result = ad.data.safeParse(data.data);\n if (!result.success) {\n return {\n success: false,\n error: result.error,\n };\n }\n\n return {\n success: true,\n data: {\n type: dataType,\n data: result.data,\n },\n };\n}\n\n// Export all ad definitions\nexport * from \"./ads\";\n\n// Export core utilities\nexport * from \"./core/ad-definition\";\n\n// Export constants\nexport { adlandApiUrl } from \"./constants\";\n\n// Export Farcaster utilities\nexport * from \"./farcaster\";\n\n// Backward compatibility aliases\nexport const adDefinitions = ads;\nexport const adModels = ads;\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -168,7 +168,9 @@ type MiniAppAd = {
|
|
|
168
168
|
|
|
169
169
|
declare const tokenAd: AdDefinition<z.ZodObject<{
|
|
170
170
|
address: z.ZodString;
|
|
171
|
-
chainId: z.ZodNumber
|
|
171
|
+
chainId: z.ZodNumber & {
|
|
172
|
+
choices: readonly FieldChoice<number>[];
|
|
173
|
+
};
|
|
172
174
|
}, z.core.$strip>, z.ZodObject<{
|
|
173
175
|
name: z.ZodOptional<z.ZodString>;
|
|
174
176
|
symbol: z.ZodOptional<z.ZodString>;
|
|
@@ -270,6 +272,18 @@ type FarcasterProfileAd = {
|
|
|
270
272
|
metadata: FarcasterProfileAdMetadata;
|
|
271
273
|
};
|
|
272
274
|
|
|
275
|
+
type FieldChoice<T> = {
|
|
276
|
+
label: string;
|
|
277
|
+
value: T;
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Attach a list of allowed choices to any Zod schema as metadata.
|
|
281
|
+
* The underlying schema and its validation are unchanged — this only
|
|
282
|
+
* annotates the field so that form builders can render a <select>.
|
|
283
|
+
*/
|
|
284
|
+
declare function withChoices<T extends z.ZodTypeAny>(schema: T, choices: ReadonlyArray<FieldChoice<z.infer<T>>>): T & {
|
|
285
|
+
choices: ReadonlyArray<FieldChoice<z.infer<T>>>;
|
|
286
|
+
};
|
|
273
287
|
/**
|
|
274
288
|
* Ad Definition type
|
|
275
289
|
* Represents a data contract + behavior for an ad type
|
|
@@ -509,7 +523,9 @@ declare const ads: {
|
|
|
509
523
|
};
|
|
510
524
|
readonly token: AdDefinition<z.ZodObject<{
|
|
511
525
|
address: z.ZodString;
|
|
512
|
-
chainId: z.ZodNumber
|
|
526
|
+
chainId: z.ZodNumber & {
|
|
527
|
+
choices: readonly FieldChoice<number>[];
|
|
528
|
+
};
|
|
513
529
|
}, z.core.$strip>, z.ZodObject<{
|
|
514
530
|
name: z.ZodOptional<z.ZodString>;
|
|
515
531
|
symbol: z.ZodOptional<z.ZodString>;
|
|
@@ -714,7 +730,9 @@ declare function getAd(type: AdType): (AdDefinition<z.ZodObject<{
|
|
|
714
730
|
}>;
|
|
715
731
|
}) | (AdDefinition<z.ZodObject<{
|
|
716
732
|
address: z.ZodString;
|
|
717
|
-
chainId: z.ZodNumber
|
|
733
|
+
chainId: z.ZodNumber & {
|
|
734
|
+
choices: readonly FieldChoice<number>[];
|
|
735
|
+
};
|
|
718
736
|
}, z.core.$strip>, z.ZodObject<{
|
|
719
737
|
name: z.ZodOptional<z.ZodString>;
|
|
720
738
|
symbol: z.ZodOptional<z.ZodString>;
|
|
@@ -925,7 +943,9 @@ declare const adDefinitions: {
|
|
|
925
943
|
};
|
|
926
944
|
readonly token: AdDefinition<z.ZodObject<{
|
|
927
945
|
address: z.ZodString;
|
|
928
|
-
chainId: z.ZodNumber
|
|
946
|
+
chainId: z.ZodNumber & {
|
|
947
|
+
choices: readonly FieldChoice<number>[];
|
|
948
|
+
};
|
|
929
949
|
}, z.core.$strip>, z.ZodObject<{
|
|
930
950
|
name: z.ZodOptional<z.ZodString>;
|
|
931
951
|
symbol: z.ZodOptional<z.ZodString>;
|
|
@@ -1126,7 +1146,9 @@ declare const adModels: {
|
|
|
1126
1146
|
};
|
|
1127
1147
|
readonly token: AdDefinition<z.ZodObject<{
|
|
1128
1148
|
address: z.ZodString;
|
|
1129
|
-
chainId: z.ZodNumber
|
|
1149
|
+
chainId: z.ZodNumber & {
|
|
1150
|
+
choices: readonly FieldChoice<number>[];
|
|
1151
|
+
};
|
|
1130
1152
|
}, z.core.$strip>, z.ZodObject<{
|
|
1131
1153
|
name: z.ZodOptional<z.ZodString>;
|
|
1132
1154
|
symbol: z.ZodOptional<z.ZodString>;
|
|
@@ -1214,4 +1236,4 @@ declare const adModels: {
|
|
|
1214
1236
|
};
|
|
1215
1237
|
};
|
|
1216
1238
|
|
|
1217
|
-
export { type AdData, type AdDefinition, type AdType, type CastAd, type CastAdData, type CastAdMetadata, FarcasterAPI, type FarcasterProfileAd, type FarcasterProfileAdData, type FarcasterProfileAdMetadata, type LinkAd, type LinkAdData, type LinkAdMetadata, type MiniAppAd, type MiniAppAdData, type MiniAppAdMetadata, type ParsedAccountAssociation, type TokenAd, type TokenAdData, type TokenAdMetadata, adDefinitions, adModels, adTypes, adlandApiUrl, ads, castAd, defineAd, farcasterProfileAd, fetchAndParseAccountAssociation, getAd, linkAd, miniappAd, parseAccountAssociation, processAd, safeProcessAd, tokenAd, validateAdData };
|
|
1239
|
+
export { type AdData, type AdDefinition, type AdType, type CastAd, type CastAdData, type CastAdMetadata, FarcasterAPI, type FarcasterProfileAd, type FarcasterProfileAdData, type FarcasterProfileAdMetadata, type FieldChoice, type LinkAd, type LinkAdData, type LinkAdMetadata, type MiniAppAd, type MiniAppAdData, type MiniAppAdMetadata, type ParsedAccountAssociation, type TokenAd, type TokenAdData, type TokenAdMetadata, adDefinitions, adModels, adTypes, adlandApiUrl, ads, castAd, defineAd, farcasterProfileAd, fetchAndParseAccountAssociation, getAd, linkAd, miniappAd, parseAccountAssociation, processAd, safeProcessAd, tokenAd, validateAdData, withChoices };
|
package/dist/index.d.ts
CHANGED
|
@@ -168,7 +168,9 @@ type MiniAppAd = {
|
|
|
168
168
|
|
|
169
169
|
declare const tokenAd: AdDefinition<z.ZodObject<{
|
|
170
170
|
address: z.ZodString;
|
|
171
|
-
chainId: z.ZodNumber
|
|
171
|
+
chainId: z.ZodNumber & {
|
|
172
|
+
choices: readonly FieldChoice<number>[];
|
|
173
|
+
};
|
|
172
174
|
}, z.core.$strip>, z.ZodObject<{
|
|
173
175
|
name: z.ZodOptional<z.ZodString>;
|
|
174
176
|
symbol: z.ZodOptional<z.ZodString>;
|
|
@@ -270,6 +272,18 @@ type FarcasterProfileAd = {
|
|
|
270
272
|
metadata: FarcasterProfileAdMetadata;
|
|
271
273
|
};
|
|
272
274
|
|
|
275
|
+
type FieldChoice<T> = {
|
|
276
|
+
label: string;
|
|
277
|
+
value: T;
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* Attach a list of allowed choices to any Zod schema as metadata.
|
|
281
|
+
* The underlying schema and its validation are unchanged — this only
|
|
282
|
+
* annotates the field so that form builders can render a <select>.
|
|
283
|
+
*/
|
|
284
|
+
declare function withChoices<T extends z.ZodTypeAny>(schema: T, choices: ReadonlyArray<FieldChoice<z.infer<T>>>): T & {
|
|
285
|
+
choices: ReadonlyArray<FieldChoice<z.infer<T>>>;
|
|
286
|
+
};
|
|
273
287
|
/**
|
|
274
288
|
* Ad Definition type
|
|
275
289
|
* Represents a data contract + behavior for an ad type
|
|
@@ -509,7 +523,9 @@ declare const ads: {
|
|
|
509
523
|
};
|
|
510
524
|
readonly token: AdDefinition<z.ZodObject<{
|
|
511
525
|
address: z.ZodString;
|
|
512
|
-
chainId: z.ZodNumber
|
|
526
|
+
chainId: z.ZodNumber & {
|
|
527
|
+
choices: readonly FieldChoice<number>[];
|
|
528
|
+
};
|
|
513
529
|
}, z.core.$strip>, z.ZodObject<{
|
|
514
530
|
name: z.ZodOptional<z.ZodString>;
|
|
515
531
|
symbol: z.ZodOptional<z.ZodString>;
|
|
@@ -714,7 +730,9 @@ declare function getAd(type: AdType): (AdDefinition<z.ZodObject<{
|
|
|
714
730
|
}>;
|
|
715
731
|
}) | (AdDefinition<z.ZodObject<{
|
|
716
732
|
address: z.ZodString;
|
|
717
|
-
chainId: z.ZodNumber
|
|
733
|
+
chainId: z.ZodNumber & {
|
|
734
|
+
choices: readonly FieldChoice<number>[];
|
|
735
|
+
};
|
|
718
736
|
}, z.core.$strip>, z.ZodObject<{
|
|
719
737
|
name: z.ZodOptional<z.ZodString>;
|
|
720
738
|
symbol: z.ZodOptional<z.ZodString>;
|
|
@@ -925,7 +943,9 @@ declare const adDefinitions: {
|
|
|
925
943
|
};
|
|
926
944
|
readonly token: AdDefinition<z.ZodObject<{
|
|
927
945
|
address: z.ZodString;
|
|
928
|
-
chainId: z.ZodNumber
|
|
946
|
+
chainId: z.ZodNumber & {
|
|
947
|
+
choices: readonly FieldChoice<number>[];
|
|
948
|
+
};
|
|
929
949
|
}, z.core.$strip>, z.ZodObject<{
|
|
930
950
|
name: z.ZodOptional<z.ZodString>;
|
|
931
951
|
symbol: z.ZodOptional<z.ZodString>;
|
|
@@ -1126,7 +1146,9 @@ declare const adModels: {
|
|
|
1126
1146
|
};
|
|
1127
1147
|
readonly token: AdDefinition<z.ZodObject<{
|
|
1128
1148
|
address: z.ZodString;
|
|
1129
|
-
chainId: z.ZodNumber
|
|
1149
|
+
chainId: z.ZodNumber & {
|
|
1150
|
+
choices: readonly FieldChoice<number>[];
|
|
1151
|
+
};
|
|
1130
1152
|
}, z.core.$strip>, z.ZodObject<{
|
|
1131
1153
|
name: z.ZodOptional<z.ZodString>;
|
|
1132
1154
|
symbol: z.ZodOptional<z.ZodString>;
|
|
@@ -1214,4 +1236,4 @@ declare const adModels: {
|
|
|
1214
1236
|
};
|
|
1215
1237
|
};
|
|
1216
1238
|
|
|
1217
|
-
export { type AdData, type AdDefinition, type AdType, type CastAd, type CastAdData, type CastAdMetadata, FarcasterAPI, type FarcasterProfileAd, type FarcasterProfileAdData, type FarcasterProfileAdMetadata, type LinkAd, type LinkAdData, type LinkAdMetadata, type MiniAppAd, type MiniAppAdData, type MiniAppAdMetadata, type ParsedAccountAssociation, type TokenAd, type TokenAdData, type TokenAdMetadata, adDefinitions, adModels, adTypes, adlandApiUrl, ads, castAd, defineAd, farcasterProfileAd, fetchAndParseAccountAssociation, getAd, linkAd, miniappAd, parseAccountAssociation, processAd, safeProcessAd, tokenAd, validateAdData };
|
|
1239
|
+
export { type AdData, type AdDefinition, type AdType, type CastAd, type CastAdData, type CastAdMetadata, FarcasterAPI, type FarcasterProfileAd, type FarcasterProfileAdData, type FarcasterProfileAdMetadata, type FieldChoice, type LinkAd, type LinkAdData, type LinkAdMetadata, type MiniAppAd, type MiniAppAdData, type MiniAppAdMetadata, type ParsedAccountAssociation, type TokenAd, type TokenAdData, type TokenAdMetadata, adDefinitions, adModels, adTypes, adlandApiUrl, ads, castAd, defineAd, farcasterProfileAd, fetchAndParseAccountAssociation, getAd, linkAd, miniappAd, parseAccountAssociation, processAd, safeProcessAd, tokenAd, validateAdData, withChoices };
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,9 @@ import { z } from 'zod';
|
|
|
6
6
|
var adlandApiUrl = process.env.NODE_ENV === "development" ? "http://localhost:3069" : "https://api.0xslots.org";
|
|
7
7
|
|
|
8
8
|
// src/core/ad-definition.ts
|
|
9
|
+
function withChoices(schema, choices) {
|
|
10
|
+
return Object.assign(schema, { choices });
|
|
11
|
+
}
|
|
9
12
|
function defineAd(def) {
|
|
10
13
|
return {
|
|
11
14
|
...def,
|
|
@@ -210,7 +213,10 @@ var tokenAd = defineAd({
|
|
|
210
213
|
type: "token",
|
|
211
214
|
data: z.object({
|
|
212
215
|
address: z.string().nonempty("Address is required"),
|
|
213
|
-
chainId:
|
|
216
|
+
chainId: withChoices(
|
|
217
|
+
z.number().int().positive("Chain ID is required").refine((chainId) => [8453].includes(chainId), "Invalid chain ID"),
|
|
218
|
+
[{ label: "Base (8453)", value: 8453 }]
|
|
219
|
+
)
|
|
214
220
|
}),
|
|
215
221
|
metadata: z.object({
|
|
216
222
|
name: z.string().optional(),
|
|
@@ -390,6 +396,6 @@ function validateAdData(data) {
|
|
|
390
396
|
var adDefinitions = ads;
|
|
391
397
|
var adModels = ads;
|
|
392
398
|
|
|
393
|
-
export { FarcasterAPI, adDefinitions, adModels, adTypes, adlandApiUrl, ads, castAd, defineAd, farcasterProfileAd, fetchAndParseAccountAssociation, getAd, linkAd, miniappAd, parseAccountAssociation, processAd, safeProcessAd, tokenAd, validateAdData };
|
|
399
|
+
export { FarcasterAPI, adDefinitions, adModels, adTypes, adlandApiUrl, ads, castAd, defineAd, farcasterProfileAd, fetchAndParseAccountAssociation, getAd, linkAd, miniappAd, parseAccountAssociation, processAd, safeProcessAd, tokenAd, validateAdData, withChoices };
|
|
394
400
|
//# sourceMappingURL=index.js.map
|
|
395
401
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts","../src/core/ad-definition.ts","../src/services/adland.api.ts","../src/ads/cast.ts","../src/ads/link.ts","../src/ads/miniapp.ts","../src/ads/token.ts","../src/ads/profile.ts","../src/farcaster.ts","../src/index.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["export const adlandApiUrl =\n process.env.NODE_ENV === \"development\"\n ? \"http://localhost:3069\"\n : \"https://api.0xslots.org\";\n\nexport const debug = true;\n","import { z } from \"zod\";\nimport { debug } from \"../constants\";\n\n/**\n * Ad Definition type\n * Represents a data contract + behavior for an ad type\n */\nexport type AdDefinition<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined = undefined,\n> = {\n /**\n * The literal type string for this ad (e.g., \"cast\", \"link\")\n */\n type: string;\n\n /**\n * The Zod schema for the ad's data field\n */\n data: TData;\n\n /**\n * Optional Zod schema for the ad's metadata field\n */\n metadata?: TMetadata;\n\n /**\n * Optional verification function that runs after parsing\n * Receives already-validated data\n */\n verify?: (data: z.infer<TData>) => Promise<void>;\n\n /**\n * Optional metadata enrichment function\n * Only available if metadata schema is defined\n */\n getMetadata?: (\n data: z.infer<TData>,\n ) => Promise<TMetadata extends z.ZodTypeAny ? z.infer<TMetadata> : never>;\n};\n\n/**\n * Typed helper to define an ad\n * Locks type inference and prevents widening\n * Adds a `process` method for convenience\n * @param def - Ad definition object\n * @returns The same definition with proper types and a process method\n */\nexport function defineAd<\n const TData extends z.ZodTypeAny,\n const TMetadata extends z.ZodTypeAny | undefined,\n>(\n def: AdDefinition<TData, TMetadata>,\n): AdDefinition<TData, TMetadata> & {\n /**\n * Process this ad through the full pipeline: parse → verify → getMetadata\n * @param input - Raw input data to process\n * @returns Processed data and optional metadata\n */\n process: (input: z.infer<TData>) => Promise<{\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n }>;\n /**\n * Safe version of process that returns a result object\n * @param input - Raw input data to process\n * @returns Result object with success flag and data or error\n */\n safeProcess: (input: z.infer<TData>) => Promise<{\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n }>;\n} {\n return {\n ...def,\n process: (input: z.infer<TData>) => processAd(def, input),\n safeProcess: (input: z.infer<TData>) => safeProcessAd(def, input),\n };\n}\n\n/**\n * Process an ad through the full pipeline: parse → verify → getMetadata\n * @param ad - Ad definition\n * @param input - Raw input data to process\n * @returns Processed data and optional metadata\n */\nexport async function processAd<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined,\n>(\n ad: AdDefinition<TData, TMetadata>,\n input: z.infer<TData>,\n): Promise<{\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n}> {\n if (debug) {\n console.log(\"processAd:input\", input);\n }\n // Parse and validate\n const data: z.infer<TData> = ad.data.parse(input);\n\n if (debug) {\n console.log(\"processAd:data\", data);\n }\n\n // Verify if function is provided\n if (ad.verify) {\n await ad.verify(input);\n }\n\n // Get metadata if function and schema are provided\n const metadata =\n ad.getMetadata && ad.metadata ? await ad.getMetadata(data) : undefined;\n\n return { data, metadata, type: ad.type } as {\n type: string;\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n };\n}\n\n/**\n * Safe version of processAd that returns a result object\n * @param ad - Ad definition\n * @param input - Raw input data to process\n * @returns Result object with success flag and data or error\n */\nexport async function safeProcessAd<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined,\n>(\n ad: AdDefinition<TData, TMetadata>,\n input: unknown,\n): Promise<{\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n}> {\n // Safe parse\n const parseResult = ad.data.safeParse(input);\n if (!parseResult.success) {\n return {\n success: false,\n error: parseResult.error,\n };\n }\n\n const data: z.infer<TData> = parseResult.data;\n\n // Verify if function is provided\n if (ad.verify) {\n try {\n await ad.verify(data);\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Verification failed\",\n };\n }\n }\n\n // Get metadata if function and schema are provided\n const metadata =\n ad.getMetadata && ad.metadata ? await ad.getMetadata(data) : undefined;\n\n return {\n success: true,\n data,\n metadata,\n } as {\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n };\n}\n","import { adlandApiUrl } from \"../constants\";\n\nclass AdlandAPI {\n constructor() {}\n\n async verifyCast({ hash }: { hash: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/cast`, {\n hash,\n });\n }\n\n async verifyMiniapp({ domain }: { domain: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/miniapp`, {\n domain,\n });\n }\n\n async getMiniappMetadata({ url }: { url: string }): Promise<{\n title: string;\n icon: string;\n description: string;\n imageUrl: string;\n }> {\n return this.get<{\n title: string;\n icon: string;\n description: string;\n imageUrl: string;\n }>(`${adlandApiUrl}/metadata/miniapp?url=${encodeURIComponent(url)}`);\n }\n\n async getLinkMetadata({ url }: { url: string }): Promise<{\n title: string;\n description: string;\n image: string;\n icon: string;\n }> {\n return this.get<{\n title: string;\n description: string;\n image: string;\n icon: string;\n }>(`${adlandApiUrl}/metadata/link?url=${encodeURIComponent(url)}`);\n }\n\n async getCastMetadata({ hash }: { hash: string }): Promise<{\n username: string;\n pfpUrl: string;\n text: string;\n timestamp: number;\n }> {\n return this.get<{\n username: string;\n pfpUrl: string;\n text: string;\n timestamp: number;\n }>(`${adlandApiUrl}/metadata/cast?hash=${encodeURIComponent(hash)}`);\n }\n\n async verifyFarcasterProfile({ fid }: { fid: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/profile`, {\n fid,\n });\n }\n\n async getFarcasterProfile({ fid }: { fid: string }): Promise<{\n pfpUrl: string;\n bio: string;\n username: string;\n displayName?: string;\n followers: number;\n following: number;\n pro: boolean;\n }> {\n return this.get<{\n pfpUrl: string;\n bio: string;\n username: string;\n displayName?: string;\n followers: number;\n following: number;\n pro: boolean;\n }>(`${adlandApiUrl}/metadata/profile?fid=${encodeURIComponent(fid)}`);\n }\n\n async verifyToken({\n address,\n chainId,\n }: {\n address: string;\n chainId: number;\n }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/token`, {\n address,\n chainId,\n });\n }\n\n async getTokenMetadata({\n address,\n chainId,\n }: {\n address: string;\n chainId: number;\n }): Promise<{\n name: string;\n symbol: string;\n decimals: number;\n logoURI: string;\n }> {\n return this.get<{\n name: string;\n symbol: string;\n decimals: number;\n logoURI: string;\n }>(\n `${adlandApiUrl}/metadata/token?address=${encodeURIComponent(address)}&chainId=${chainId}`,\n );\n }\n\n private async post<T>(url: string, body: object): Promise<T> {\n return fetch(url, {\n method: \"POST\",\n body: JSON.stringify(body),\n }).then((res) => res.json()) as T;\n }\n\n private async get<T>(url: string): Promise<T> {\n return fetch(url).then((res) => res.json()) as T;\n }\n}\n\nexport const adlandAPI = new AdlandAPI();\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * Cast Ad Definition\n * Represents a Farcaster cast ad with validation and verification\n */\nexport const castAd = defineAd({\n type: \"cast\",\n data: z.object({\n hash: z.string().nonempty(\"Hash is required\"),\n }),\n metadata: z.object({\n username: z.string().optional(),\n pfpUrl: z.string().optional(),\n text: z.string().optional(),\n timestamp: z.number().optional(),\n }),\n async verify({ hash }) {\n if (!/^0x[0-9a-fA-F]{40}$/.test(hash)) {\n throw new Error(\"Invalid Farcaster cast hash\");\n }\n\n const res = await adlandAPI.verifyCast({ hash });\n if (!res.verified) {\n throw new Error(\"Cast hash verification failed\");\n }\n },\n async getMetadata({ hash }) {\n const cast = await adlandAPI.getCastMetadata({ hash });\n return {\n username: cast.username,\n pfpUrl: cast.pfpUrl,\n text: cast.text,\n timestamp: cast.timestamp,\n };\n },\n});\n\n/**\n * Type inference for CastAd data\n */\nexport type CastAdData = z.infer<typeof castAd.data>;\n\n/**\n * Type inference for CastAd metadata\n */\nexport type CastAdMetadata = z.infer<NonNullable<typeof castAd.metadata>>;\n\nexport type CastAd = {\n type: \"cast\";\n data: CastAdData;\n metadata: CastAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * Link Ad Definition\n * Represents a basic link ad with validation and verification\n */\nexport const linkAd = defineAd({\n type: \"link\",\n\n data: z.object({\n url: z.string().nonempty(\"URL is required\"),\n }),\n metadata: z.object({\n title: z.string().optional(),\n description: z.string().optional(),\n image: z.string().optional(),\n icon: z.string().optional(),\n }),\n async verify({ url }) {\n if (!url.startsWith(\"http\")) {\n throw new Error(\"Invalid link\");\n }\n },\n async getMetadata({ url }) {\n const metadata = await adlandAPI.getLinkMetadata({ url });\n return {\n title: metadata.title,\n description: metadata.description,\n image: metadata.image,\n icon: metadata.icon,\n };\n },\n});\n\n/**\n * Type inference for LinkAd data\n */\nexport type LinkAdData = z.infer<typeof linkAd.data>;\n\n/**\n * Type inference for LinkAd metadata\n */\nexport type LinkAdMetadata = z.infer<NonNullable<typeof linkAd.metadata>>;\n\nexport type LinkAd = {\n type: \"link\";\n data: LinkAdData;\n metadata: LinkAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * MiniApp Ad Definition\n * Represents a Farcaster mini app ad with validation and verification\n */\nexport const miniappAd = defineAd({\n type: \"miniapp\",\n\n data: z.object({\n url: z.string().nonempty(\"URL is required\"),\n }),\n\n metadata: z.object({\n icon: z.string().optional(),\n title: z.string().optional(),\n description: z.string().optional(),\n imageUrl: z.string().optional(),\n }),\n\n async verify({ url }) {\n const errorMessage = \"Miniapp domain verification failed\";\n const domain = url.split(\"//\")[1];\n console.log(\"verifyMiniapp:domain\", domain);\n if (!domain) {\n throw new Error(errorMessage);\n }\n const res = await adlandAPI.verifyMiniapp({ domain });\n console.log(\"verifyMiniapp:res\", res);\n if (!res.verified) {\n throw new Error(errorMessage);\n }\n },\n async getMetadata({ url }) {\n const res = await adlandAPI.getMiniappMetadata({ url });\n console.log(\"getMetadata:res\", res);\n return {\n icon: res.icon,\n title: res.title,\n description: res.description,\n imageUrl: res.imageUrl,\n };\n },\n});\n\n/**\n * Type inference for MiniAppAd data\n */\nexport type MiniAppAdData = z.infer<typeof miniappAd.data>;\n\n/**\n * Type inference for MiniAppAd metadata\n */\nexport type MiniAppAdMetadata = z.infer<NonNullable<typeof miniappAd.metadata>>;\n\nexport type MiniAppAd = {\n type: \"miniapp\";\n data: MiniAppAdData;\n metadata: MiniAppAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\nexport const tokenAd = defineAd({\n type: \"token\",\n data: z.object({\n address: z.string().nonempty(\"Address is required\"),\n chainId: z\n .number()\n .int()\n .positive(\"Chain ID is required\")\n .refine((chainId) => [8453].includes(chainId), \"Invalid chain ID\"),\n }),\n metadata: z.object({\n name: z.string().optional(),\n symbol: z.string().optional(),\n decimals: z.number().optional(),\n logoURI: z.string().optional(),\n }),\n async verify({ address, chainId }) {\n const res = await adlandAPI.verifyToken({ address, chainId });\n if (!res.verified) {\n throw new Error(\"Token verification failed\");\n }\n },\n async getMetadata({ address, chainId }) {\n const token = await adlandAPI.getTokenMetadata({ address, chainId });\n return {\n name: token.name,\n symbol: token.symbol,\n decimals: token.decimals,\n logoURI: token.logoURI,\n };\n },\n});\n\nexport type TokenAdData = z.infer<typeof tokenAd.data>;\nexport type TokenAdMetadata = z.infer<NonNullable<typeof tokenAd.metadata>>;\nexport type TokenAd = {\n type: \"token\";\n data: TokenAdData;\n metadata: TokenAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\nexport const farcasterProfileAd = defineAd({\n type: \"farcasterProfile\",\n data: z.object({\n fid: z.string().nonempty(\"Fid is required\"),\n }),\n metadata: z.object({\n pfpUrl: z.string().optional(),\n bio: z.string().optional(),\n username: z.string().optional(),\n displayName: z.string().optional(),\n followers: z.number().optional(),\n following: z.number().optional(),\n pro: z.boolean().optional(),\n }),\n async verify({ fid }) {\n const res = await adlandAPI.verifyFarcasterProfile({ fid });\n if (!res.verified) {\n throw new Error(\"Farcaster profile verification failed\");\n }\n },\n async getMetadata({ fid }) {\n const res = await adlandAPI.getFarcasterProfile({ fid });\n return {\n pfpUrl: res.pfpUrl,\n bio: res.bio,\n username: res.username,\n displayName: res.displayName,\n followers: res.followers,\n following: res.following,\n pro: res.pro,\n };\n },\n});\n\nexport type FarcasterProfileAdData = z.infer<typeof farcasterProfileAd.data>;\nexport type FarcasterProfileAdMetadata = z.infer<\n NonNullable<typeof farcasterProfileAd.metadata>\n>;\nexport type FarcasterProfileAd = {\n type: \"farcasterProfile\";\n data: FarcasterProfileAdData;\n metadata: FarcasterProfileAdMetadata;\n};\n","import { Manifest } from \"@farcaster/miniapp-sdk\";\n\n/**\n * Utility functions to parse accountAssociation from Mini App manifest\n *\n * The accountAssociation is a JSON Farcaster Signature (JFS) that contains:\n * - header: base64url encoded JSON with FID, type, and key (address)\n * - payload: base64url encoded JSON with domain\n * - signature: base64url encoded signature\n */\n\ninterface AccountAssociationHeader {\n fid: number;\n type: \"custody\" | \"auth\";\n key: string; // The address (e.g., \"0x...\")\n}\n\ninterface AccountAssociationPayload {\n domain: string;\n}\n\ninterface AccountAssociation {\n header: string; // base64url encoded\n payload: string; // base64url encoded\n signature: string; // base64url encoded\n}\n\nexport interface ParsedAccountAssociation {\n fid: number;\n address: string; // Ethereum address (0x...)\n type: \"custody\" | \"auth\";\n domain: string;\n}\n\n/**\n * Decode base64url encoded string to JSON object\n */\nfunction decodeBase64Url<T>(encoded: string): T {\n // Replace URL-safe characters with standard base64 characters\n let base64 = encoded.replace(/-/g, \"+\").replace(/_/g, \"/\");\n\n // Add padding if needed\n while (base64.length % 4) {\n base64 += \"=\";\n }\n\n // Node.js environment\n const decoded = Buffer.from(base64, \"base64\").toString(\"utf-8\");\n return JSON.parse(decoded) as T;\n}\n\n/**\n * Parse accountAssociation to extract FID and address\n *\n * @param accountAssociation - The accountAssociation object from manifest\n * @returns Parsed object with FID, address, type, and domain\n */\nexport function parseAccountAssociation(\n accountAssociation: AccountAssociation,\n): ParsedAccountAssociation {\n try {\n // Decode the header to get FID, type, and key (address)\n const header: AccountAssociationHeader = decodeBase64Url(\n accountAssociation.header,\n );\n\n // Decode the payload to get domain\n const payload: AccountAssociationPayload = decodeBase64Url(\n accountAssociation.payload,\n );\n\n return {\n fid: header.fid,\n address: header.key, // The key is the Ethereum address\n type: header.type,\n domain: payload.domain,\n };\n } catch (error) {\n throw new Error(\n `Failed to parse accountAssociation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n}\n\n/**\n * Fetch and parse accountAssociation from a manifest URL\n *\n * @param manifestUrl - URL to the manifest (e.g., \"https://example.com/.well-known/farcaster.json\")\n * @returns Parsed accountAssociation\n */\nexport async function fetchAndParseAccountAssociation(\n manifestUrl: string,\n): Promise<ParsedAccountAssociation> {\n try {\n const response = await fetch(manifestUrl);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch manifest: ${response.status} ${response.statusText}`,\n );\n }\n\n const manifest = (await response.json()) as any;\n\n if (!manifest.accountAssociation) {\n throw new Error(\"Manifest does not contain accountAssociation\");\n }\n\n return parseAccountAssociation(manifest.accountAssociation);\n } catch (error) {\n throw new Error(\n `Failed to fetch and parse accountAssociation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n}\n\nexport class FarcasterAPI {\n private readonly apiKey: string;\n\n constructor(apiKey: string) {\n this.apiKey = apiKey;\n }\n\n async getDomainManifest(domain: string) {\n const response = await fetch(\n `https://client.farcaster.xyz/v1/domain-manifest?domain=${domain}`,\n {\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n },\n },\n );\n if (!response.ok) {\n throw new Error(\n `Failed to fetch domain manifest: ${response.status} ${response.statusText}`,\n );\n }\n const data = (await response.json()) as {\n result: {\n state: {\n verified: boolean;\n updatedAt: number; // timestamp\n manifest: string;\n };\n };\n };\n\n console.log(\"FarcasterAPI:data\", data);\n\n return {\n ...data.result.state,\n manifest: JSON.parse(data.result.state.manifest) as Manifest.Manifest,\n };\n }\n}\n","import { z } from \"zod\";\nimport { castAd } from \"./ads/cast\";\nimport { linkAd } from \"./ads/link\";\nimport { miniappAd } from \"./ads/miniapp\";\nimport type { CastAd } from \"./ads/cast\";\nimport type { LinkAd } from \"./ads/link\";\nimport type { MiniAppAd } from \"./ads/miniapp\";\nimport type { TokenAd } from \"./ads/token\";\nimport type { FarcasterProfileAd } from \"./ads/profile\";\nimport { tokenAd } from \"./ads/token\";\nimport { farcasterProfileAd } from \"./ads/profile\";\n\n/**\n * Union type for all complete ad structures with type, data, and optional metadata\n */\nexport type AdData = CastAd | LinkAd | MiniAppAd | TokenAd | FarcasterProfileAd;\n\n/**\n * Registry of all ad definitions\n * Each entry is an AdDefinition object\n */\nexport const ads = {\n link: linkAd,\n cast: castAd,\n miniapp: miniappAd,\n token: tokenAd,\n farcasterProfile: farcasterProfileAd,\n} as const;\n\nexport const adTypes = [\n \"link\",\n \"cast\",\n \"miniapp\",\n \"token\",\n \"farcasterProfile\",\n] as const;\n\n/**\n * Type for ad definition keys\n */\nexport type AdType = keyof typeof ads;\n\n/**\n * Get ad definition by type\n */\nexport function getAd(type: AdType) {\n return ads[type];\n}\n/**\n * Validate ad data against any ad definition\n */\nexport function validateAdData(data: any): {\n success: boolean;\n data?: {\n type: AdType;\n data: unknown;\n };\n error?: z.ZodError | string;\n} {\n const dataType = data.type;\n if (!dataType || !adTypes.includes(dataType)) {\n return {\n success: false,\n error: \"Data does not match any known ad type\",\n };\n }\n const ad = getAd(data.type);\n\n const result = ad.data.safeParse(data.data);\n if (!result.success) {\n return {\n success: false,\n error: result.error,\n };\n }\n\n return {\n success: true,\n data: {\n type: dataType,\n data: result.data,\n },\n };\n}\n\n// Export all ad definitions\nexport * from \"./ads\";\n\n// Export core utilities\nexport * from \"./core/ad-definition\";\n\n// Export constants\nexport { adlandApiUrl } from \"./constants\";\n\n// Export Farcaster utilities\nexport * from \"./farcaster\";\n\n// Backward compatibility aliases\nexport const adDefinitions = ads;\nexport const adModels = ads;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/core/ad-definition.ts","../src/services/adland.api.ts","../src/ads/cast.ts","../src/ads/link.ts","../src/ads/miniapp.ts","../src/ads/token.ts","../src/ads/profile.ts","../src/farcaster.ts","../src/index.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["export const adlandApiUrl =\n process.env.NODE_ENV === \"development\"\n ? \"http://localhost:3069\"\n : \"https://api.0xslots.org\";\n\nexport const debug = true;\n","import type { z } from \"zod\";\nimport { debug } from \"../constants\";\n\nexport type FieldChoice<T> = { label: string; value: T };\n\n/**\n * Attach a list of allowed choices to any Zod schema as metadata.\n * The underlying schema and its validation are unchanged — this only\n * annotates the field so that form builders can render a <select>.\n */\nexport function withChoices<T extends z.ZodTypeAny>(\n schema: T,\n choices: ReadonlyArray<FieldChoice<z.infer<T>>>,\n): T & { choices: ReadonlyArray<FieldChoice<z.infer<T>>> } {\n return Object.assign(schema, { choices });\n}\n\n/**\n * Ad Definition type\n * Represents a data contract + behavior for an ad type\n */\nexport type AdDefinition<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined = undefined,\n> = {\n /**\n * The literal type string for this ad (e.g., \"cast\", \"link\")\n */\n type: string;\n\n /**\n * The Zod schema for the ad's data field\n */\n data: TData;\n\n /**\n * Optional Zod schema for the ad's metadata field\n */\n metadata?: TMetadata;\n\n /**\n * Optional verification function that runs after parsing\n * Receives already-validated data\n */\n verify?: (data: z.infer<TData>) => Promise<void>;\n\n /**\n * Optional metadata enrichment function\n * Only available if metadata schema is defined\n */\n getMetadata?: (\n data: z.infer<TData>,\n ) => Promise<TMetadata extends z.ZodTypeAny ? z.infer<TMetadata> : never>;\n};\n\n/**\n * Typed helper to define an ad\n * Locks type inference and prevents widening\n * Adds a `process` method for convenience\n * @param def - Ad definition object\n * @returns The same definition with proper types and a process method\n */\nexport function defineAd<\n const TData extends z.ZodTypeAny,\n const TMetadata extends z.ZodTypeAny | undefined,\n>(\n def: AdDefinition<TData, TMetadata>,\n): AdDefinition<TData, TMetadata> & {\n /**\n * Process this ad through the full pipeline: parse → verify → getMetadata\n * @param input - Raw input data to process\n * @returns Processed data and optional metadata\n */\n process: (input: z.infer<TData>) => Promise<{\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n }>;\n /**\n * Safe version of process that returns a result object\n * @param input - Raw input data to process\n * @returns Result object with success flag and data or error\n */\n safeProcess: (input: z.infer<TData>) => Promise<{\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n }>;\n} {\n return {\n ...def,\n process: (input: z.infer<TData>) => processAd(def, input),\n safeProcess: (input: z.infer<TData>) => safeProcessAd(def, input),\n };\n}\n\n/**\n * Process an ad through the full pipeline: parse → verify → getMetadata\n * @param ad - Ad definition\n * @param input - Raw input data to process\n * @returns Processed data and optional metadata\n */\nexport async function processAd<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined,\n>(\n ad: AdDefinition<TData, TMetadata>,\n input: z.infer<TData>,\n): Promise<{\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n}> {\n if (debug) {\n console.log(\"processAd:input\", input);\n }\n // Parse and validate\n const data: z.infer<TData> = ad.data.parse(input);\n\n if (debug) {\n console.log(\"processAd:data\", data);\n }\n\n // Verify if function is provided\n if (ad.verify) {\n await ad.verify(input);\n }\n\n // Get metadata if function and schema are provided\n const metadata =\n ad.getMetadata && ad.metadata ? await ad.getMetadata(data) : undefined;\n\n return { data, metadata, type: ad.type } as {\n type: string;\n data: z.infer<TData>;\n metadata: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n };\n}\n\n/**\n * Safe version of processAd that returns a result object\n * @param ad - Ad definition\n * @param input - Raw input data to process\n * @returns Result object with success flag and data or error\n */\nexport async function safeProcessAd<\n TData extends z.ZodTypeAny,\n TMetadata extends z.ZodTypeAny | undefined,\n>(\n ad: AdDefinition<TData, TMetadata>,\n input: unknown,\n): Promise<{\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n}> {\n // Safe parse\n const parseResult = ad.data.safeParse(input);\n if (!parseResult.success) {\n return {\n success: false,\n error: parseResult.error,\n };\n }\n\n const data: z.infer<TData> = parseResult.data;\n\n // Verify if function is provided\n if (ad.verify) {\n try {\n await ad.verify(data);\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Verification failed\",\n };\n }\n }\n\n // Get metadata if function and schema are provided\n const metadata =\n ad.getMetadata && ad.metadata ? await ad.getMetadata(data) : undefined;\n\n return {\n success: true,\n data,\n metadata,\n } as {\n success: boolean;\n data?: z.infer<TData>;\n metadata?: TMetadata extends z.ZodTypeAny\n ? TMetadata extends undefined\n ? undefined\n : z.infer<TMetadata> | undefined\n : undefined;\n error?: z.ZodError | string;\n };\n}\n","import { adlandApiUrl } from \"../constants\";\n\nclass AdlandAPI {\n constructor() {}\n\n async verifyCast({ hash }: { hash: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/cast`, {\n hash,\n });\n }\n\n async verifyMiniapp({ domain }: { domain: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/miniapp`, {\n domain,\n });\n }\n\n async getMiniappMetadata({ url }: { url: string }): Promise<{\n title: string;\n icon: string;\n description: string;\n imageUrl: string;\n }> {\n return this.get<{\n title: string;\n icon: string;\n description: string;\n imageUrl: string;\n }>(`${adlandApiUrl}/metadata/miniapp?url=${encodeURIComponent(url)}`);\n }\n\n async getLinkMetadata({ url }: { url: string }): Promise<{\n title: string;\n description: string;\n image: string;\n icon: string;\n }> {\n return this.get<{\n title: string;\n description: string;\n image: string;\n icon: string;\n }>(`${adlandApiUrl}/metadata/link?url=${encodeURIComponent(url)}`);\n }\n\n async getCastMetadata({ hash }: { hash: string }): Promise<{\n username: string;\n pfpUrl: string;\n text: string;\n timestamp: number;\n }> {\n return this.get<{\n username: string;\n pfpUrl: string;\n text: string;\n timestamp: number;\n }>(`${adlandApiUrl}/metadata/cast?hash=${encodeURIComponent(hash)}`);\n }\n\n async verifyFarcasterProfile({ fid }: { fid: string }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/profile`, {\n fid,\n });\n }\n\n async getFarcasterProfile({ fid }: { fid: string }): Promise<{\n pfpUrl: string;\n bio: string;\n username: string;\n displayName?: string;\n followers: number;\n following: number;\n pro: boolean;\n }> {\n return this.get<{\n pfpUrl: string;\n bio: string;\n username: string;\n displayName?: string;\n followers: number;\n following: number;\n pro: boolean;\n }>(`${adlandApiUrl}/metadata/profile?fid=${encodeURIComponent(fid)}`);\n }\n\n async verifyToken({\n address,\n chainId,\n }: {\n address: string;\n chainId: number;\n }) {\n return this.post<{ verified: boolean }>(`${adlandApiUrl}/verify/token`, {\n address,\n chainId,\n });\n }\n\n async getTokenMetadata({\n address,\n chainId,\n }: {\n address: string;\n chainId: number;\n }): Promise<{\n name: string;\n symbol: string;\n decimals: number;\n logoURI: string;\n }> {\n return this.get<{\n name: string;\n symbol: string;\n decimals: number;\n logoURI: string;\n }>(\n `${adlandApiUrl}/metadata/token?address=${encodeURIComponent(address)}&chainId=${chainId}`,\n );\n }\n\n private async post<T>(url: string, body: object): Promise<T> {\n return fetch(url, {\n method: \"POST\",\n body: JSON.stringify(body),\n }).then((res) => res.json()) as T;\n }\n\n private async get<T>(url: string): Promise<T> {\n return fetch(url).then((res) => res.json()) as T;\n }\n}\n\nexport const adlandAPI = new AdlandAPI();\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * Cast Ad Definition\n * Represents a Farcaster cast ad with validation and verification\n */\nexport const castAd = defineAd({\n type: \"cast\",\n data: z.object({\n hash: z.string().nonempty(\"Hash is required\"),\n }),\n metadata: z.object({\n username: z.string().optional(),\n pfpUrl: z.string().optional(),\n text: z.string().optional(),\n timestamp: z.number().optional(),\n }),\n async verify({ hash }) {\n if (!/^0x[0-9a-fA-F]{40}$/.test(hash)) {\n throw new Error(\"Invalid Farcaster cast hash\");\n }\n\n const res = await adlandAPI.verifyCast({ hash });\n if (!res.verified) {\n throw new Error(\"Cast hash verification failed\");\n }\n },\n async getMetadata({ hash }) {\n const cast = await adlandAPI.getCastMetadata({ hash });\n return {\n username: cast.username,\n pfpUrl: cast.pfpUrl,\n text: cast.text,\n timestamp: cast.timestamp,\n };\n },\n});\n\n/**\n * Type inference for CastAd data\n */\nexport type CastAdData = z.infer<typeof castAd.data>;\n\n/**\n * Type inference for CastAd metadata\n */\nexport type CastAdMetadata = z.infer<NonNullable<typeof castAd.metadata>>;\n\nexport type CastAd = {\n type: \"cast\";\n data: CastAdData;\n metadata: CastAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * Link Ad Definition\n * Represents a basic link ad with validation and verification\n */\nexport const linkAd = defineAd({\n type: \"link\",\n\n data: z.object({\n url: z.string().nonempty(\"URL is required\"),\n }),\n metadata: z.object({\n title: z.string().optional(),\n description: z.string().optional(),\n image: z.string().optional(),\n icon: z.string().optional(),\n }),\n async verify({ url }) {\n if (!url.startsWith(\"http\")) {\n throw new Error(\"Invalid link\");\n }\n },\n async getMetadata({ url }) {\n const metadata = await adlandAPI.getLinkMetadata({ url });\n return {\n title: metadata.title,\n description: metadata.description,\n image: metadata.image,\n icon: metadata.icon,\n };\n },\n});\n\n/**\n * Type inference for LinkAd data\n */\nexport type LinkAdData = z.infer<typeof linkAd.data>;\n\n/**\n * Type inference for LinkAd metadata\n */\nexport type LinkAdMetadata = z.infer<NonNullable<typeof linkAd.metadata>>;\n\nexport type LinkAd = {\n type: \"link\";\n data: LinkAdData;\n metadata: LinkAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\n/**\n * MiniApp Ad Definition\n * Represents a Farcaster mini app ad with validation and verification\n */\nexport const miniappAd = defineAd({\n type: \"miniapp\",\n\n data: z.object({\n url: z.string().nonempty(\"URL is required\"),\n }),\n\n metadata: z.object({\n icon: z.string().optional(),\n title: z.string().optional(),\n description: z.string().optional(),\n imageUrl: z.string().optional(),\n }),\n\n async verify({ url }) {\n const errorMessage = \"Miniapp domain verification failed\";\n const domain = url.split(\"//\")[1];\n console.log(\"verifyMiniapp:domain\", domain);\n if (!domain) {\n throw new Error(errorMessage);\n }\n const res = await adlandAPI.verifyMiniapp({ domain });\n console.log(\"verifyMiniapp:res\", res);\n if (!res.verified) {\n throw new Error(errorMessage);\n }\n },\n async getMetadata({ url }) {\n const res = await adlandAPI.getMiniappMetadata({ url });\n console.log(\"getMetadata:res\", res);\n return {\n icon: res.icon,\n title: res.title,\n description: res.description,\n imageUrl: res.imageUrl,\n };\n },\n});\n\n/**\n * Type inference for MiniAppAd data\n */\nexport type MiniAppAdData = z.infer<typeof miniappAd.data>;\n\n/**\n * Type inference for MiniAppAd metadata\n */\nexport type MiniAppAdMetadata = z.infer<NonNullable<typeof miniappAd.metadata>>;\n\nexport type MiniAppAd = {\n type: \"miniapp\";\n data: MiniAppAdData;\n metadata: MiniAppAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd, withChoices } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\nexport const tokenAd = defineAd({\n type: \"token\",\n data: z.object({\n address: z.string().nonempty(\"Address is required\"),\n chainId: withChoices(\n z\n .number()\n .int()\n .positive(\"Chain ID is required\")\n .refine((chainId) => [8453].includes(chainId), \"Invalid chain ID\"),\n [{ label: \"Base (8453)\", value: 8453 }],\n ),\n }),\n metadata: z.object({\n name: z.string().optional(),\n symbol: z.string().optional(),\n decimals: z.number().optional(),\n logoURI: z.string().optional(),\n }),\n async verify({ address, chainId }) {\n const res = await adlandAPI.verifyToken({ address, chainId });\n if (!res.verified) {\n throw new Error(\"Token verification failed\");\n }\n },\n async getMetadata({ address, chainId }) {\n const token = await adlandAPI.getTokenMetadata({ address, chainId });\n return {\n name: token.name,\n symbol: token.symbol,\n decimals: token.decimals,\n logoURI: token.logoURI,\n };\n },\n});\n\nexport type TokenAdData = z.infer<typeof tokenAd.data>;\nexport type TokenAdMetadata = z.infer<NonNullable<typeof tokenAd.metadata>>;\nexport type TokenAd = {\n type: \"token\";\n data: TokenAdData;\n metadata: TokenAdMetadata;\n};\n","import { z } from \"zod\";\nimport { defineAd } from \"../core/ad-definition\";\nimport { adlandAPI } from \"../services/adland.api\";\n\nexport const farcasterProfileAd = defineAd({\n type: \"farcasterProfile\",\n data: z.object({\n fid: z.string().nonempty(\"Fid is required\"),\n }),\n metadata: z.object({\n pfpUrl: z.string().optional(),\n bio: z.string().optional(),\n username: z.string().optional(),\n displayName: z.string().optional(),\n followers: z.number().optional(),\n following: z.number().optional(),\n pro: z.boolean().optional(),\n }),\n async verify({ fid }) {\n const res = await adlandAPI.verifyFarcasterProfile({ fid });\n if (!res.verified) {\n throw new Error(\"Farcaster profile verification failed\");\n }\n },\n async getMetadata({ fid }) {\n const res = await adlandAPI.getFarcasterProfile({ fid });\n return {\n pfpUrl: res.pfpUrl,\n bio: res.bio,\n username: res.username,\n displayName: res.displayName,\n followers: res.followers,\n following: res.following,\n pro: res.pro,\n };\n },\n});\n\nexport type FarcasterProfileAdData = z.infer<typeof farcasterProfileAd.data>;\nexport type FarcasterProfileAdMetadata = z.infer<\n NonNullable<typeof farcasterProfileAd.metadata>\n>;\nexport type FarcasterProfileAd = {\n type: \"farcasterProfile\";\n data: FarcasterProfileAdData;\n metadata: FarcasterProfileAdMetadata;\n};\n","import { Manifest } from \"@farcaster/miniapp-sdk\";\n\n/**\n * Utility functions to parse accountAssociation from Mini App manifest\n *\n * The accountAssociation is a JSON Farcaster Signature (JFS) that contains:\n * - header: base64url encoded JSON with FID, type, and key (address)\n * - payload: base64url encoded JSON with domain\n * - signature: base64url encoded signature\n */\n\ninterface AccountAssociationHeader {\n fid: number;\n type: \"custody\" | \"auth\";\n key: string; // The address (e.g., \"0x...\")\n}\n\ninterface AccountAssociationPayload {\n domain: string;\n}\n\ninterface AccountAssociation {\n header: string; // base64url encoded\n payload: string; // base64url encoded\n signature: string; // base64url encoded\n}\n\nexport interface ParsedAccountAssociation {\n fid: number;\n address: string; // Ethereum address (0x...)\n type: \"custody\" | \"auth\";\n domain: string;\n}\n\n/**\n * Decode base64url encoded string to JSON object\n */\nfunction decodeBase64Url<T>(encoded: string): T {\n // Replace URL-safe characters with standard base64 characters\n let base64 = encoded.replace(/-/g, \"+\").replace(/_/g, \"/\");\n\n // Add padding if needed\n while (base64.length % 4) {\n base64 += \"=\";\n }\n\n // Node.js environment\n const decoded = Buffer.from(base64, \"base64\").toString(\"utf-8\");\n return JSON.parse(decoded) as T;\n}\n\n/**\n * Parse accountAssociation to extract FID and address\n *\n * @param accountAssociation - The accountAssociation object from manifest\n * @returns Parsed object with FID, address, type, and domain\n */\nexport function parseAccountAssociation(\n accountAssociation: AccountAssociation,\n): ParsedAccountAssociation {\n try {\n // Decode the header to get FID, type, and key (address)\n const header: AccountAssociationHeader = decodeBase64Url(\n accountAssociation.header,\n );\n\n // Decode the payload to get domain\n const payload: AccountAssociationPayload = decodeBase64Url(\n accountAssociation.payload,\n );\n\n return {\n fid: header.fid,\n address: header.key, // The key is the Ethereum address\n type: header.type,\n domain: payload.domain,\n };\n } catch (error) {\n throw new Error(\n `Failed to parse accountAssociation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n}\n\n/**\n * Fetch and parse accountAssociation from a manifest URL\n *\n * @param manifestUrl - URL to the manifest (e.g., \"https://example.com/.well-known/farcaster.json\")\n * @returns Parsed accountAssociation\n */\nexport async function fetchAndParseAccountAssociation(\n manifestUrl: string,\n): Promise<ParsedAccountAssociation> {\n try {\n const response = await fetch(manifestUrl);\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch manifest: ${response.status} ${response.statusText}`,\n );\n }\n\n const manifest = (await response.json()) as any;\n\n if (!manifest.accountAssociation) {\n throw new Error(\"Manifest does not contain accountAssociation\");\n }\n\n return parseAccountAssociation(manifest.accountAssociation);\n } catch (error) {\n throw new Error(\n `Failed to fetch and parse accountAssociation: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n}\n\nexport class FarcasterAPI {\n private readonly apiKey: string;\n\n constructor(apiKey: string) {\n this.apiKey = apiKey;\n }\n\n async getDomainManifest(domain: string) {\n const response = await fetch(\n `https://client.farcaster.xyz/v1/domain-manifest?domain=${domain}`,\n {\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n },\n },\n );\n if (!response.ok) {\n throw new Error(\n `Failed to fetch domain manifest: ${response.status} ${response.statusText}`,\n );\n }\n const data = (await response.json()) as {\n result: {\n state: {\n verified: boolean;\n updatedAt: number; // timestamp\n manifest: string;\n };\n };\n };\n\n console.log(\"FarcasterAPI:data\", data);\n\n return {\n ...data.result.state,\n manifest: JSON.parse(data.result.state.manifest) as Manifest.Manifest,\n };\n }\n}\n","import { z } from \"zod\";\nimport { castAd } from \"./ads/cast\";\nimport { linkAd } from \"./ads/link\";\nimport { miniappAd } from \"./ads/miniapp\";\nimport type { CastAd } from \"./ads/cast\";\nimport type { LinkAd } from \"./ads/link\";\nimport type { MiniAppAd } from \"./ads/miniapp\";\nimport type { TokenAd } from \"./ads/token\";\nimport type { FarcasterProfileAd } from \"./ads/profile\";\nimport { tokenAd } from \"./ads/token\";\nimport { farcasterProfileAd } from \"./ads/profile\";\n\n/**\n * Union type for all complete ad structures with type, data, and optional metadata\n */\nexport type AdData = CastAd | LinkAd | MiniAppAd | TokenAd | FarcasterProfileAd;\n\n/**\n * Registry of all ad definitions\n * Each entry is an AdDefinition object\n */\nexport const ads = {\n link: linkAd,\n cast: castAd,\n miniapp: miniappAd,\n token: tokenAd,\n farcasterProfile: farcasterProfileAd,\n} as const;\n\nexport const adTypes = [\n \"link\",\n \"cast\",\n \"miniapp\",\n \"token\",\n \"farcasterProfile\",\n] as const;\n\n/**\n * Type for ad definition keys\n */\nexport type AdType = keyof typeof ads;\n\n/**\n * Get ad definition by type\n */\nexport function getAd(type: AdType) {\n return ads[type];\n}\n/**\n * Validate ad data against any ad definition\n */\nexport function validateAdData(data: any): {\n success: boolean;\n data?: {\n type: AdType;\n data: unknown;\n };\n error?: z.ZodError | string;\n} {\n const dataType = data.type;\n if (!dataType || !adTypes.includes(dataType)) {\n return {\n success: false,\n error: \"Data does not match any known ad type\",\n };\n }\n const ad = getAd(data.type);\n\n const result = ad.data.safeParse(data.data);\n if (!result.success) {\n return {\n success: false,\n error: result.error,\n };\n }\n\n return {\n success: true,\n data: {\n type: dataType,\n data: result.data,\n },\n };\n}\n\n// Export all ad definitions\nexport * from \"./ads\";\n\n// Export core utilities\nexport * from \"./core/ad-definition\";\n\n// Export constants\nexport { adlandApiUrl } from \"./constants\";\n\n// Export Farcaster utilities\nexport * from \"./farcaster\";\n\n// Backward compatibility aliases\nexport const adDefinitions = ads;\nexport const adModels = ads;\n"]}
|