solfaces 1.0.1 → 2.0.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.
Files changed (69) hide show
  1. package/README.md +359 -87
  2. package/dist/agent/index.cjs +14 -14
  3. package/dist/agent/index.js +4 -4
  4. package/dist/agent/mcp-server.cjs +716 -277
  5. package/dist/{chunk-VMNATBH3.cjs → chunk-23XJ5VDX.cjs} +37 -27
  6. package/dist/chunk-23XJ5VDX.cjs.map +1 -0
  7. package/dist/chunk-46ZEFA6R.cjs +243 -0
  8. package/dist/chunk-46ZEFA6R.cjs.map +1 -0
  9. package/dist/{chunk-A6N3RPEA.cjs → chunk-546TBMAR.cjs} +6 -6
  10. package/dist/{chunk-A6N3RPEA.cjs.map → chunk-546TBMAR.cjs.map} +1 -1
  11. package/dist/chunk-6QRDULAO.cjs +191 -0
  12. package/dist/chunk-6QRDULAO.cjs.map +1 -0
  13. package/dist/chunk-6UWILY7E.cjs +647 -0
  14. package/dist/chunk-6UWILY7E.cjs.map +1 -0
  15. package/dist/chunk-DRUSCLEF.js +177 -0
  16. package/dist/chunk-DRUSCLEF.js.map +1 -0
  17. package/dist/chunk-HCEE4K4T.js +625 -0
  18. package/dist/chunk-HCEE4K4T.js.map +1 -0
  19. package/dist/chunk-JS527VKL.js +238 -0
  20. package/dist/chunk-JS527VKL.js.map +1 -0
  21. package/dist/{chunk-SNJABBAT.js → chunk-LRHYF5QN.js} +3 -3
  22. package/dist/{chunk-SNJABBAT.js.map → chunk-LRHYF5QN.js.map} +1 -1
  23. package/dist/{chunk-RX6D5FGH.js → chunk-TTGJZEPV.js} +30 -20
  24. package/dist/chunk-TTGJZEPV.js.map +1 -0
  25. package/dist/core/index.cjs +69 -29
  26. package/dist/core/index.d.cts +29 -47
  27. package/dist/core/index.d.ts +29 -47
  28. package/dist/core/index.js +3 -3
  29. package/dist/index.cjs +75 -35
  30. package/dist/index.d.cts +2 -2
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +5 -5
  33. package/dist/react/index.cjs +431 -397
  34. package/dist/react/index.cjs.map +1 -1
  35. package/dist/react/index.d.cts +3 -2
  36. package/dist/react/index.d.ts +3 -2
  37. package/dist/react/index.js +427 -393
  38. package/dist/react/index.js.map +1 -1
  39. package/dist/solfaces.cdn.global.js +2 -2
  40. package/dist/solfaces.cdn.global.js.map +1 -1
  41. package/dist/themes/index.cjs +29 -17
  42. package/dist/themes/index.d.cts +10 -7
  43. package/dist/themes/index.d.ts +10 -7
  44. package/dist/themes/index.js +1 -1
  45. package/dist/{traits-DAFZnXeS.d.cts → traits-QlWuxZDD.d.cts} +45 -1
  46. package/dist/{traits-DAFZnXeS.d.ts → traits-QlWuxZDD.d.ts} +45 -1
  47. package/dist/vanilla/index.cjs +20 -8
  48. package/dist/vanilla/index.cjs.map +1 -1
  49. package/dist/vanilla/index.d.cts +1 -1
  50. package/dist/vanilla/index.d.ts +1 -1
  51. package/dist/vanilla/index.js +17 -5
  52. package/dist/vanilla/index.js.map +1 -1
  53. package/package.json +1 -2
  54. package/python/solfaces.py +557 -235
  55. package/skill.md +210 -65
  56. package/dist/chunk-2DIKGLXZ.cjs +0 -126
  57. package/dist/chunk-2DIKGLXZ.cjs.map +0 -1
  58. package/dist/chunk-CVFO7YHY.cjs +0 -97
  59. package/dist/chunk-CVFO7YHY.cjs.map +0 -1
  60. package/dist/chunk-H3SK3MNX.cjs +0 -409
  61. package/dist/chunk-H3SK3MNX.cjs.map +0 -1
  62. package/dist/chunk-KSGFMW33.js +0 -401
  63. package/dist/chunk-KSGFMW33.js.map +0 -1
  64. package/dist/chunk-LQWJRHGC.js +0 -86
  65. package/dist/chunk-LQWJRHGC.js.map +0 -1
  66. package/dist/chunk-RX6D5FGH.js.map +0 -1
  67. package/dist/chunk-VMNATBH3.cjs.map +0 -1
  68. package/dist/chunk-WURY4QGH.js +0 -117
  69. package/dist/chunk-WURY4QGH.js.map +0 -1
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # SolFaces
1
+ # SolFaces
2
2
 
3
3
  **Deterministic wallet avatars for the Solana ecosystem.**
4
4
 
@@ -12,10 +12,15 @@ Built for dApps, AI agents, social features, leaderboards, and anywhere a wallet
12
12
 
13
13
  - **Deterministic** — Same wallet always produces the same avatar. No database needed.
14
14
  - **Zero dependencies** — Core engine has no runtime dependencies.
15
- - **~221M unique faces** — 11 traits with multiple variants = massive combination space.
15
+ - **~2.56B unique faces** — 11 traits with expanded ranges = massive combination space.
16
+ - **Gradient-rich rendering** — Skin-luminance-driven colors, specular highlights, cheek blush, gradient hair, glow overlays.
16
17
  - **Works everywhere** — React, vanilla JS, Node, Python, CDN script tag, edge functions.
