@chillwhales/lsp2 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Chillwhales contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # @chillwhales/lsp2
2
+
3
+ [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
4
+
5
+ LSP2 ERC725Y JSON Schema — shared primitives, VerifiableURI encoding/decoding, and image utilities for LUKSO dApps.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pnpm add @chillwhales/lsp2
11
+ ```
12
+
13
+ > **Peer dependency:** This package requires [`viem`](https://viem.sh) ^2.0.0
14
+ >
15
+ > ```bash
16
+ > pnpm add viem
17
+ > ```
18
+
19
+ ## Usage
20
+
21
+ ```typescript
22
+ import { encodeVerifiableUri, parseVerifiableUri } from "@chillwhales/lsp2";
23
+
24
+ // Encode metadata as a VerifiableURI for on-chain storage
25
+ const metadata = {
26
+ LSP4Metadata: { name: "My Token", description: "A LUKSO token" },
27
+ };
28
+ const encoded = encodeVerifiableUri(metadata, "ipfs://QmYwAPJz...");
29
+ // encoded is a hex string ready for setData()
30
+
31
+ // Later, read back from on-chain and parse the components
32
+ const { verificationMethod, verificationData, url } =
33
+ parseVerifiableUri(encoded);
34
+ console.log(url); // "ipfs://QmYwAPJz..."
35
+ ```
36
+
37
+ > **Spec:** [LSP-2 ERC725Y JSON Schema](https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-2-ERC725YJSONSchema.md)
38
+
39
+ ## API
40
+
41
+ Types are exported and available in your editor via TypeScript IntelliSense.
42
+
43
+ ## License
44
+
45
+ [MIT](./LICENSE)
@@ -0,0 +1,423 @@
1
+ import { z } from 'zod';
2
+ import { Hex } from 'viem';
3
+
4
+ /**
5
+ * LSP2 ERC725Y JSON Schema Constants
6
+ *
7
+ * @see https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-2-ERC725YJSONSchema.md
8
+ */
9
+ /**
10
+ * LSP2 VerifiableURI verification methods
11
+ */
12
+ declare enum VERIFICATION_METHODS {
13
+ HASH_KECCAK256_UTF8 = "keccak256(utf8)",
14
+ HASH_KECCAK256_BYTES = "keccak256(bytes)",
15
+ ECDSA = "ecdsa"
16
+ }
17
+ /** Separator used in LSP2 mapping keys */
18
+ declare const MAPPING_SEPARATOR = "0x0000";
19
+ /**
20
+ * Verification method ID for keccak256(bytes)
21
+ * Computed as: bytes4(keccak256('keccak256(bytes)')) = 0x8019f9b1
22
+ */
23
+ declare const KECCAK256_BYTES_METHOD_ID: "0x8019f9b1";
24
+ /**
25
+ * Reserved bytes prefix (2 bytes of zeros) for VerifiableURI
26
+ */
27
+ declare const RESERVED_PREFIX: "0x0000";
28
+ /**
29
+ * Length of a keccak256 hash in bytes (32 bytes = 0x0020)
30
+ */
31
+ declare const HASH_LENGTH_PREFIX: "0x0020";
32
+ /**
33
+ * Minimum length of a valid VerifiableURI value in bytes
34
+ * 2 (reserved) + 4 (method ID) + 2 (hash length) + 32 (hash) = 40 bytes = 80 hex chars + '0x'
35
+ */
36
+ declare const MIN_VERIFIABLE_URI_LENGTH = 82;
37
+
38
+ /**
39
+ * LSP2 Shared Primitive Schemas
40
+ *
41
+ * Reusable Zod schemas for LSP2/LSP3/LSP4 metadata validation.
42
+ * These are the foundation schemas that downstream packages depend on.
43
+ *
44
+ * @see https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-2-ERC725YJSONSchema.md
45
+ */
46
+
47
+ /**
48
+ * Validates an Ethereum address (0x... format)
49
+ */
50
+ declare const addressSchema: z.ZodString;
51
+ /**
52
+ * Validates a 32-byte hex string (0x + 64 chars)
53
+ */
54
+ declare const bytes32Schema: z.ZodString;
55
+ /**
56
+ * Validates any hex string (0x...)
57
+ */
58
+ declare const bytesSchema: z.ZodString;
59
+ /**
60
+ * Verification data schema for LSP2 ERC725YJSONSchema
61
+ */
62
+ declare const verificationSchema: z.ZodDiscriminatedUnion<"method", [z.ZodObject<{
63
+ data: z.ZodString;
64
+ method: z.ZodEnum<[VERIFICATION_METHODS.HASH_KECCAK256_BYTES, VERIFICATION_METHODS.HASH_KECCAK256_UTF8]>;
65
+ }, "strip", z.ZodTypeAny, {
66
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
67
+ data: string;
68
+ }, {
69
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
70
+ data: string;
71
+ }>, z.ZodObject<{
72
+ method: z.ZodEnum<[VERIFICATION_METHODS.ECDSA]>;
73
+ /** Signer address */
74
+ data: z.ZodString;
75
+ /** URL where the signature can be retrieved */
76
+ source: z.ZodString;
77
+ }, "strip", z.ZodTypeAny, {
78
+ method: VERIFICATION_METHODS.ECDSA;
79
+ data: string;
80
+ source: string;
81
+ }, {
82
+ method: VERIFICATION_METHODS.ECDSA;
83
+ data: string;
84
+ source: string;
85
+ }>]>;
86
+ /**
87
+ * Image metadata schema (LSP3/LSP4)
88
+ */
89
+ declare const imageSchema: z.ZodObject<{
90
+ url: z.ZodString;
91
+ width: z.ZodNumber;
92
+ height: z.ZodNumber;
93
+ verification: z.ZodDiscriminatedUnion<"method", [z.ZodObject<{
94
+ data: z.ZodString;
95
+ method: z.ZodEnum<[VERIFICATION_METHODS.HASH_KECCAK256_BYTES, VERIFICATION_METHODS.HASH_KECCAK256_UTF8]>;
96
+ }, "strip", z.ZodTypeAny, {
97
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
98
+ data: string;
99
+ }, {
100
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
101
+ data: string;
102
+ }>, z.ZodObject<{
103
+ method: z.ZodEnum<[VERIFICATION_METHODS.ECDSA]>;
104
+ /** Signer address */
105
+ data: z.ZodString;
106
+ /** URL where the signature can be retrieved */
107
+ source: z.ZodString;
108
+ }, "strip", z.ZodTypeAny, {
109
+ method: VERIFICATION_METHODS.ECDSA;
110
+ data: string;
111
+ source: string;
112
+ }, {
113
+ method: VERIFICATION_METHODS.ECDSA;
114
+ data: string;
115
+ source: string;
116
+ }>]>;
117
+ }, "strip", z.ZodTypeAny, {
118
+ url: string;
119
+ width: number;
120
+ height: number;
121
+ verification: {
122
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
123
+ data: string;
124
+ } | {
125
+ method: VERIFICATION_METHODS.ECDSA;
126
+ data: string;
127
+ source: string;
128
+ };
129
+ }, {
130
+ url: string;
131
+ width: number;
132
+ height: number;
133
+ verification: {
134
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
135
+ data: string;
136
+ } | {
137
+ method: VERIFICATION_METHODS.ECDSA;
138
+ data: string;
139
+ source: string;
140
+ };
141
+ }>;
142
+ /**
143
+ * Asset metadata schema (LSP3/LSP4)
144
+ */
145
+ declare const assetSchema: z.ZodObject<{
146
+ url: z.ZodString;
147
+ fileType: z.ZodString;
148
+ verification: z.ZodDiscriminatedUnion<"method", [z.ZodObject<{
149
+ data: z.ZodString;
150
+ method: z.ZodEnum<[VERIFICATION_METHODS.HASH_KECCAK256_BYTES, VERIFICATION_METHODS.HASH_KECCAK256_UTF8]>;
151
+ }, "strip", z.ZodTypeAny, {
152
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
153
+ data: string;
154
+ }, {
155
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
156
+ data: string;
157
+ }>, z.ZodObject<{
158
+ method: z.ZodEnum<[VERIFICATION_METHODS.ECDSA]>;
159
+ /** Signer address */
160
+ data: z.ZodString;
161
+ /** URL where the signature can be retrieved */
162
+ source: z.ZodString;
163
+ }, "strip", z.ZodTypeAny, {
164
+ method: VERIFICATION_METHODS.ECDSA;
165
+ data: string;
166
+ source: string;
167
+ }, {
168
+ method: VERIFICATION_METHODS.ECDSA;
169
+ data: string;
170
+ source: string;
171
+ }>]>;
172
+ }, "strip", z.ZodTypeAny, {
173
+ url: string;
174
+ verification: {
175
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
176
+ data: string;
177
+ } | {
178
+ method: VERIFICATION_METHODS.ECDSA;
179
+ data: string;
180
+ source: string;
181
+ };
182
+ fileType: string;
183
+ }, {
184
+ url: string;
185
+ verification: {
186
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
187
+ data: string;
188
+ } | {
189
+ method: VERIFICATION_METHODS.ECDSA;
190
+ data: string;
191
+ source: string;
192
+ };
193
+ fileType: string;
194
+ }>;
195
+ /**
196
+ * Link schema (LSP3/LSP4)
197
+ */
198
+ declare const linkSchema: z.ZodObject<{
199
+ title: z.ZodString;
200
+ url: z.ZodString;
201
+ }, "strip", z.ZodTypeAny, {
202
+ url: string;
203
+ title: string;
204
+ }, {
205
+ url: string;
206
+ title: string;
207
+ }>;
208
+ /**
209
+ * Tag schema (LSP3/LSP4)
210
+ */
211
+ declare const tagSchema: z.ZodString;
212
+
213
+ /**
214
+ * LSP2 Type Guards
215
+ *
216
+ * Runtime type guards using Zod schema validation.
217
+ */
218
+
219
+ /**
220
+ * Type guard for image schema
221
+ */
222
+ declare function isImageSchema(obj: unknown): obj is z.infer<typeof imageSchema>;
223
+ /**
224
+ * Type guard for link schema
225
+ */
226
+ declare function isLinkSchema(obj: unknown): obj is z.infer<typeof linkSchema>;
227
+ /**
228
+ * Type guard for tag schema
229
+ */
230
+ declare function isTagSchema(obj: unknown): obj is z.infer<typeof tagSchema>;
231
+ /**
232
+ * Type guard for asset schema
233
+ */
234
+ declare function isAssetSchema(obj: unknown): obj is z.infer<typeof assetSchema>;
235
+
236
+ /**
237
+ * LSP2 Inferred Types
238
+ *
239
+ * TypeScript types inferred from LSP2 Zod schemas.
240
+ */
241
+
242
+ type Verification = z.infer<typeof verificationSchema>;
243
+ type Image = z.infer<typeof imageSchema>;
244
+ type ImagesArray = Image[];
245
+ type ImagesMatrix = ImagesArray[];
246
+ type Asset = z.infer<typeof assetSchema>;
247
+ type Link = z.infer<typeof linkSchema>;
248
+ type Tag = z.infer<typeof tagSchema>;
249
+
250
+ /**
251
+ * LSP2 Image Utilities
252
+ *
253
+ * Functions for finding optimal images from LSP metadata arrays.
254
+ * Used by downstream LSP3/LSP4 packages for profile and asset images.
255
+ */
256
+
257
+ /**
258
+ * Image size in pixels
259
+ */
260
+ interface ImageSize {
261
+ /** Width in pixels */
262
+ width: number;
263
+ /** Height in pixels */
264
+ height: number;
265
+ }
266
+ /**
267
+ * Find the best matching image from an array based on target dimensions.
268
+ * If no dimensions provided, returns the first image.
269
+ *
270
+ * @param images - Array of images with url, width, height
271
+ * @param options - Optional target dimensions
272
+ * @returns The best matching image or undefined
273
+ */
274
+ declare function findBestImage(images: Image[] | undefined, options?: Partial<ImageSize>): Image | undefined;
275
+ /**
276
+ * Finds the image closest to the target resolution
277
+ *
278
+ * Uses Euclidean distance in resolution space.
279
+ *
280
+ * @param images - Array of image objects
281
+ * @param targetWidth - Target width
282
+ * @param targetHeight - Target height
283
+ * @returns The closest image object or null if no images provided
284
+ */
285
+ declare function findClosestImage(images: Image[], targetWidth: number, targetHeight: number): Image | null;
286
+
287
+ /**
288
+ * LSP2 VerifiableURI Encoding/Decoding Utilities
289
+ *
290
+ * Pure functions for encoding and decoding VerifiableURI values according to
291
+ * the LSP2 ERC725Y JSON Schema specification.
292
+ *
293
+ * @see https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-2-ERC725YJSONSchema.md
294
+ */
295
+
296
+ /**
297
+ * Parsed components of a VerifiableURI
298
+ */
299
+ interface ParsedVerifiableUri {
300
+ /** Verification method ID (e.g., 0x6f357c6a for keccak256(bytes)) */
301
+ verificationMethod: Hex;
302
+ /** Verification hash (32 bytes) */
303
+ verificationData: Hex;
304
+ /** The URL pointing to the content (e.g., ipfs://Qm...) */
305
+ url: string;
306
+ }
307
+ /**
308
+ * Result of decoding a VerifiableURI
309
+ */
310
+ interface DecodedVerifiableUri<T> {
311
+ /** The parsed and validated data */
312
+ data: T;
313
+ /** The URL extracted from the VerifiableURI */
314
+ url: string;
315
+ }
316
+ /**
317
+ * Encodes data as a VerifiableURI value
318
+ *
319
+ * Creates an ERC725Y-compatible VerifiableURI encoding with:
320
+ * - 2 bytes reserved (0x0000)
321
+ * - 4 bytes verification method ID (keccak256(bytes)) = 0x8019f9b1
322
+ * - 2 bytes verification data length (0x0020 = 32)
323
+ * - 32 bytes verification hash
324
+ * - UTF-8 encoded URL
325
+ *
326
+ * @param data - Any JSON-serializable object to encode
327
+ * @param ipfsUrl - IPFS URL where the JSON will be stored (e.g., "ipfs://Qm...")
328
+ * @returns Hex-encoded VerifiableURI value
329
+ *
330
+ * @example
331
+ * ```typescript
332
+ * import { encodeVerifiableUri } from '@chillwhales/lsp2';
333
+ *
334
+ * const metadata = { LSP4Metadata: { name: 'My Token', description: 'A token' } };
335
+ * const value = encodeVerifiableUri(metadata, 'ipfs://QmXyz...');
336
+ * // Use with setData operation
337
+ * ```
338
+ */
339
+ declare function encodeVerifiableUri<T>(data: T, ipfsUrl: string): Hex;
340
+ /**
341
+ * Parses a VerifiableURI hex value into its components
342
+ *
343
+ * Format: 0x + reserved (2 bytes) + method (4 bytes) + length (2 bytes) + hash (N bytes) + url
344
+ *
345
+ * @param value - The raw hex value from ERC725Y getData
346
+ * @returns Parsed components (method, hash, url)
347
+ * @throws Error if the value is malformed
348
+ *
349
+ * @example
350
+ * ```typescript
351
+ * import { parseVerifiableUri } from '@chillwhales/lsp2';
352
+ *
353
+ * const { verificationMethod, verificationData, url } = parseVerifiableUri(rawValue);
354
+ * console.log(url); // 'ipfs://Qm...'
355
+ * ```
356
+ */
357
+ declare function parseVerifiableUri(value: Hex): ParsedVerifiableUri;
358
+ /**
359
+ * Decodes a VerifiableURI value and validates the content
360
+ *
361
+ * @param verifiableUriValue - The raw hex value from ERC725Y getData
362
+ * @param jsonContent - The JSON content fetched from the URL
363
+ * @param schema - Optional Zod schema for type validation
364
+ * @returns Decoded data and URL
365
+ * @throws Error if hash doesn't match or schema validation fails
366
+ *
367
+ * @example
368
+ * ```typescript
369
+ * import { decodeVerifiableUri } from '@chillwhales/lsp2';
370
+ *
371
+ * // Fetch JSON from IPFS first
372
+ * const jsonContent = await fetchFromIpfs(url);
373
+ *
374
+ * // Decode with schema validation
375
+ * const { data, url } = decodeVerifiableUri(
376
+ * rawValue,
377
+ * jsonContent,
378
+ * mySchema
379
+ * );
380
+ *
381
+ * // Decode without schema (caller handles typing)
382
+ * const { data: rawData } = decodeVerifiableUri<MyType>(rawValue, jsonContent);
383
+ * ```
384
+ */
385
+ declare function decodeVerifiableUri<T>(verifiableUriValue: Hex, jsonContent: string, schema?: z.ZodSchema<T>): DecodedVerifiableUri<T>;
386
+ /**
387
+ * Computes the verification hash for JSON data
388
+ *
389
+ * Useful when you need to compute the hash without encoding the full VerifiableURI.
390
+ *
391
+ * @param data - Any JSON-serializable object
392
+ * @returns The keccak256 hash as a Hex string
393
+ *
394
+ * @example
395
+ * ```typescript
396
+ * import { computeVerificationHash } from '@chillwhales/lsp2';
397
+ *
398
+ * const hash = computeVerificationHash({ name: 'My Profile' });
399
+ * // Use for verification or comparison
400
+ * ```
401
+ */
402
+ declare function computeVerificationHash<T>(data: T): Hex;
403
+ /**
404
+ * Checks if a hex value appears to be a valid VerifiableURI format
405
+ *
406
+ * This is a quick check based on structure, not content validation.
407
+ *
408
+ * @param value - Hex value to check
409
+ * @returns true if the value has valid VerifiableURI structure
410
+ *
411
+ * @example
412
+ * ```typescript
413
+ * import { isVerifiableUri } from '@chillwhales/lsp2';
414
+ *
415
+ * if (isVerifiableUri(rawValue)) {
416
+ * const { url } = parseVerifiableUri(rawValue);
417
+ * }
418
+ * ```
419
+ */
420
+ declare function isVerifiableUri(value: Hex): boolean;
421
+
422
+ export { HASH_LENGTH_PREFIX, KECCAK256_BYTES_METHOD_ID, MAPPING_SEPARATOR, MIN_VERIFIABLE_URI_LENGTH, RESERVED_PREFIX, VERIFICATION_METHODS, addressSchema, assetSchema, bytes32Schema, bytesSchema, computeVerificationHash, decodeVerifiableUri, encodeVerifiableUri, findBestImage, findClosestImage, imageSchema, isAssetSchema, isImageSchema, isLinkSchema, isTagSchema, isVerifiableUri, linkSchema, parseVerifiableUri, tagSchema, verificationSchema };
423
+ export type { Asset, DecodedVerifiableUri, Image, ImageSize, ImagesArray, ImagesMatrix, Link, ParsedVerifiableUri, Tag, Verification };
@@ -0,0 +1,423 @@
1
+ import { z } from 'zod';
2
+ import { Hex } from 'viem';
3
+
4
+ /**
5
+ * LSP2 ERC725Y JSON Schema Constants
6
+ *
7
+ * @see https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-2-ERC725YJSONSchema.md
8
+ */
9
+ /**
10
+ * LSP2 VerifiableURI verification methods
11
+ */
12
+ declare enum VERIFICATION_METHODS {
13
+ HASH_KECCAK256_UTF8 = "keccak256(utf8)",
14
+ HASH_KECCAK256_BYTES = "keccak256(bytes)",
15
+ ECDSA = "ecdsa"
16
+ }
17
+ /** Separator used in LSP2 mapping keys */
18
+ declare const MAPPING_SEPARATOR = "0x0000";
19
+ /**
20
+ * Verification method ID for keccak256(bytes)
21
+ * Computed as: bytes4(keccak256('keccak256(bytes)')) = 0x8019f9b1
22
+ */
23
+ declare const KECCAK256_BYTES_METHOD_ID: "0x8019f9b1";
24
+ /**
25
+ * Reserved bytes prefix (2 bytes of zeros) for VerifiableURI
26
+ */
27
+ declare const RESERVED_PREFIX: "0x0000";
28
+ /**
29
+ * Length of a keccak256 hash in bytes (32 bytes = 0x0020)
30
+ */
31
+ declare const HASH_LENGTH_PREFIX: "0x0020";
32
+ /**
33
+ * Minimum length of a valid VerifiableURI value in bytes
34
+ * 2 (reserved) + 4 (method ID) + 2 (hash length) + 32 (hash) = 40 bytes = 80 hex chars + '0x'
35
+ */
36
+ declare const MIN_VERIFIABLE_URI_LENGTH = 82;
37
+
38
+ /**
39
+ * LSP2 Shared Primitive Schemas
40
+ *
41
+ * Reusable Zod schemas for LSP2/LSP3/LSP4 metadata validation.
42
+ * These are the foundation schemas that downstream packages depend on.
43
+ *
44
+ * @see https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-2-ERC725YJSONSchema.md
45
+ */
46
+
47
+ /**
48
+ * Validates an Ethereum address (0x... format)
49
+ */
50
+ declare const addressSchema: z.ZodString;
51
+ /**
52
+ * Validates a 32-byte hex string (0x + 64 chars)
53
+ */
54
+ declare const bytes32Schema: z.ZodString;
55
+ /**
56
+ * Validates any hex string (0x...)
57
+ */
58
+ declare const bytesSchema: z.ZodString;
59
+ /**
60
+ * Verification data schema for LSP2 ERC725YJSONSchema
61
+ */
62
+ declare const verificationSchema: z.ZodDiscriminatedUnion<"method", [z.ZodObject<{
63
+ data: z.ZodString;
64
+ method: z.ZodEnum<[VERIFICATION_METHODS.HASH_KECCAK256_BYTES, VERIFICATION_METHODS.HASH_KECCAK256_UTF8]>;
65
+ }, "strip", z.ZodTypeAny, {
66
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
67
+ data: string;
68
+ }, {
69
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
70
+ data: string;
71
+ }>, z.ZodObject<{
72
+ method: z.ZodEnum<[VERIFICATION_METHODS.ECDSA]>;
73
+ /** Signer address */
74
+ data: z.ZodString;
75
+ /** URL where the signature can be retrieved */
76
+ source: z.ZodString;
77
+ }, "strip", z.ZodTypeAny, {
78
+ method: VERIFICATION_METHODS.ECDSA;
79
+ data: string;
80
+ source: string;
81
+ }, {
82
+ method: VERIFICATION_METHODS.ECDSA;
83
+ data: string;
84
+ source: string;
85
+ }>]>;
86
+ /**
87
+ * Image metadata schema (LSP3/LSP4)
88
+ */
89
+ declare const imageSchema: z.ZodObject<{
90
+ url: z.ZodString;
91
+ width: z.ZodNumber;
92
+ height: z.ZodNumber;
93
+ verification: z.ZodDiscriminatedUnion<"method", [z.ZodObject<{
94
+ data: z.ZodString;
95
+ method: z.ZodEnum<[VERIFICATION_METHODS.HASH_KECCAK256_BYTES, VERIFICATION_METHODS.HASH_KECCAK256_UTF8]>;
96
+ }, "strip", z.ZodTypeAny, {
97
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
98
+ data: string;
99
+ }, {
100
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
101
+ data: string;
102
+ }>, z.ZodObject<{
103
+ method: z.ZodEnum<[VERIFICATION_METHODS.ECDSA]>;
104
+ /** Signer address */
105
+ data: z.ZodString;
106
+ /** URL where the signature can be retrieved */
107
+ source: z.ZodString;
108
+ }, "strip", z.ZodTypeAny, {
109
+ method: VERIFICATION_METHODS.ECDSA;
110
+ data: string;
111
+ source: string;
112
+ }, {
113
+ method: VERIFICATION_METHODS.ECDSA;
114
+ data: string;
115
+ source: string;
116
+ }>]>;
117
+ }, "strip", z.ZodTypeAny, {
118
+ url: string;
119
+ width: number;
120
+ height: number;
121
+ verification: {
122
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
123
+ data: string;
124
+ } | {
125
+ method: VERIFICATION_METHODS.ECDSA;
126
+ data: string;
127
+ source: string;
128
+ };
129
+ }, {
130
+ url: string;
131
+ width: number;
132
+ height: number;
133
+ verification: {
134
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
135
+ data: string;
136
+ } | {
137
+ method: VERIFICATION_METHODS.ECDSA;
138
+ data: string;
139
+ source: string;
140
+ };
141
+ }>;
142
+ /**
143
+ * Asset metadata schema (LSP3/LSP4)
144
+ */
145
+ declare const assetSchema: z.ZodObject<{
146
+ url: z.ZodString;
147
+ fileType: z.ZodString;
148
+ verification: z.ZodDiscriminatedUnion<"method", [z.ZodObject<{
149
+ data: z.ZodString;
150
+ method: z.ZodEnum<[VERIFICATION_METHODS.HASH_KECCAK256_BYTES, VERIFICATION_METHODS.HASH_KECCAK256_UTF8]>;
151
+ }, "strip", z.ZodTypeAny, {
152
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
153
+ data: string;
154
+ }, {
155
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
156
+ data: string;
157
+ }>, z.ZodObject<{
158
+ method: z.ZodEnum<[VERIFICATION_METHODS.ECDSA]>;
159
+ /** Signer address */
160
+ data: z.ZodString;
161
+ /** URL where the signature can be retrieved */
162
+ source: z.ZodString;
163
+ }, "strip", z.ZodTypeAny, {
164
+ method: VERIFICATION_METHODS.ECDSA;
165
+ data: string;
166
+ source: string;
167
+ }, {
168
+ method: VERIFICATION_METHODS.ECDSA;
169
+ data: string;
170
+ source: string;
171
+ }>]>;
172
+ }, "strip", z.ZodTypeAny, {
173
+ url: string;
174
+ verification: {
175
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
176
+ data: string;
177
+ } | {
178
+ method: VERIFICATION_METHODS.ECDSA;
179
+ data: string;
180
+ source: string;
181
+ };
182
+ fileType: string;
183
+ }, {
184
+ url: string;
185
+ verification: {
186
+ method: VERIFICATION_METHODS.HASH_KECCAK256_UTF8 | VERIFICATION_METHODS.HASH_KECCAK256_BYTES;
187
+ data: string;
188
+ } | {
189
+ method: VERIFICATION_METHODS.ECDSA;
190
+ data: string;
191
+ source: string;
192
+ };
193
+ fileType: string;
194
+ }>;
195
+ /**
196
+ * Link schema (LSP3/LSP4)
197
+ */
198
+ declare const linkSchema: z.ZodObject<{
199
+ title: z.ZodString;
200
+ url: z.ZodString;
201
+ }, "strip", z.ZodTypeAny, {
202
+ url: string;
203
+ title: string;
204
+ }, {
205
+ url: string;
206
+ title: string;
207
+ }>;
208
+ /**
209
+ * Tag schema (LSP3/LSP4)
210
+ */
211
+ declare const tagSchema: z.ZodString;
212
+
213
+ /**
214
+ * LSP2 Type Guards
215
+ *
216
+ * Runtime type guards using Zod schema validation.
217
+ */
218
+
219
+ /**
220
+ * Type guard for image schema
221
+ */
222
+ declare function isImageSchema(obj: unknown): obj is z.infer<typeof imageSchema>;
223
+ /**
224
+ * Type guard for link schema
225
+ */
226
+ declare function isLinkSchema(obj: unknown): obj is z.infer<typeof linkSchema>;
227
+ /**
228
+ * Type guard for tag schema
229
+ */
230
+ declare function isTagSchema(obj: unknown): obj is z.infer<typeof tagSchema>;
231
+ /**
232
+ * Type guard for asset schema
233
+ */
234
+ declare function isAssetSchema(obj: unknown): obj is z.infer<typeof assetSchema>;
235
+
236
+ /**
237
+ * LSP2 Inferred Types
238
+ *
239
+ * TypeScript types inferred from LSP2 Zod schemas.
240
+ */
241
+
242
+ type Verification = z.infer<typeof verificationSchema>;
243
+ type Image = z.infer<typeof imageSchema>;
244
+ type ImagesArray = Image[];
245
+ type ImagesMatrix = ImagesArray[];
246
+ type Asset = z.infer<typeof assetSchema>;
247
+ type Link = z.infer<typeof linkSchema>;
248
+ type Tag = z.infer<typeof tagSchema>;
249
+
250
+ /**
251
+ * LSP2 Image Utilities
252
+ *
253
+ * Functions for finding optimal images from LSP metadata arrays.
254
+ * Used by downstream LSP3/LSP4 packages for profile and asset images.
255
+ */
256
+
257
+ /**
258
+ * Image size in pixels
259
+ */
260
+ interface ImageSize {
261
+ /** Width in pixels */
262
+ width: number;
263
+ /** Height in pixels */
264
+ height: number;
265
+ }
266
+ /**
267
+ * Find the best matching image from an array based on target dimensions.
268
+ * If no dimensions provided, returns the first image.
269
+ *
270
+ * @param images - Array of images with url, width, height
271
+ * @param options - Optional target dimensions
272
+ * @returns The best matching image or undefined
273
+ */
274
+ declare function findBestImage(images: Image[] | undefined, options?: Partial<ImageSize>): Image | undefined;
275
+ /**
276
+ * Finds the image closest to the target resolution
277
+ *
278
+ * Uses Euclidean distance in resolution space.
279
+ *
280
+ * @param images - Array of image objects
281
+ * @param targetWidth - Target width
282
+ * @param targetHeight - Target height
283
+ * @returns The closest image object or null if no images provided
284
+ */
285
+ declare function findClosestImage(images: Image[], targetWidth: number, targetHeight: number): Image | null;
286
+
287
+ /**
288
+ * LSP2 VerifiableURI Encoding/Decoding Utilities
289
+ *
290
+ * Pure functions for encoding and decoding VerifiableURI values according to
291
+ * the LSP2 ERC725Y JSON Schema specification.
292
+ *
293
+ * @see https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-2-ERC725YJSONSchema.md
294
+ */
295
+
296
+ /**
297
+ * Parsed components of a VerifiableURI
298
+ */
299
+ interface ParsedVerifiableUri {
300
+ /** Verification method ID (e.g., 0x6f357c6a for keccak256(bytes)) */
301
+ verificationMethod: Hex;
302
+ /** Verification hash (32 bytes) */
303
+ verificationData: Hex;
304
+ /** The URL pointing to the content (e.g., ipfs://Qm...) */
305
+ url: string;
306
+ }
307
+ /**
308
+ * Result of decoding a VerifiableURI
309
+ */
310
+ interface DecodedVerifiableUri<T> {
311
+ /** The parsed and validated data */
312
+ data: T;
313
+ /** The URL extracted from the VerifiableURI */
314
+ url: string;
315
+ }
316
+ /**
317
+ * Encodes data as a VerifiableURI value
318
+ *
319
+ * Creates an ERC725Y-compatible VerifiableURI encoding with:
320
+ * - 2 bytes reserved (0x0000)
321
+ * - 4 bytes verification method ID (keccak256(bytes)) = 0x8019f9b1
322
+ * - 2 bytes verification data length (0x0020 = 32)
323
+ * - 32 bytes verification hash
324
+ * - UTF-8 encoded URL
325
+ *
326
+ * @param data - Any JSON-serializable object to encode
327
+ * @param ipfsUrl - IPFS URL where the JSON will be stored (e.g., "ipfs://Qm...")
328
+ * @returns Hex-encoded VerifiableURI value
329
+ *
330
+ * @example
331
+ * ```typescript
332
+ * import { encodeVerifiableUri } from '@chillwhales/lsp2';
333
+ *
334
+ * const metadata = { LSP4Metadata: { name: 'My Token', description: 'A token' } };
335
+ * const value = encodeVerifiableUri(metadata, 'ipfs://QmXyz...');
336
+ * // Use with setData operation
337
+ * ```
338
+ */
339
+ declare function encodeVerifiableUri<T>(data: T, ipfsUrl: string): Hex;
340
+ /**
341
+ * Parses a VerifiableURI hex value into its components
342
+ *
343
+ * Format: 0x + reserved (2 bytes) + method (4 bytes) + length (2 bytes) + hash (N bytes) + url
344
+ *
345
+ * @param value - The raw hex value from ERC725Y getData
346
+ * @returns Parsed components (method, hash, url)
347
+ * @throws Error if the value is malformed
348
+ *
349
+ * @example
350
+ * ```typescript
351
+ * import { parseVerifiableUri } from '@chillwhales/lsp2';
352
+ *
353
+ * const { verificationMethod, verificationData, url } = parseVerifiableUri(rawValue);
354
+ * console.log(url); // 'ipfs://Qm...'
355
+ * ```
356
+ */
357
+ declare function parseVerifiableUri(value: Hex): ParsedVerifiableUri;
358
+ /**
359
+ * Decodes a VerifiableURI value and validates the content
360
+ *
361
+ * @param verifiableUriValue - The raw hex value from ERC725Y getData
362
+ * @param jsonContent - The JSON content fetched from the URL
363
+ * @param schema - Optional Zod schema for type validation
364
+ * @returns Decoded data and URL
365
+ * @throws Error if hash doesn't match or schema validation fails
366
+ *
367
+ * @example
368
+ * ```typescript
369
+ * import { decodeVerifiableUri } from '@chillwhales/lsp2';
370
+ *
371
+ * // Fetch JSON from IPFS first
372
+ * const jsonContent = await fetchFromIpfs(url);
373
+ *
374
+ * // Decode with schema validation
375
+ * const { data, url } = decodeVerifiableUri(
376
+ * rawValue,
377
+ * jsonContent,
378
+ * mySchema
379
+ * );
380
+ *
381
+ * // Decode without schema (caller handles typing)
382
+ * const { data: rawData } = decodeVerifiableUri<MyType>(rawValue, jsonContent);
383
+ * ```
384
+ */
385
+ declare function decodeVerifiableUri<T>(verifiableUriValue: Hex, jsonContent: string, schema?: z.ZodSchema<T>): DecodedVerifiableUri<T>;
386
+ /**
387
+ * Computes the verification hash for JSON data
388
+ *
389
+ * Useful when you need to compute the hash without encoding the full VerifiableURI.
390
+ *
391
+ * @param data - Any JSON-serializable object
392
+ * @returns The keccak256 hash as a Hex string
393
+ *
394
+ * @example
395
+ * ```typescript
396
+ * import { computeVerificationHash } from '@chillwhales/lsp2';
397
+ *
398
+ * const hash = computeVerificationHash({ name: 'My Profile' });
399
+ * // Use for verification or comparison
400
+ * ```
401
+ */
402
+ declare function computeVerificationHash<T>(data: T): Hex;
403
+ /**
404
+ * Checks if a hex value appears to be a valid VerifiableURI format
405
+ *
406
+ * This is a quick check based on structure, not content validation.
407
+ *
408
+ * @param value - Hex value to check
409
+ * @returns true if the value has valid VerifiableURI structure
410
+ *
411
+ * @example
412
+ * ```typescript
413
+ * import { isVerifiableUri } from '@chillwhales/lsp2';
414
+ *
415
+ * if (isVerifiableUri(rawValue)) {
416
+ * const { url } = parseVerifiableUri(rawValue);
417
+ * }
418
+ * ```
419
+ */
420
+ declare function isVerifiableUri(value: Hex): boolean;
421
+
422
+ export { HASH_LENGTH_PREFIX, KECCAK256_BYTES_METHOD_ID, MAPPING_SEPARATOR, MIN_VERIFIABLE_URI_LENGTH, RESERVED_PREFIX, VERIFICATION_METHODS, addressSchema, assetSchema, bytes32Schema, bytesSchema, computeVerificationHash, decodeVerifiableUri, encodeVerifiableUri, findBestImage, findClosestImage, imageSchema, isAssetSchema, isImageSchema, isLinkSchema, isTagSchema, isVerifiableUri, linkSchema, parseVerifiableUri, tagSchema, verificationSchema };
423
+ export type { Asset, DecodedVerifiableUri, Image, ImageSize, ImagesArray, ImagesMatrix, Link, ParsedVerifiableUri, Tag, Verification };
package/dist/index.mjs ADDED
@@ -0,0 +1,188 @@
1
+ import { z } from 'zod';
2
+ import { keccak256, stringToHex, concat, slice, hexToString } from 'viem';
3
+
4
+ var VERIFICATION_METHODS = /* @__PURE__ */ ((VERIFICATION_METHODS2) => {
5
+ VERIFICATION_METHODS2["HASH_KECCAK256_UTF8"] = "keccak256(utf8)";
6
+ VERIFICATION_METHODS2["HASH_KECCAK256_BYTES"] = "keccak256(bytes)";
7
+ VERIFICATION_METHODS2["ECDSA"] = "ecdsa";
8
+ return VERIFICATION_METHODS2;
9
+ })(VERIFICATION_METHODS || {});
10
+ const MAPPING_SEPARATOR = "0x0000";
11
+ const KECCAK256_BYTES_METHOD_ID = "0x8019f9b1";
12
+ const RESERVED_PREFIX = "0x0000";
13
+ const HASH_LENGTH_PREFIX = "0x0020";
14
+ const MIN_VERIFIABLE_URI_LENGTH = 82;
15
+
16
+ const EVM_ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;
17
+ const BYTES32_REGEX = /^0x[0-9a-fA-F]{64}$/;
18
+ const BYTES_REGEX = /^0x[0-9a-fA-F]*$/;
19
+ const addressSchema = z.string({
20
+ invalid_type_error: "Invalid value, not a string"
21
+ }).regex(EVM_ADDRESS_REGEX, "Invalid value, not an Address");
22
+ const bytes32Schema = z.string({
23
+ invalid_type_error: "Invalid value, not a string"
24
+ }).regex(BYTES32_REGEX, "Invalid value, not 32 bytes hex");
25
+ const bytesSchema = z.string({
26
+ invalid_type_error: "Invalid value, not a string"
27
+ }).regex(BYTES_REGEX, "Invalid value, not hex");
28
+ const verificationSchema = z.discriminatedUnion("method", [
29
+ z.object({
30
+ data: bytes32Schema,
31
+ method: z.enum([
32
+ VERIFICATION_METHODS.HASH_KECCAK256_BYTES,
33
+ VERIFICATION_METHODS.HASH_KECCAK256_UTF8
34
+ ])
35
+ }),
36
+ z.object({
37
+ method: z.enum([VERIFICATION_METHODS.ECDSA]),
38
+ /** Signer address */
39
+ data: addressSchema,
40
+ /** URL where the signature can be retrieved */
41
+ source: z.string().url("Invalid value, not a URL")
42
+ })
43
+ ]);
44
+ const imageSchema = z.object({
45
+ url: z.string({ invalid_type_error: "Invalid value, not a string" }).url("Invalid value, not a URL"),
46
+ width: z.number({ invalid_type_error: "Invalid value, not a number" }),
47
+ height: z.number({ invalid_type_error: "Invalid value, not a number" }),
48
+ verification: verificationSchema
49
+ });
50
+ const assetSchema = z.object({
51
+ url: z.string({ invalid_type_error: "Invalid value, not a string" }).url("Invalid value, not a URL"),
52
+ fileType: z.string({ invalid_type_error: "Invalid value, not a string" }),
53
+ verification: verificationSchema
54
+ });
55
+ const linkSchema = z.object({
56
+ title: z.string({ invalid_type_error: "Invalid value, not a string" }),
57
+ url: z.string({ invalid_type_error: "Invalid value, not a string" }).url("Invalid value, not a URL")
58
+ });
59
+ const tagSchema = z.string({
60
+ invalid_type_error: "Invalid value, not a string"
61
+ });
62
+
63
+ function isImageSchema(obj) {
64
+ const { success } = imageSchema.safeParse(obj);
65
+ return success;
66
+ }
67
+ function isLinkSchema(obj) {
68
+ const { success } = linkSchema.safeParse(obj);
69
+ return success;
70
+ }
71
+ function isTagSchema(obj) {
72
+ const { success } = tagSchema.safeParse(obj);
73
+ return success;
74
+ }
75
+ function isAssetSchema(obj) {
76
+ const { success } = assetSchema.safeParse(obj);
77
+ return success;
78
+ }
79
+
80
+ function findBestImage(images, options) {
81
+ if (!images || images.length === 0) {
82
+ return void 0;
83
+ }
84
+ if (options?.width != null && options?.height != null) {
85
+ return findClosestImage(images, options.width, options.height) ?? void 0;
86
+ }
87
+ return images[0];
88
+ }
89
+ function findClosestImage(images, targetWidth, targetHeight) {
90
+ if (!images || images.length === 0) {
91
+ return null;
92
+ }
93
+ const calculateDistance = (width, height) => {
94
+ return Math.sqrt((width - targetWidth) ** 2 + (height - targetHeight) ** 2);
95
+ };
96
+ let closestImage = null;
97
+ let minDistance = Infinity;
98
+ for (const image of images) {
99
+ const distance = calculateDistance(image.width, image.height);
100
+ if (distance < minDistance) {
101
+ minDistance = distance;
102
+ closestImage = image;
103
+ }
104
+ }
105
+ return closestImage;
106
+ }
107
+
108
+ function encodeVerifiableUri(data, ipfsUrl) {
109
+ const jsonString = JSON.stringify(data);
110
+ const verificationHash = keccak256(stringToHex(jsonString));
111
+ const urlHex = stringToHex(ipfsUrl);
112
+ return concat([
113
+ RESERVED_PREFIX,
114
+ KECCAK256_BYTES_METHOD_ID,
115
+ HASH_LENGTH_PREFIX,
116
+ verificationHash,
117
+ urlHex
118
+ ]);
119
+ }
120
+ function parseVerifiableUri(value) {
121
+ if (value.length < MIN_VERIFIABLE_URI_LENGTH) {
122
+ throw new Error(
123
+ `Invalid VerifiableURI: value too short (${value.length} chars, minimum ${MIN_VERIFIABLE_URI_LENGTH})`
124
+ );
125
+ }
126
+ const reservedPrefix = slice(value, 0, 2);
127
+ if (reservedPrefix !== RESERVED_PREFIX) {
128
+ throw new Error(
129
+ `Invalid VerifiableURI: expected reserved prefix ${RESERVED_PREFIX}, got ${reservedPrefix}`
130
+ );
131
+ }
132
+ const verificationMethod = slice(value, 2, 6);
133
+ const hashLengthHex = slice(value, 6, 8);
134
+ const hashLength = parseInt(hashLengthHex.slice(2), 16);
135
+ const verificationData = slice(value, 8, 8 + hashLength);
136
+ const urlHex = slice(value, 8 + hashLength);
137
+ const url = hexToString(urlHex);
138
+ return {
139
+ verificationMethod,
140
+ verificationData,
141
+ url
142
+ };
143
+ }
144
+ function decodeVerifiableUri(verifiableUriValue, jsonContent, schema) {
145
+ const { verificationMethod, verificationData, url } = parseVerifiableUri(verifiableUriValue);
146
+ if (verificationMethod !== KECCAK256_BYTES_METHOD_ID) {
147
+ throw new Error(
148
+ `Unsupported verification method: ${verificationMethod}. Expected ${KECCAK256_BYTES_METHOD_ID} (keccak256(bytes))`
149
+ );
150
+ }
151
+ const computedHash = keccak256(stringToHex(jsonContent));
152
+ if (computedHash.toLowerCase() !== verificationData.toLowerCase()) {
153
+ throw new Error(
154
+ `VerifiableURI hash mismatch: content hash ${computedHash} does not match verification data ${verificationData}`
155
+ );
156
+ }
157
+ let parsed;
158
+ try {
159
+ parsed = JSON.parse(jsonContent);
160
+ } catch {
161
+ throw new Error("Invalid JSON content");
162
+ }
163
+ if (schema) {
164
+ const result = schema.safeParse(parsed);
165
+ if (!result.success) {
166
+ throw new Error(`Schema validation failed: ${result.error.message}`);
167
+ }
168
+ return { data: result.data, url };
169
+ }
170
+ return { data: parsed, url };
171
+ }
172
+ function computeVerificationHash(data) {
173
+ const jsonString = JSON.stringify(data);
174
+ return keccak256(stringToHex(jsonString));
175
+ }
176
+ function isVerifiableUri(value) {
177
+ if (value.length < MIN_VERIFIABLE_URI_LENGTH) {
178
+ return false;
179
+ }
180
+ try {
181
+ const reservedPrefix = slice(value, 0, 2);
182
+ return reservedPrefix === RESERVED_PREFIX;
183
+ } catch {
184
+ return false;
185
+ }
186
+ }
187
+
188
+ export { HASH_LENGTH_PREFIX, KECCAK256_BYTES_METHOD_ID, MAPPING_SEPARATOR, MIN_VERIFIABLE_URI_LENGTH, RESERVED_PREFIX, VERIFICATION_METHODS, addressSchema, assetSchema, bytes32Schema, bytesSchema, computeVerificationHash, decodeVerifiableUri, encodeVerifiableUri, findBestImage, findClosestImage, imageSchema, isAssetSchema, isImageSchema, isLinkSchema, isTagSchema, isVerifiableUri, linkSchema, parseVerifiableUri, tagSchema, verificationSchema };
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@chillwhales/lsp2",
3
+ "version": "0.1.1",
4
+ "type": "module",
5
+ "description": "LSP2 ERC725Y JSON Schema — shared primitives, VerifiableURI encoding/decoding, and image utilities",
6
+ "author": "b00ste",
7
+ "license": "MIT",
8
+ "types": "./dist/index.d.mts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.mts",
12
+ "default": "./dist/index.mjs"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "LICENSE",
18
+ "README.md"
19
+ ],
20
+ "engines": {
21
+ "node": ">=22"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/chillwhales/LSPs.git",
26
+ "directory": "packages/lsp2"
27
+ },
28
+ "keywords": [
29
+ "chillwhales",
30
+ "lukso",
31
+ "lsp",
32
+ "lsp2",
33
+ "erc725y",
34
+ "verifiable-uri",
35
+ "json-schema"
36
+ ],
37
+ "sideEffects": false,
38
+ "dependencies": {
39
+ "zod": "^3.24.1"
40
+ },
41
+ "peerDependencies": {
42
+ "viem": "^2.0.0"
43
+ },
44
+ "devDependencies": {
45
+ "typescript": "^5.9.3",
46
+ "unbuild": "^3.6.1",
47
+ "viem": "^2.0.0",
48
+ "vitest": "^4.0.17",
49
+ "@chillwhales/config": "0.0.0"
50
+ },
51
+ "scripts": {
52
+ "build": "unbuild",
53
+ "build:watch": "unbuild --watch",
54
+ "clean": "rm -rf dist",
55
+ "test": "vitest run",
56
+ "test:watch": "vitest"
57
+ }
58
+ }