@adland/data 0.14.2 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @adland/data
2
2
 
3
+ ## 0.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0c9cc04: update route
8
+
9
+ ## 0.14.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 9296ae2: update tracking system by custom DB & event handling
14
+
3
15
  ## 0.14.2
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -1,217 +1,85 @@
1
1
  # @adland/data
2
2
 
3
- TypeScript types and Zod schemas for AdLand ad types. Perfect for building forms with react-hook-form, validating data, and type-safe ad handling.
3
+ Type-safe data schemas, validation, and metadata enrichment for [0xSlots](https://0xslots.org) ad types.
4
4
 
5
- ## Installation
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
- ## Usage
16
-
17
- ### TypeScript Types
11
+ ## Ad Types
18
12
 
19
- Types are automatically derived from Zod schemas, ensuring type safety:
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
- ```tsx
22
- import type { AdData, LinkAd, SwapAd } from "@adland/data";
21
+ ## Usage
23
22
 
24
- // Use the types
25
- const linkAd: LinkAd = {
26
- type: "link",
27
- url: "https://example.com",
28
- };
23
+ ### Types
29
24
 
30
- const swapAd: SwapAd = {
31
- type: "swap",
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
- ### Zod Schemas
29
+ ### Form Validation
39
30
 
40
- Use Zod schemas for validation and form integration:
31
+ Each ad definition exposes a Zod schema works directly with form libraries:
41
32
 
42
- ```tsx
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
- // With react-hook-form
48
- function MyForm() {
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
- ## Ad Types
42
+ ### Processing Pipeline
87
43
 
88
- ### Link Ad
89
- Basic link ad type.
44
+ Validate, verify against external sources, and enrich with metadata in one call:
90
45
 
91
- ```typescript
92
- type LinkAd = {
93
- type: "link";
94
- url: string;
95
- }
96
- ```
46
+ ```ts
47
+ import { linkAd } from "@adland/data";
97
48
 
98
- ### Cast Ad
99
- Farcaster cast link ad type.
49
+ const result = await linkAd.safeProcess({ url: "https://example.com" });
100
50
 
101
- ```typescript
102
- type CastAd = {
103
- type: "cast";
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
- ### MiniApp Ad
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
- ### Token Ad
119
- Token information ad type.
59
+ ```ts
60
+ import { ads, getAd, validateAdData } from "@adland/data";
120
61
 
121
- ```typescript
122
- type TokenAd = {
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
- ### Swap Ad
129
- Token swap ad type.
66
+ ### Farcaster Utilities
130
67
 
131
- ```typescript
132
- type SwapAd = {
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
- ## API
71
+ const parsed = parseAccountAssociation(accountAssociation);
72
+ // => { fid, address, type, domain }
73
+ ```
141
74
 
142
- ### Types
75
+ ## How It Works
143
76
 
144
- - `AdType` - Union type of all ad type strings
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
- ### Formik
193
-
194
- ```tsx
195
- import { Formik } from "formik";
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
@@ -60,64 +60,59 @@ async function safeProcessAd(ad, input) {
60
60
  }
61
61
 
62
62
  // src/services/adland.api.ts
63
- var AdlandAPI = class {
64
- constructor() {
65
- }
66
- async verifyCast({ hash }) {
67
- return this.post(`${adlandApiUrl}/verify/cast`, {
68
- hash
69
- });
70
- }
71
- async verifyMiniapp({ domain }) {
72
- return this.post(`${adlandApiUrl}/verify/miniapp`, {
73
- domain
74
- });
75
- }
76
- async getMiniappMetadata({ url }) {
77
- return this.get(`${adlandApiUrl}/metadata/miniapp?url=${encodeURIComponent(url)}`);
78
- }
79
- async getLinkMetadata({ url }) {
80
- return this.get(`${adlandApiUrl}/metadata/link?url=${encodeURIComponent(url)}`);
81
- }
82
- async getCastMetadata({ hash }) {
83
- return this.get(`${adlandApiUrl}/metadata/cast?hash=${encodeURIComponent(hash)}`);
84
- }
85
- async verifyFarcasterProfile({ fid }) {
86
- return this.post(`${adlandApiUrl}/verify/profile`, {
87
- fid
88
- });
89
- }
90
- async getFarcasterProfile({ fid }) {
91
- return this.get(`${adlandApiUrl}/metadata/profile?fid=${encodeURIComponent(fid)}`);
92
- }
93
- async verifyToken({
94
- address,
95
- chainId
96
- }) {
97
- return this.post(`${adlandApiUrl}/verify/token`, {
63
+ var baseUrl = `${adlandApiUrl}/adland`;
64
+ async function post(url, body) {
65
+ return fetch(url, {
66
+ method: "POST",
67
+ body: JSON.stringify(body)
68
+ }).then((res) => res.json());
69
+ }
70
+ async function get(url) {
71
+ return fetch(url).then((res) => res.json());
72
+ }
73
+ var adlandAPI = {
74
+ verify: {
75
+ cast({ hash }) {
76
+ return post(`${baseUrl}/verify/cast`, { hash });
77
+ },
78
+ miniapp({ domain }) {
79
+ return post(`${baseUrl}/verify/miniapp`, {
80
+ domain
81
+ });
82
+ },
83
+ profile({ fid }) {
84
+ return post(`${baseUrl}/verify/profile`, { fid });
85
+ },
86
+ token({ address, chainId }) {
87
+ return post(`${baseUrl}/verify/token`, {
88
+ address,
89
+ chainId
90
+ });
91
+ }
92
+ },
93
+ metadata: {
94
+ cast({ hash }) {
95
+ return get(`${baseUrl}/metadata/cast?hash=${encodeURIComponent(hash)}`);
96
+ },
97
+ miniapp({ url }) {
98
+ return get(`${baseUrl}/metadata/miniapp?url=${encodeURIComponent(url)}`);
99
+ },
100
+ link({ url }) {
101
+ return get(`${baseUrl}/metadata/link?url=${encodeURIComponent(url)}`);
102
+ },
103
+ profile({ fid }) {
104
+ return get(`${baseUrl}/metadata/profile?fid=${encodeURIComponent(fid)}`);
105
+ },
106
+ token({
98
107
  address,
99
108
  chainId
100
- });
101
- }
102
- async getTokenMetadata({
103
- address,
104
- chainId
105
- }) {
106
- return this.get(
107
- `${adlandApiUrl}/metadata/token?address=${encodeURIComponent(address)}&chainId=${chainId}`
108
- );
109
- }
110
- async post(url, body) {
111
- return fetch(url, {
112
- method: "POST",
113
- body: JSON.stringify(body)
114
- }).then((res) => res.json());
115
- }
116
- async get(url) {
117
- return fetch(url).then((res) => res.json());
109
+ }) {
110
+ return get(
111
+ `${baseUrl}/metadata/token?address=${encodeURIComponent(address)}&chainId=${chainId}`
112
+ );
113
+ }
118
114
  }
119
115
  };
120
- var adlandAPI = new AdlandAPI();
121
116
 
122
117
  // src/ads/cast.ts
123
118
  var castAd = defineAd({
@@ -128,23 +123,23 @@ var castAd = defineAd({
128
123
  metadata: zod.z.object({
129
124
  username: zod.z.string().optional(),
130
125
  pfpUrl: zod.z.string().optional(),
131
- text: zod.z.string().optional(),
132
- timestamp: zod.z.number().optional()
126
+ text: zod.z.string(),
127
+ timestamp: zod.z.string()
133
128
  }),
134
129
  async verify({ hash }) {
135
130
  if (!/^0x[0-9a-fA-F]{40}$/.test(hash)) {
136
131
  throw new Error("Invalid Farcaster cast hash");
137
132
  }
138
- const res = await adlandAPI.verifyCast({ hash });
133
+ const res = await adlandAPI.verify.cast({ hash });
139
134
  if (!res.verified) {
140
135
  throw new Error("Cast hash verification failed");
141
136
  }
142
137
  },
143
138
  async getMetadata({ hash }) {
144
- const cast = await adlandAPI.getCastMetadata({ hash });
139
+ const { cast } = await adlandAPI.metadata.cast({ hash });
145
140
  return {
146
- username: cast.username,
147
- pfpUrl: cast.pfpUrl,
141
+ username: cast.author.username,
142
+ pfpUrl: cast.author.pfp_url,
148
143
  text: cast.text,
149
144
  timestamp: cast.timestamp
150
145
  };
@@ -167,7 +162,7 @@ var linkAd = defineAd({
167
162
  }
168
163
  },
169
164
  async getMetadata({ url }) {
170
- const metadata = await adlandAPI.getLinkMetadata({ url });
165
+ const metadata = await adlandAPI.metadata.link({ url });
171
166
  return {
172
167
  title: metadata.title,
173
168
  description: metadata.description,
@@ -194,14 +189,14 @@ var miniappAd = defineAd({
194
189
  if (!domain) {
195
190
  throw new Error(errorMessage);
196
191
  }
197
- const res = await adlandAPI.verifyMiniapp({ domain });
192
+ const res = await adlandAPI.verify.miniapp({ domain });
198
193
  console.log("verifyMiniapp:res", res);
199
194
  if (!res.verified) {
200
195
  throw new Error(errorMessage);
201
196
  }
202
197
  },
203
198
  async getMetadata({ url }) {
204
- const res = await adlandAPI.getMiniappMetadata({ url });
199
+ const res = await adlandAPI.metadata.miniapp({ url });
205
200
  console.log("getMetadata:res", res);
206
201
  return {
207
202
  icon: res.icon,
@@ -227,13 +222,13 @@ var tokenAd = defineAd({
227
222
  logoURI: zod.z.string().optional()
228
223
  }),
229
224
  async verify({ address, chainId }) {
230
- const res = await adlandAPI.verifyToken({ address, chainId });
225
+ const res = await adlandAPI.verify.token({ address, chainId });
231
226
  if (!res.verified) {
232
227
  throw new Error("Token verification failed");
233
228
  }
234
229
  },
235
230
  async getMetadata({ address, chainId }) {
236
- const token = await adlandAPI.getTokenMetadata({ address, chainId });
231
+ const token = await adlandAPI.metadata.token({ address, chainId });
237
232
  return {
238
233
  name: token.name,
239
234
  symbol: token.symbol,
@@ -257,13 +252,13 @@ var farcasterProfileAd = defineAd({
257
252
  pro: zod.z.boolean().optional()
258
253
  }),
259
254
  async verify({ fid }) {
260
- const res = await adlandAPI.verifyFarcasterProfile({ fid });
255
+ const res = await adlandAPI.verify.profile({ fid });
261
256
  if (!res.verified) {
262
257
  throw new Error("Farcaster profile verification failed");
263
258
  }
264
259
  },
265
260
  async getMetadata({ fid }) {
266
- const res = await adlandAPI.getFarcasterProfile({ fid });
261
+ const res = await adlandAPI.metadata.profile({ fid });
267
262
  return {
268
263
  pfpUrl: res.pfpUrl,
269
264
  bio: res.bio,
@@ -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 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"]}
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\";\nimport type {\n CastMetadata,\n LinkMetadata,\n MiniappMetadata,\n ProfileMetadata,\n TokenMetadata,\n} from \"../types\";\n\nconst baseUrl = `${adlandApiUrl}/adland`;\n\nasync function 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\nasync function get<T>(url: string): Promise<T> {\n return fetch(url).then((res) => res.json()) as T;\n}\n\nexport const adlandAPI = {\n verify: {\n cast({ hash }: { hash: string }) {\n return post<{ verified: boolean }>(`${baseUrl}/verify/cast`, { hash });\n },\n\n miniapp({ domain }: { domain: string }) {\n return post<{ verified: boolean }>(`${baseUrl}/verify/miniapp`, {\n domain,\n });\n },\n\n profile({ fid }: { fid: string }) {\n return post<{ verified: boolean }>(`${baseUrl}/verify/profile`, { fid });\n },\n\n token({ address, chainId }: { address: string; chainId: number }) {\n return post<{ verified: boolean }>(`${baseUrl}/verify/token`, {\n address,\n chainId,\n });\n },\n },\n\n metadata: {\n cast({ hash }: { hash: string }): Promise<CastMetadata> {\n return get(`${baseUrl}/metadata/cast?hash=${encodeURIComponent(hash)}`);\n },\n\n miniapp({ url }: { url: string }): Promise<MiniappMetadata> {\n return get(`${baseUrl}/metadata/miniapp?url=${encodeURIComponent(url)}`);\n },\n\n link({ url }: { url: string }): Promise<LinkMetadata> {\n return get(`${baseUrl}/metadata/link?url=${encodeURIComponent(url)}`);\n },\n\n profile({ fid }: { fid: string }): Promise<ProfileMetadata> {\n return get(`${baseUrl}/metadata/profile?fid=${encodeURIComponent(fid)}`);\n },\n\n token({\n address,\n chainId,\n }: {\n address: string;\n chainId: number;\n }): Promise<TokenMetadata> {\n return get(\n `${baseUrl}/metadata/token?address=${encodeURIComponent(address)}&chainId=${chainId}`,\n );\n },\n },\n};\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(),\n timestamp: z.string(),\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.verify.cast({ hash });\n if (!res.verified) {\n throw new Error(\"Cast hash verification failed\");\n }\n },\n async getMetadata({ hash }) {\n const { cast } = await adlandAPI.metadata.cast({ hash });\n return {\n username: cast.author.username,\n pfpUrl: cast.author.pfp_url,\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.metadata.link({ 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.verify.miniapp({ 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.metadata.miniapp({ 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.verify.token({ 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.metadata.token({ 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.verify.profile({ fid });\n if (!res.verified) {\n throw new Error(\"Farcaster profile verification failed\");\n }\n },\n async getMetadata({ fid }) {\n const res = await adlandAPI.metadata.profile({ 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 { tokenAd } from \"./ads/token\";\nimport { farcasterProfileAd } from \"./ads/profile\";\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\";\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"]}