17
- - **Fully customizable** — Every color, every feature. Themes, per-instance overrides, animation timing — adapt every detail to match your UI, your brand, or your users' preferences.
18
- - **Eliminates dead space** — No more blank avatars or generic placeholders. Every wallet gets a unique face instantly, elevating your dApp or website UI even when users never upload a profile picture.
18
+ - **Pixel art mode** — Retro pixelated rendering with optional scanlines (React).
19
+ - **Liquid glass mode** — Backdrop-blur glass effect with rim lighting (React).
20
+ - **Flat mode** — Disable all gradients for simplified rendering.
21
+ - **Detail levels** — Full detail (gradients, specular, cheeks) at size >= 48, simplified below.
22
+ - **Fully customizable** — Every visual element is customizable: 4 color palettes, 8 individual color overrides, 9 per-instance color keys, rendering toggles, layout controls, blink timing, and 30+ React-only pixel/glass fields. No visual element is locked — if you can see it, you can theme it.
23
+ - **Eliminates dead space** — No more blank avatars or generic placeholders. Every wallet gets a unique face instantly.
19
24
  - **AI-agent ready** — Natural language self-descriptions for agent system prompts.
20
25
  - **PNG rasterization** — Serve real image files for bots, Discord, Telegram, OG images.
21
26
  - **SSR-ready** — String renderer works server-side with zero browser APIs.
@@ -57,6 +62,25 @@ function UserProfile({ walletAddress }) {
57
62
  }
58
63
  ```
59
64
 
65
+ ### Pixel Art Mode (React)
66
+
67
+ ```tsx
68
+ import { SolFace } from "solfaces/react";
69
+ import { pixelTheme, pixelRetroTheme } from "solfaces/themes";
70
+
71
+ <SolFace walletAddress="7xKXqR..." size={64} theme={pixelTheme} />
72
+ <SolFace walletAddress="7xKXqR..." size={64} theme={pixelRetroTheme} />
73
+ ```
74
+
75
+ ### Liquid Glass Mode (React)
76
+
77
+ ```tsx
78
+ import { SolFace } from "solfaces/react";
79
+ import { glassTheme, glassDarkTheme } from "solfaces/themes";
80
+
81
+ <SolFace walletAddress="7xKXqR..." size={64} theme={glassTheme} />
82
+ ```
83
+
60
84
  ### Vanilla JS (npm)
61
85
 
62
86
  ```js
@@ -69,6 +93,8 @@ mountSolFace("#avatar", "7xKXqR...", { size: 48 });
69
93
 
70
94
  ```html
71
95
  <div data-solface="7xKXqR..." data-solface-size="48" data-solface-theme="dark"></div>
96
+ <div data-solface="DRpbCBMx..." data-solface-flat="true"></div>
97
+ <div data-solface="9WzDXwBb..." data-solface-detail="full"></div>
72
98
 
73
99
  <script src="https://unpkg.com/solfaces/dist/solfaces.cdn.global.js"></script>
74
100
  <!-- Auto-initializes on DOMContentLoaded -->
@@ -101,6 +127,65 @@ desc = describe_appearance("7xKXqR...")
101
127
 
102
128
  ---
103
129
 
130
+ ## Rendering Modes
131
+
132
+ ### Full Detail vs Simplified
133
+
134
+ SolFaces automatically adjusts detail based on size:
135
+
136
+ - **Full detail** (size >= 48): Gradient fills, specular highlights on eyes, cheek blush, chin shadow, face glow, eyelid strokes, jawline hints.
137
+ - **Simplified** (size < 48): Flat shapes optimized for small sizes — no gradients, no cheeks, no specular.
138
+
139
+ Override with the `detail` option:
140
+
141
+ ```ts
142
+ renderSolFaceSVG("7xKXqR...", { detail: "full" }); // Force full detail at any size
143
+ renderSolFaceSVG("7xKXqR...", { detail: "simplified" }); // Force simplified
144
+ renderSolFaceSVG("7xKXqR...", { detail: "auto" }); // Default — based on size
145
+ ```
146
+
147
+ ### Flat Mode
148
+
149
+ Disable all gradients globally. Useful for print, email clients, or minimal UIs:
150
+
151
+ ```ts
152
+ import { flatTheme } from "solfaces/themes";
153
+
154
+ renderSolFaceSVG("7xKXqR...", { theme: flatTheme });
155
+ // Zero <linearGradient> or <radialGradient> elements in output
156
+ ```
157
+
158
+ Or set `flat: true` on any theme:
159
+
160
+ ```ts
161
+ renderSolFaceSVG("7xKXqR...", { theme: { flat: true } });
162
+ ```
163
+
164
+ ### Pixel Art Mode (React Only)
165
+
166
+ Renders the SVG at a low pixel density then scales up with `image-rendering: pixelated`:
167
+
168
+ ```tsx
169
+ import { pixelTheme, pixelRetroTheme, pixelCleanTheme } from "solfaces/themes";
170
+
171
+ <SolFace walletAddress="7xKXqR..." theme={pixelTheme} /> // 16px density, rounded
172
+ <SolFace walletAddress="7xKXqR..." theme={pixelRetroTheme} /> // 12px + scanlines + shadow
173
+ <SolFace walletAddress="7xKXqR..." theme={pixelCleanTheme} /> // 24px, clean
174
+ ```
175
+
176
+ ### Liquid Glass Mode (React Only)
177
+
178
+ Backdrop-blur glass effect with specular highlights and rim lighting:
179
+
180
+ ```tsx
181
+ import { glassTheme, glassDarkTheme } from "solfaces/themes";
182
+
183
+ <SolFace walletAddress="7xKXqR..." theme={glassTheme} />
184
+ <SolFace walletAddress="7xKXqR..." theme={glassDarkTheme} />
185
+ ```
186
+
187
+ ---
188
+
104
189
  ## AI Agent Identity
105
190
 
106
191
  SolFaces gives AI agents a visual identity tied to their wallet. The `describeAppearance()` function generates natural language descriptions agents can use in system prompts to know and reference what they look like.
@@ -112,11 +197,11 @@ import { agentAppearancePrompt } from "solfaces";
112
197
 
113
198
  const appearance = agentAppearancePrompt("7xKXqR...", "Atlas");
114
199
  // → "My visual identity is a SolFace avatar (ID: a3f2b1c0) derived from
115
- // my wallet address. I'm Atlas. I have a round face with light peach skin,
116
- // wide and expressive blue eyes with elegantly arched eyebrows, and tall,
117
- // spiky Solana mint green hair. I'm wearing round glasses. I have a
118
- // confident smirk. This appearance is deterministic — anyone who looks up
119
- // my wallet will see the same face."
200
+ // my wallet address. I'm Atlas. I have a squircle face with warm golden skin,
201
+ // almond-shaped hazel eyes with gently curved eyebrows, and flowing
202
+ // auburn wavy hair. I'm wearing aviator sunglasses. I have a playful grin.
203
+ // This appearance is deterministic — anyone who looks up my wallet will
204
+ // see the same face."
120
205
 
121
206
  const systemPrompt = `You are Atlas, a DeFi trading agent. ${appearance}`;
122
207
  ```
@@ -134,11 +219,11 @@ describeAppearance("7xKXqR...", { format: "paragraph", perspective: "first", nam
134
219
 
135
220
  // Structured (for data display)
136
221
  describeAppearance("7xKXqR...", { format: "structured" });
137
- // → "Face: round\nSkin: light peach\nEyes: wide and expressive, blue\n..."
222
+ // → "Face: squircle\nSkin: warm golden\nEyes: almond-shaped, hazel\n..."
138
223
 
139
224
  // Compact (for alt text, captions)
140
225
  describeAppearance("7xKXqR...", { format: "compact" });
141
- // → "round face, light peach skin, blue wide eyes, spiky mint hair, round glasses, smirking"
226
+ // → "squircle face, warm golden skin, hazel almond eyes, wavy auburn hair, aviator sunglasses, grinning"
142
227
  ```
143
228
 
144
229
  ### Alt Text & Accessibility
@@ -147,7 +232,7 @@ describeAppearance("7xKXqR...", { format: "compact" });
147
232
  import { solFaceAltText } from "solfaces";
148
233
 
149
234
  const alt = solFaceAltText("7xKXqR...");
150
- // → "SolFace avatar: round face, light peach skin, blue wide eyes, ..."
235
+ // → "SolFace avatar: squircle face, warm golden skin, hazel almond eyes, ..."
151
236
  ```
152
237
 
153
238
  ### Python (AI Agent Backends)
@@ -206,36 +291,69 @@ const dataUrl = await renderSolFacePNGDataURL("7xKXqR...", { pngSize: 256 });
206
291
 
207
292
  ## Themes
208
293
 
209
- SolFaces is fully customizable to your UI. Every visual element — skin, eyes, hair, mouth, eyebrows, nose, accessories, background, border, and even eye white/teeth color — can be themed globally or overridden per instance. Use a preset, extend one, or build your own from scratch. You can also use `colorOverrides` to change individual colors on a specific avatar without affecting the theme.
294
+ SolFaces ships with 11 preset themes. Themes control colors, gradients, borders, rendering modes, and more.
210
295
 
211
296
  ### Available Presets
212
297
 
213
- | Theme | Description |
214
- |-------|-------------|
215
- | `solanaTheme` | Defaultvibrant Solana colors (#14F195, #9945FF) |
216
- | `darkTheme` | Muted tones on dark backgrounds |
217
- | `lightTheme` | Soft pastels for white/light UIs |
218
- | `monoTheme` | Grayscale onlyminimal interfaces |
219
- | `neonTheme` | High-contrast cyberpunk vibes |
220
- | `jupiterTheme` | Matches Jupiter aggregator's palette |
221
- | `phantomTheme` | Phantom wallet's purple style |
222
- | `circleTheme` | Full border-radius for circular avatars |
298
+ | Theme | Description | Works In |
299
+ |-------|-------------|----------|
300
+ | `default` | Base look with gradient-rich rendering no overrides | All renderers |
301
+ | `dark` | Dark backgrounds with muted tones and subtle border | All renderers |
302
+ | `light` | Soft pastel backgrounds with rounded corners | All renderers |
303
+ | `mono` | Full grayscaleall colors replaced with grays | All renderers |
304
+ | `flat` | Disables all gradients — flat fill colors only | All renderers |
305
+ | `transparent` | Transparent background with flat rendering | All renderers |
306
+ | `glass` | Liquid glass effect with backdrop blur and specular highlights | React only |
307
+ | `glassDark` | Dark variant of liquid glass with deeper blur | React only |
308
+ | `pixel` | Pixel art mode at 16px density with rounded corners | React only |
309
+ | `pixelRetro` | Retro pixel art with scanlines and drop shadow | React only |
310
+ | `pixelClean` | Clean pixel art at 24px density | React only |
311
+
312
+ ### Using Themes
313
+
314
+ ```ts
315
+ import { renderSolFaceSVG } from "solfaces";
316
+ import { darkTheme } from "solfaces/themes";
317
+
318
+ const svg = renderSolFaceSVG("7xKXqR...", { theme: darkTheme });
319
+ ```
223
320
 
224
321
  ### Custom Themes
225
322
 
323
+ Every visual element is customizable through the theme system — color palettes, individual colors, rendering toggles, layout, and more. All fields are optional; only override what you need.
324
+
226
325
  ```ts
326
+ import type { SolFaceTheme } from "solfaces";
327
+
227
328
  const myTheme: SolFaceTheme = {
228
- skinColors: ["#ffd5b0", "#f4c794", "#e0a370", "#c68642", "#8d5524", "#4a2c17"],
229
- eyeColors: ["#333", "#4a80c4", "#5a9a5a"],
230
- hairColors: ["#1a1a1a", "#6b3a2a", "#d4a844", "#ff6b6b", "#4ecdc4", "#45b7d1"],
231
- bgColors: ["#1a1b23", "#2d1b69", "#0a2463"],
329
+ // Color palettes (arrays one color per trait variant)
330
+ skinColors: ["#fce4d4", "#f5d0b0", "#e8b88a", "#d4956a", "#b5724a", "#8d5524", "#6b3f1d", "#4a2c17", "#3a1f10", "#2a1008"],
331
+ eyeColors: ["#333", "#4a80c4", "#5a9a5a", "#c89430", "#8a8a8a"],
332
+ hairColors: ["#1a1a1a", "#4a3728", "#8b6b4a", "#c44a20", "#d4a844", "#6090e0", "#14F195", "#e040c0", "#ff6b6b", "#4ecdc4"],
333
+ bgColors: ["#14F195", "#4a90e2", "#9945FF", "#f0e68c", "#e06070", "#ff8c42", "#5bc0be", "#8338ec", "#ff006e", "#3a86ff"],
334
+
335
+ // Individual color overrides
232
336
  mouthColor: "#e06070",
233
337
  eyebrowColor: "#aaa",
234
- accessoryColor: "#888",
235
- eyeWhiteColor: "#e0e0e0", // Sclera color (great for dark themes)
236
- noseColor: "#c68642aa", // Nose color (defaults to skin + transparency)
338
+ accessoryColor: "#888", // Default glasses/earring/headband color
339
+ eyeWhiteColor: "#e0e0e0", // Sclera + teeth color (important for dark themes)
340
+ noseColor: "#c68642aa", // Nose color (defaults to skin-derived)
341
+ glassesColor: "#333", // Glasses frame color (overrides accessoryColor)
342
+ earringColor: "#ffd700", // Earring color (overrides accessoryColor)
343
+ headbandColor: "#e04080", // Headband color (overrides accessoryColor)
344
+
345
+ // Rendering control
346
+ flat: false, // Set true to disable all gradients
347
+ cheekEnabled: true, // Enable/disable cheek blush
348
+ cheekColor: "#ff8080", // Custom cheek color
349
+ cheekOpacity: 0.3, // Cheek blush opacity
350
+ skinOpacity: 1, // Skin fill opacity
351
+ shadowEnabled: true, // Enable/disable chin shadow
352
+ glowIntensity: 0.15, // Face glow strength
353
+
354
+ // Layout
237
355
  bgOpacity: 1,
238
- bgRadius: 999,
356
+ bgRadius: 14,
239
357
  border: { color: "#14F195", width: 2 },
240
358
  };
241
359
  ```
@@ -248,25 +366,98 @@ import { getPresetTheme } from "solfaces/themes";
248
366
  const myTheme = getPresetTheme("dark", {
249
367
  bgRadius: 999,
250
368
  border: { color: "#14F195", width: 1 },
369
+ eyeWhiteColor: "#d0c8c0", // Warmer eye whites for dark mode
251
370
  });
252
371
  ```
253
372
 
254
- ### Per-Instance Color Overrides
255
-
256
- Override any color on a specific avatar without changing the global theme:
257
-
258
- ```tsx
259
- // React
260
- <SolFace walletAddress="7xKXqR..." colorOverrides={{ hair: "#ff0000", bg: "#000" }} />
261
-
262
- // String renderer
263
- renderSolFaceSVG("7xKXqR...", {
264
- theme: darkTheme,
265
- colorOverrides: { skin: "#ffd5b0", eyes: "#00ff00", accessory: "#gold" },
266
- });
267
- ```
268
-
269
- Available override keys: `skin`, `eyes`, `hair`, `bg`, `mouth`, `eyebrow`, `accessory`, `nose`, `eyeWhite`.
373
+ ### Theme Field Reference
374
+
375
+ **Color palettes** (arrays one per trait variant):
376
+
377
+ | Field | Type | What it controls |
378
+ |-------|------|-----------------|
379
+ | `skinColors` | `string[]` | 10 skin tone colors |
380
+ | `eyeColors` | `string[]` | 5 iris/pupil colors |
381
+ | `hairColors` | `string[]` | 10 hair fill colors |
382
+ | `bgColors` | `string[]` | 10 background fill colors |
383
+
384
+ **Individual color overrides:**
385
+
386
+ | Field | Type | What it controls |
387
+ |-------|------|-----------------|
388
+ | `mouthColor` | `string` | Mouth stroke/fill |
389
+ | `eyebrowColor` | `string` | Eyebrow stroke |
390
+ | `accessoryColor` | `string` | Default accessory color (glasses, earring, headband) |
391
+ | `eyeWhiteColor` | `string` | Sclera (eye white) and teeth color — set for dark themes |
392
+ | `noseColor` | `string` | Nose color (defaults to skin-derived + transparency) |
393
+ | `glassesColor` | `string` | Glasses frame color (overrides accessoryColor) |
394
+ | `earringColor` | `string` | Earring color (overrides accessoryColor) |
395
+ | `headbandColor` | `string` | Headband color (overrides accessoryColor) |
396
+
397
+ **Rendering control:**
398
+
399
+ | Field | Type | What it controls |
400
+ |-------|------|-----------------|
401
+ | `flat` | `boolean` | Disable all gradients (flat fill colors only) |
402
+ | `cheekEnabled` | `boolean` | Enable/disable cheek blush |
403
+ | `cheekColor` | `string` | Custom cheek color |
404
+ | `cheekOpacity` | `number` | Cheek blush opacity (0-1) |
405
+ | `skinOpacity` | `number` | Skin fill opacity (0-1) |
406
+ | `shadowEnabled` | `boolean` | Enable/disable chin shadow and face overlays |
407
+
408
+ **Layout:**
409
+
410
+ | Field | Type | What it controls |
411
+ |-------|------|-----------------|
412
+ | `bgOpacity` | `number` | Background opacity (0-1) |
413
+ | `bgRadius` | `number` | SVG rect border radius (999 = circle) |
414
+ | `border` | `{ color, width }` | Optional border around avatar |
415
+
416
+ ### Pixel Art Customization (React Only)
417
+
418
+ All `_pixel*` fields are React-only. Set `_pixel: true` to enable pixel art mode.
419
+
420
+ | Field | Type | Default | What it controls |
421
+ |-------|------|---------|-----------------|
422
+ | `_pixel` | `boolean` | `false` | Enable pixel art mode |
423
+ | `_pixelDensity` | `number` | `16` | Render resolution before upscale (lower = blockier) |
424
+ | `_pixelRounded` | `boolean` | `true` | Rounded corners on pixel container |
425
+ | `_pixelOutline` | `boolean` | `false` | Draw outline around pixel art |
426
+ | `_pixelOutlineColor` | `string` | `"#000"` | Outline color |
427
+ | `_pixelOutlineWidth` | `number` | `1` | Outline width in pixels |
428
+ | `_pixelContrast` | `number` | — | CSS contrast filter |
429
+ | `_pixelSaturation` | `number` | — | CSS saturation filter |
430
+ | `_pixelBrightness` | `number` | — | CSS brightness filter |
431
+ | `_pixelScanlines` | `boolean` | `false` | Horizontal scanline overlay |
432
+ | `_pixelScanlineOpacity` | `number` | `0.08` | Scanline opacity |
433
+ | `_pixelScanlineSpacing` | `number` | `2` | Scanline spacing in pixels |
434
+ | `_pixelGrid` | `boolean` | `false` | Pixel grid overlay |
435
+ | `_pixelGridOpacity` | `number` | — | Grid opacity |
436
+ | `_pixelGridColor` | `string` | — | Grid color |
437
+ | `_pixelShadow` | `boolean` | `false` | Drop shadow behind pixel art |
438
+ | `_pixelShadowColor` | `string` | `"rgba(0,0,0,0.3)"` | Shadow color |
439
+ | `_pixelShadowOffset` | `number` | `2` | Shadow offset in pixels |
440
+
441
+ ### Liquid Glass Customization (React Only)
442
+
443
+ All glass fields are React-only. Set `_glass: true` to enable liquid glass mode.
444
+
445
+ | Field | Type | Default | What it controls |
446
+ |-------|------|---------|-----------------|
447
+ | `_glass` | `boolean` | `false` | Enable liquid glass mode |
448
+ | `_blurRadius` | `number` | `12` | Backdrop blur radius |
449
+ | `_saturate` | `number` | `1.8` | Backdrop saturation multiplier |
450
+ | `_tintColor` | `string` | `"rgba(255,255,255,1)"` | Glass tint color |
451
+ | `_tintOpacity` | `number` | `0.12` | Glass tint opacity |
452
+ | `_borderColor` | `string` | `"rgba(255,255,255,0.25)"` | Glass border color |
453
+ | `_borderWidth` | `number` | `1` | Glass border width |
454
+ | `_borderOpacity` | `number` | `0.25` | Glass border opacity |
455
+ | `_specularColor` | `string` | `"rgba(255,255,255,1)"` | Specular highlight color |
456
+ | `_specularOpacity` | `number` | `0.25` | Specular highlight strength |
457
+ | `_specularEnd` | `number` | `50` | Specular gradient end (%) |
458
+ | `_lightAngle` | `number` | `135` | Light source angle (degrees) |
459
+ | `_rimIntensity` | `number` | `0.08` | Rim lighting intensity |
460
+ | `_shadow` | `string` | `"0 8px 32px rgba(0,0,0,0.12)"` | CSS box-shadow |
270
461
 
271
462
  ---
272
463
 
@@ -327,14 +518,7 @@ import {
327
518
 
328
519
  ### Skill File for AI Agents
329
520
 
330
- SolFaces includes a comprehensive `skill.md` that teaches AI agents how to integrate, customize, and use SolFaces. Feed it to any agent (Claude, GPT, custom bots) as context:
331
-
332
- - How to install and import for any platform
333
- - React component usage with themes, animations, and styling
334
- - Server-side rendering and API route patterns
335
- - Custom theme creation to match any UI
336
- - Bot integration (Discord, Telegram)
337
- - All 5 tool definitions with parameters and usage guidance
521
+ SolFaces includes a comprehensive `skill.md` that teaches AI agents how to integrate, customize, and use SolFaces. Feed it to any agent (Claude, GPT, custom bots) as context.
338
522
 
339
523
  ---
340
524
 
@@ -356,7 +540,7 @@ Templates included for: **Next.js App Router**, **Express**, **Hono (Cloudflare
356
540
 
357
541
  ## Python Port
358
542
 
359
- Full Python implementation with identical trait generation to JavaScript. Zero dependencies.
543
+ Full Python implementation with identical trait generation to JavaScript. Zero dependencies. Includes gradient-rich rendering matching the TypeScript renderer.
360
544
 
361
545
  ```python
362
546
  from solfaces import generate_traits, render_svg, describe_appearance
@@ -375,8 +559,11 @@ python solfaces.py 7xKXqR... --svg # Output SVG
375
559
  python solfaces.py 7xKXqR... --json # Output JSON
376
560
  python solfaces.py 7xKXqR... --describe # Natural language
377
561
  python solfaces.py 7xKXqR... --svg --size 512 # Custom size
562
+ python solfaces.py 7xKXqR... --svg --flat # Flat mode (no gradients)
378
563
  ```
379
564
 
565
+ > **Note:** Pixel art and liquid glass modes are React-only (CSS-dependent) and not available in the Python port.
566
+
380
567
  ---
381
568
 
382
569
  ## CDN / Script Tag
@@ -390,6 +577,8 @@ For sites without a build step — Webflow, Notion embeds, plain HTML, WordPress
390
577
  <div data-solface="7xKXqR..." data-solface-size="48"></div>
391
578
  <div data-solface="DRpbCBMx..." data-solface-size="48" data-solface-theme="dark"></div>
392
579
  <div data-solface="9WzDXwBb..." data-solface-blink="true"></div>
580
+ <div data-solface="Abc123..." data-solface-flat="true"></div>
581
+ <div data-solface="Def456..." data-solface-detail="full"></div>
393
582
 
394
583
  <!-- Global API available as window.SolFaces -->
395
584
  <script>
@@ -408,22 +597,30 @@ For sites without a build step — Webflow, Notion embeds, plain HTML, WordPress
408
597
  | Function | Returns | Description |
409
598
  |----------|---------|-------------|
410
599
  | `generateTraits(wallet, overrides?)` | `SolFaceTraits` | Deterministic traits from wallet |
600
+ | `getTraitLabels(traits)` | `Record<string, string>` | Human-readable trait names |
601
+ | `traitHash(wallet)` | `string` | 8-char hex hash |
602
+ | `resolveTheme(name?, themes?)` | `SolFaceTheme \| undefined` | Look up theme by name from a map |
603
+ | `mergeTheme(base, overrides)` | `SolFaceTheme` | Merge two themes |
604
+ | `effectiveAccessory(traits)` | `number` | Accessory index (earring suppressed for long/bob hair) |
411
605
  | `renderSolFaceSVG(wallet, options?)` | `string` | Raw SVG markup |
412
606
  | `renderSolFaceDataURI(wallet, options?)` | `string` | Data URI for `<img>` tags |
413
607
  | `renderSolFaceBase64(wallet, options?)` | `string` | Base64 data URI |
414
608
  | `renderSolFacePNG(wallet, options?)` | `Promise<Buffer>` | PNG buffer (Node) |
415
609
  | `renderSolFacePNGBrowser(wallet, options?)` | `Promise<Blob>` | PNG blob (browser) |
610
+ | `renderSolFacePNGDataURL(wallet, options?)` | `Promise<string>` | PNG data URL (browser) |
416
611
  | `describeAppearance(wallet, options?)` | `string` | Natural language description |
612
+ | `describeTraits(traits, options?)` | `string` | Describe from pre-generated traits |
417
613
  | `agentAppearancePrompt(wallet, name?)` | `string` | System prompt for AI agents |
418
614
  | `solFaceAltText(wallet)` | `string` | Accessible alt text |
419
- | `getTraitLabels(traits)` | `Record<string, string>` | Human-readable trait names |
420
- | `traitHash(wallet)` | `string` | 8-char hex hash |
615
+ | `hexToRgb(hex)` | `[r, g, b]` | Parse hex color |
616
+ | `rgbToHex(r, g, b)` | `string` | Convert RGB to hex |
617
+ | `darken(hex, pct)` | `string` | Darken a color |
618
+ | `lighten(hex, pct)` | `string` | Lighten a color |
619
+ | `blend(a, b, t)` | `string` | Blend two colors |
620
+ | `luminance(hex)` | `number` | Perceived luminance (0-255) |
621
+ | `deriveSkinColors(skinHex)` | `DerivedColors` | Full skin-luminance color derivation |
421
622
  | `SOLFACE_TOOLS` | `SolFaceTool[]` | All 5 agent tool definitions |
422
- | `handleToolCall(name, params)` | `Promise<unknown>` | Universal agent tool dispatcher |
423
- | `allToolsOpenAI()` | `OpenAITool[]` | Tools in OpenAI format |
424
- | `allToolsAnthropic()` | `AnthropicTool[]` | Tools in Anthropic format |
425
- | `allToolsVercelAI()` | `Record<string, VercelAITool>` | Tools in Vercel AI SDK format |
426
- | `allToolsMCP()` | `MCPTool[]` | Tools in MCP format |
623
+ | `handleToolCall(name, params)` | `unknown` | Universal agent tool dispatcher |
427
624
 
428
625
  ### React Component Props
429
626
 
@@ -431,25 +628,76 @@ For sites without a build step — Webflow, Notion embeds, plain HTML, WordPress
431
628
  <SolFace
432
629
  walletAddress="7xKXqR..." // Required
433
630
  size={48} // Default: 64
434
- enableBlink={true} // Default: false — or { duration: 2, delay: 0.5 }
631
+ enableBlink={true} // Default: false — or custom timing below
435
632
  theme={darkTheme} // Optional theme
633
+ detail="full" // "full" | "simplified" | "auto"
436
634
  traitOverrides={{ hairStyle: 0 }} // Pin specific traits
437
635
  colorOverrides={{ hair: "#ff0000" }} // Override individual colors
438
636
  className="my-avatar" // CSS class
439
637
  style={{ borderRadius: "50%" }} // Inline styles
440
- onClick={handleClick} // All SVG props supported
638
+ onClick={handleClick} // All standard SVG element props supported
441
639
  />
640
+
641
+ // Custom blink timing
642
+ <SolFace
643
+ walletAddress="7xKXqR..."
644
+ enableBlink={{ duration: 3, delay: 1 }} // 3s cycle, 1s initial delay
645
+ />
646
+ ```
647
+
648
+ ### RenderOptions
649
+
650
+ ```ts
651
+ interface RenderOptions {
652
+ size?: number; // Default: 64
653
+ theme?: SolFaceTheme; // Theme object
654
+ enableBlink?: boolean | { // Blink animation (boolean or custom timing)
655
+ duration?: number; // Blink cycle duration in seconds (default: 4)
656
+ delay?: number; // Initial delay in seconds (default: 0)
657
+ };
658
+ detail?: "full" | "simplified" | "auto"; // Detail level (default: "auto")
659
+ traitOverrides?: Partial<SolFaceTraits>; // Pin specific traits
660
+ className?: string; // CSS class on SVG element
661
+ colorOverrides?: { // Override individual colors per instance
662
+ skin?: string;
663
+ eyes?: string;
664
+ hair?: string;
665
+ bg?: string;
666
+ mouth?: string;
667
+ eyebrow?: string;
668
+ accessory?: string;
669
+ nose?: string;
670
+ eyeWhite?: string;
671
+ };
672
+ }
673
+ ```
674
+
675
+ ### Per-Instance Color Overrides
676
+
677
+ Override any color on a specific avatar without changing the global theme:
678
+
679
+ ```tsx
680
+ // React
681
+ <SolFace walletAddress="7xKXqR..." colorOverrides={{ hair: "#ff0000", bg: "#000" }} />
682
+
683
+ // String renderer
684
+ renderSolFaceSVG("7xKXqR...", {
685
+ theme: darkTheme,
686
+ colorOverrides: { skin: "#ffd5b0", eyes: "#00ff00" },
687
+ });
442
688
  ```
443
689
 
690
+ Available keys: `skin`, `eyes`, `hair`, `bg`, `mouth`, `eyebrow`, `accessory`, `nose`, `eyeWhite`.
691
+
444
692
  ### Import Paths
445
693
 
446
694
  | Path | Contents | React? |
447
695
  |------|----------|--------|
448
- | `solfaces` | Core + themes + describe + rasterize + agent tools | No |
449
- | `solfaces/core` | Engine only | No |
450
- | `solfaces/react` | React component | Yes |
451
- | `solfaces/vanilla` | DOM helpers | No |
452
- | `solfaces/themes` | Preset themes | No |
696
+ | `solfaces` | Core + colors + themes + describe + rasterize + agent tools | No |
697
+ | `solfaces/core` | Engine only (traits, renderer, colors, describe) | No |
698
+ | `solfaces/react` | React component (base + pixel + glass modes) | Yes |
699
+ | `solfaces/vanilla` | DOM helpers (mount, setImg, autoInit) | No |
700
+ | `solfaces/themes` | 11 preset themes | No |
453
701
  | `solfaces/agent` | AI agent tool definitions + framework adapters | No |
454
702
  | `solfaces/cdn` | IIFE for `<script>` tags | No |
455
703
 
@@ -459,22 +707,26 @@ For sites without a build step — Webflow, Notion embeds, plain HTML, WordPress
459
707
 
460
708
  | Trait | Variants | Options |
461
709
  |-------|----------|---------|
462
- | Face Shape | 4 | Round, Square, Oval, Hexagon |
463
- | Skin Color | 6 | Light Dark (6 tones) |
464
- | Eye Style | 8 | Round, Dots, Almond, Wide, Sleepy, Winking, Lashes, Narrow |
465
- | Eye Color | 5 | Dark Brown, Blue, Green, Amber, Gray |
466
- | Eyebrows | 5 | None, Thin, Thick, Arched, Angled |
467
- | Nose | 4 | None, Dot, Triangle, Button |
468
- | Mouth | 6 | Smile, Neutral, Grin, Open, Smirk, Wide Smile |
469
- | Hair Style | 8 | Bald, Short, Spiky, Swept, Mohawk, Long, Bob, Buzz |
470
- | Hair Color | 8 | Black, Brown, Blonde, Ginger, Neon Lime, Neon Blue, Solana Mint, Neon Magenta |
471
- | Accessory | 6 | None (×2), Round Glasses, Square Glasses, Earring, Bandana |
472
- | Background | 5 | Lime, Blue, Solana Mint, Sand, Red |
473
-
474
- **Total unique combinations: ~221,184,000**
710
+ | Face Shape | 4 | Squircle (all preserved for PRNG ordering) |
711
+ | Skin Color | 10 | Porcelain, Ivory, Fair, Light, Sand, Golden, Warm, Caramel, Brown, Deep |
712
+ | Eye Style | 8 | Round, Minimal, Almond, Wide, Relaxed, Joyful, Bright, Gentle |
713
+ | Eye Color | 5 | Chocolate, Sky, Emerald, Hazel, Storm |
714
+ | Eyebrows | 5 | Wispy, Straight, Natural, Arched, Angled |
715
+ | Nose | 4 | Shadow, Button, Soft, Nostrils |
716
+ | Mouth | 8 | Smile, Calm, Happy, Oh, Smirk, Grin, Flat, Pout |
717
+ | Hair Style | 10 | Bald, Short, Curly, Side Sweep, Puff, Long, Bob, Buzz, Wavy, Topknot |
718
+ | Hair Color | 10 | Black, Espresso, Walnut, Honey, Copper, Silver, Charcoal, Burgundy, Strawberry, Ginger |
719
+ | Accessory | 10 | None, Beauty Mark, Round Glasses, Rect Glasses, Earring, Headband, Freckles, Stud Earrings, Aviators, Band-Aid |
720
+ | Background | 10 | Rose, Olive, Sage, Fern, Mint, Ocean, Sky, Lavender, Orchid, Blush |
721
+
722
+ **Total unique combinations: ~2,560,000,000**
475
723
 
476
724
  Algorithm: **djb2 hash** → **mulberry32 PRNG** → sequential trait sampling. Sub-millisecond. Deterministic across JS and Python.
477
725
 
726
+ ### Color Derivation
727
+
728
+ v2 introduces skin-luminance-driven color derivation. Every face's shadow colors, highlights, cheek blush, lip color, nose shading, ear colors, brow colors, and eye white adaptation are automatically computed from the skin tone's luminance. This creates cohesive, natural-looking faces without manual palette tuning.
729
+
478
730
  ---
479
731
 
480
732
  ## Architecture
@@ -483,18 +735,19 @@ Algorithm: **djb2 hash** → **mulberry32 PRNG** → sequential trait sampling.
483
735
  solfaces/
484
736
  ├── src/
485
737
  │ ├── core/
738
+ │ │ ├── colors.ts # Color math: darken, lighten, blend, deriveSkinColors
486
739
  │ │ ├── traits.ts # Types, palettes, theme system, trait generation
487
- │ │ ├── renderer.ts # SVG string renderer, data URI, base64
740
+ │ │ ├── renderer.ts # SVG string renderer (gradient-rich, detail levels)
488
741
  │ │ ├── describe.ts # Natural language descriptions for AI agents
489
742
  │ │ ├── rasterize.ts # PNG output (sharp / resvg / canvas)
490
743
  │ │ └── index.ts
491
744
  │ ├── react/
492
- │ │ ├── SolFace.tsx # React component
745
+ │ │ ├── SolFace.tsx # React component (base + pixel art + liquid glass)
493
746
  │ │ └── index.ts
494
747
  │ ├── vanilla/
495
748
  │ │ └── index.ts # mountSolFace, setSolFaceImg, autoInit
496
749
  │ ├── themes/
497
- │ │ ├── presets.ts # 8 preset themes
750
+ │ │ ├── presets.ts # 11 preset themes
498
751
  │ │ └── index.ts
499
752
  │ ├── agent/
500
753
  │ │ ├── tools.ts # 5 canonical tool definitions + handlers
@@ -504,11 +757,30 @@ solfaces/
504
757
  │ ├── api-templates.ts # Copy-paste route handlers
505
758
  │ └── index.ts
506
759
  ├── python/
507
- │ └── solfaces.py # Full Python port (zero deps)
760
+ │ └── solfaces.py # Full Python port (zero deps, gradient rendering)
508
761
  ├── package.json
509
762
  └── tsup.config.ts
510
763
  ```
511
764
 
765
+ ### Key Design Decisions
766
+
767
+ - **`colors.ts` is the single source of truth** for all color math. Both `renderer.ts` and `SolFace.tsx` import from it, preventing renderer drift.
768
+ - **`effectiveAccessory()`** handles earring suppression: long and bob hairstyles suppress earring accessories.
769
+ - **`_` prefix** on theme fields marks React-only features (pixel, glass). The string renderer ignores these.
770
+ - **Detail levels** are resolved at render time: `"auto"` → full if size >= 48, simplified otherwise.
771
+
772
+ ---
773
+
774
+ ## Migration from v1
775
+
776
+ v2.0.0 is a breaking release:
777
+
778
+ - **All faces change.** Trait ranges expanded (skin 6→10, mouth 6→8, hair 8→10, accessories 6→10, bg 5→10), so every wallet generates a different face than in v1.
779
+ - **Old themes removed.** `solana`, `neon`, `jupiter`, `phantom`, `circle` themes are gone. Use `dark`, `light`, `mono`, `flat`, `transparent`, or the new `glass`/`pixel` themes.
780
+ - **New rendering engine.** Gradient-rich rendering with skin-luminance-driven colors, ears, hair-back layers, and face overlays.
781
+ - **New theme fields.** `flat`, `cheekEnabled`, `shadowEnabled`, `glowIntensity`, and React-only `_glass*`/`_pixel*` fields.
782
+ - **`colorOverrides` still supported.** Per-instance color overrides work the same as v1.
783
+
512
784
  ---
513
785
 
514
786
  ## License