solfaces 1.0.2 → 2.1.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/README.md +489 -97
- package/SKILL.md +171 -0
- package/dist/agent/index.cjs +15 -14
- package/dist/agent/index.js +5 -4
- package/dist/agent/mcp-server.cjs +2956 -287
- package/dist/chunk-6QRDULAO.cjs +191 -0
- package/dist/chunk-6QRDULAO.cjs.map +1 -0
- package/dist/{chunk-RX6D5FGH.js → chunk-77SPWQU5.js} +69 -28
- package/dist/chunk-77SPWQU5.js.map +1 -0
- package/dist/chunk-CQWXUU7P.js +239 -0
- package/dist/chunk-CQWXUU7P.js.map +1 -0
- package/dist/chunk-CXRVPOTI.cjs +244 -0
- package/dist/chunk-CXRVPOTI.cjs.map +1 -0
- package/dist/chunk-DRUSCLEF.js +177 -0
- package/dist/chunk-DRUSCLEF.js.map +1 -0
- package/dist/{chunk-VMNATBH3.cjs → chunk-F244Q4KC.cjs} +74 -33
- package/dist/chunk-F244Q4KC.cjs.map +1 -0
- package/dist/chunk-HVPGR6G5.cjs +647 -0
- package/dist/chunk-HVPGR6G5.cjs.map +1 -0
- package/dist/{chunk-SNJABBAT.js → chunk-MGP7F65H.js} +3 -3
- package/dist/{chunk-SNJABBAT.js.map → chunk-MGP7F65H.js.map} +1 -1
- package/dist/chunk-R3MC2AJZ.cjs +2247 -0
- package/dist/chunk-R3MC2AJZ.cjs.map +1 -0
- package/dist/chunk-SWML743U.js +625 -0
- package/dist/chunk-SWML743U.js.map +1 -0
- package/dist/chunk-SX3FQDKM.js +2238 -0
- package/dist/chunk-SX3FQDKM.js.map +1 -0
- package/dist/{chunk-A6N3RPEA.cjs → chunk-WTCXTXTV.cjs} +6 -6
- package/dist/{chunk-A6N3RPEA.cjs.map → chunk-WTCXTXTV.cjs.map} +1 -1
- package/dist/constants-Bi5uTRp5.d.cts +17 -0
- package/dist/constants-Bi5uTRp5.d.ts +17 -0
- package/dist/core/index.cjs +69 -29
- package/dist/core/index.d.cts +29 -47
- package/dist/core/index.d.ts +29 -47
- package/dist/core/index.js +3 -3
- package/dist/index.cjs +104 -35
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -5
- package/dist/names/index.cjs +40 -0
- package/dist/names/index.cjs.map +1 -0
- package/dist/names/index.d.cts +36 -0
- package/dist/names/index.d.ts +36 -0
- package/dist/names/index.js +3 -0
- package/dist/names/index.js.map +1 -0
- package/dist/react/index.cjs +454 -397
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +17 -3
- package/dist/react/index.d.ts +17 -3
- package/dist/react/index.js +450 -394
- package/dist/react/index.js.map +1 -1
- package/dist/solfaces.cdn.global.js +2 -2
- package/dist/solfaces.cdn.global.js.map +1 -1
- package/dist/themes/index.cjs +29 -17
- package/dist/themes/index.d.cts +10 -7
- package/dist/themes/index.d.ts +10 -7
- package/dist/themes/index.js +1 -1
- package/dist/{traits-DAFZnXeS.d.cts → traits-QlWuxZDD.d.cts} +45 -1
- package/dist/{traits-DAFZnXeS.d.ts → traits-QlWuxZDD.d.ts} +45 -1
- package/dist/vanilla/index.cjs +20 -8
- package/dist/vanilla/index.cjs.map +1 -1
- package/dist/vanilla/index.d.cts +1 -1
- package/dist/vanilla/index.d.ts +1 -1
- package/dist/vanilla/index.js +17 -5
- package/dist/vanilla/index.js.map +1 -1
- package/package.json +22 -5
- package/python/solfaces.py +830 -237
- package/reference/integrations.md +166 -0
- package/reference/react.md +108 -0
- package/reference/themes.md +124 -0
- package/dist/chunk-2DIKGLXZ.cjs +0 -126
- package/dist/chunk-2DIKGLXZ.cjs.map +0 -1
- package/dist/chunk-CVFO7YHY.cjs +0 -97
- package/dist/chunk-CVFO7YHY.cjs.map +0 -1
- package/dist/chunk-H3SK3MNX.cjs +0 -409
- package/dist/chunk-H3SK3MNX.cjs.map +0 -1
- package/dist/chunk-KSGFMW33.js +0 -401
- package/dist/chunk-KSGFMW33.js.map +0 -1
- package/dist/chunk-LQWJRHGC.js +0 -86
- package/dist/chunk-LQWJRHGC.js.map +0 -1
- package/dist/chunk-RX6D5FGH.js.map +0 -1
- package/dist/chunk-VMNATBH3.cjs.map +0 -1
- package/dist/chunk-WURY4QGH.js +0 -117
- package/dist/chunk-WURY4QGH.js.map +0 -1
- package/skill.md +0 -463
package/README.md
CHANGED
|
@@ -1,22 +1,36 @@
|
|
|
1
|
-
#
|
|
1
|
+
# SolFaces
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/solfaces)
|
|
4
|
+
[](https://www.npmjs.com/package/solfaces)
|
|
5
|
+
[](https://github.com/jorger3301/SolFaces/blob/main/LICENSE)
|
|
6
|
+
[](https://bundlephobia.com/package/solfaces)
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
**Deterministic wallet avatars and names for the Solana ecosystem.**
|
|
9
|
+
|
|
10
|
+
Every Solana wallet address generates a unique, consistent face and a deterministic name — no API calls, no storage, no randomness. Same wallet = same face, same name, everywhere, forever.
|
|
6
11
|
|
|
7
12
|
Built for dApps, AI agents, social features, leaderboards, and anywhere a wallet needs a visual identity.
|
|
8
13
|
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
*Default, Light, Dark, and Mono — four of the 11 built-in themes. Each row shows the same 10 wallets rendered in a different theme.*
|
|
17
|
+
|
|
9
18
|
---
|
|
10
19
|
|
|
11
20
|
## Why SolFaces?
|
|
12
21
|
|
|
13
22
|
- **Deterministic** — Same wallet always produces the same avatar. No database needed.
|
|
14
23
|
- **Zero dependencies** — Core engine has no runtime dependencies.
|
|
15
|
-
- **~
|
|
24
|
+
- **~2.56B unique faces** — 11 traits with expanded ranges = massive combination space.
|
|
25
|
+
- **SolNames** — Every wallet gets a deterministic, human-friendly name derived via SHA-256 (e.g. "SunnyIcon"). ~1M display names, ~65.5B unique tags.
|
|
26
|
+
- **11 built-in themes** — Default, Dark, Light, Mono, Flat, Transparent, plus 3 Pixel and 2 Glass themes (React).
|
|
27
|
+
- **Gradient-rich rendering** — Skin-luminance-driven colors, specular highlights, cheek blush, gradient hair, glow overlays.
|
|
16
28
|
- **Works everywhere** — React, vanilla JS, Node, Python, CDN script tag, edge functions.
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
29
|
+
- **Flat mode** — Disable all gradients for simplified rendering.
|
|
30
|
+
- **Detail levels** — Full detail (gradients, specular, cheeks) at size >= 48, simplified below.
|
|
31
|
+
- **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.
|
|
32
|
+
- **Eliminates dead space** — No more blank avatars or generic placeholders. Every wallet gets a unique face instantly.
|
|
33
|
+
- **AI-agent ready** — AI trading bots and autonomous agents are becoming on-chain users. SolFaces gives every agent a recognizable face and a natural language self-description for system prompts and bios.
|
|
20
34
|
- **PNG rasterization** — Serve real image files for bots, Discord, Telegram, OG images.
|
|
21
35
|
- **SSR-ready** — String renderer works server-side with zero browser APIs.
|
|
22
36
|
|
|
@@ -57,6 +71,25 @@ function UserProfile({ walletAddress }) {
|
|
|
57
71
|
}
|
|
58
72
|
```
|
|
59
73
|
|
|
74
|
+
### Pixel Art Mode (React)
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
import { SolFace } from "solfaces/react";
|
|
78
|
+
import { pixelTheme, pixelRetroTheme } from "solfaces/themes";
|
|
79
|
+
|
|
80
|
+
<SolFace walletAddress="7xKXqR..." size={64} theme={pixelTheme} />
|
|
81
|
+
<SolFace walletAddress="7xKXqR..." size={64} theme={pixelRetroTheme} />
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Liquid Glass Mode (React)
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { SolFace } from "solfaces/react";
|
|
88
|
+
import { glassTheme, glassDarkTheme } from "solfaces/themes";
|
|
89
|
+
|
|
90
|
+
<SolFace walletAddress="7xKXqR..." size={64} theme={glassTheme} />
|
|
91
|
+
```
|
|
92
|
+
|
|
60
93
|
### Vanilla JS (npm)
|
|
61
94
|
|
|
62
95
|
```js
|
|
@@ -69,6 +102,8 @@ mountSolFace("#avatar", "7xKXqR...", { size: 48 });
|
|
|
69
102
|
|
|
70
103
|
```html
|
|
71
104
|
<div data-solface="7xKXqR..." data-solface-size="48" data-solface-theme="dark"></div>
|
|
105
|
+
<div data-solface="DRpbCBMx..." data-solface-flat="true"></div>
|
|
106
|
+
<div data-solface="9WzDXwBb..." data-solface-detail="full"></div>
|
|
72
107
|
|
|
73
108
|
<script src="https://unpkg.com/solfaces/dist/solfaces.cdn.global.js"></script>
|
|
74
109
|
<!-- Auto-initializes on DOMContentLoaded -->
|
|
@@ -80,6 +115,24 @@ mountSolFace("#avatar", "7xKXqR...", { size: 48 });
|
|
|
80
115
|
</script>
|
|
81
116
|
```
|
|
82
117
|
|
|
118
|
+
### Name Derivation (SolNames)
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { deriveName, deriveIdentity } from "solfaces";
|
|
122
|
+
|
|
123
|
+
deriveName("7xKXqR...");
|
|
124
|
+
// → "SunnyIcon" (deterministic, SHA-256 derived)
|
|
125
|
+
|
|
126
|
+
deriveName("7xKXqR...", "tag");
|
|
127
|
+
// → "SunnyIcon#2f95" (unique identifier)
|
|
128
|
+
|
|
129
|
+
deriveName("7xKXqR...", "full");
|
|
130
|
+
// → "SunnyIcon-InfiniteOre" (formal contexts)
|
|
131
|
+
|
|
132
|
+
const id = deriveIdentity("7xKXqR...");
|
|
133
|
+
// → { short, name, tag, full, adjective, noun, hash, discriminator }
|
|
134
|
+
```
|
|
135
|
+
|
|
83
136
|
### Node / SSR / Edge
|
|
84
137
|
|
|
85
138
|
```ts
|
|
@@ -92,18 +145,157 @@ const svg = renderSolFaceSVG("7xKXqR...", { size: 128 });
|
|
|
92
145
|
### Python
|
|
93
146
|
|
|
94
147
|
```python
|
|
95
|
-
from solfaces import generate_traits, render_svg, describe_appearance
|
|
148
|
+
from solfaces import generate_traits, render_svg, describe_appearance, derive_name
|
|
96
149
|
|
|
97
150
|
traits = generate_traits("7xKXqR...")
|
|
98
151
|
svg = render_svg("7xKXqR...", size=256)
|
|
99
152
|
desc = describe_appearance("7xKXqR...")
|
|
153
|
+
name = derive_name("7xKXqR...")
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## SolNames — Deterministic Name Derivation
|
|
159
|
+
|
|
160
|
+
Every wallet gets a deterministic, human-friendly name derived via SHA-256 hashing and curated word lists. Nothing like this exists on any blockchain — every other naming system (SNS, ENS, Unstoppable Domains) requires purchase. SolNames derives names automatically — zero registration, zero storage, just math.
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
Wallet: 7PjJ2AHq9BMXWYjt3qqeKwZVLXHYFPmHRYrMF6PpRySD
|
|
164
|
+
│
|
|
165
|
+
↓
|
|
166
|
+
SHA-256("solnames-v1:" + wallet) → 32 bytes
|
|
167
|
+
│
|
|
168
|
+
├─→ Bytes 0-3: seed PRNG → adjective + noun
|
|
169
|
+
└─→ Bytes 8-9: hex discriminator → "2f95"
|
|
170
|
+
|
|
171
|
+
Display: WavingMistral
|
|
172
|
+
Tag: WavingMistral#2f95
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Name Formats
|
|
176
|
+
|
|
177
|
+
| Format | Example | Unique Names | Use Case |
|
|
178
|
+
|---------|------------------------------|-------------|-----------------------------|
|
|
179
|
+
| short | "Waving" | 1,000 | Tight UIs, badges |
|
|
180
|
+
| display | "WavingMistral" | ~1,000,000 | Default — profiles, feeds |
|
|
181
|
+
| tag | "WavingMistral#2f95" | ~65.5B | Unique identifier |
|
|
182
|
+
| full | "WavingMistral-InfiniteOre" | ~1T | Formal contexts |
|
|
183
|
+
|
|
184
|
+
### Usage
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { deriveName, deriveIdentity } from "solfaces";
|
|
188
|
+
// or: import { deriveName } from "solfaces/names";
|
|
189
|
+
|
|
190
|
+
deriveName("7xKXqR..."); // → "SunnyIcon" (display format)
|
|
191
|
+
deriveName("7xKXqR...", "short"); // → "Sunny"
|
|
192
|
+
deriveName("7xKXqR...", "tag"); // → "SunnyIcon#2f95"
|
|
193
|
+
deriveName("7xKXqR...", "full"); // → "SunnyIcon-InfiniteOre"
|
|
194
|
+
|
|
195
|
+
const id = deriveIdentity("7xKXqR...");
|
|
196
|
+
// → { short, name, tag, full, adjective, noun, hash, discriminator }
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### React Hook
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
import { useSolName } from "solfaces/react";
|
|
203
|
+
|
|
204
|
+
function Profile({ wallet }) {
|
|
205
|
+
const name = useSolName(wallet, "display"); // string
|
|
206
|
+
const identity = useSolName(wallet); // full SolNameIdentity
|
|
207
|
+
return <span>{name}</span>;
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Show Name with Avatar
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
import { SolFace } from "solfaces/react";
|
|
215
|
+
|
|
216
|
+
<SolFace walletAddress="7xKXqR..." showName />
|
|
217
|
+
<SolFace walletAddress="7xKXqR..." showName namePosition="above" nameFormat="tag" />
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Validation
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
import { isValidSolName, parseSolName } from "solfaces/names";
|
|
224
|
+
|
|
225
|
+
isValidSolName("SunnyIcon"); // true
|
|
226
|
+
isValidSolName("SunnyIcon#2f95"); // true
|
|
227
|
+
parseSolName("SunnyIcon#2f95");
|
|
228
|
+
// → { adjective: "Sunny", noun: "Icon", discriminator: "2f95" }
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
- **1000 adjectives + 1000 nouns** — curated positive/neutral PascalCase words
|
|
232
|
+
- **Same name everywhere** — TypeScript, Python, CDN, and server all produce identical output
|
|
233
|
+
- **Blocked combinations** — offensive adjective+noun pairs are automatically skipped
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Rendering Modes
|
|
238
|
+
|
|
239
|
+
### Full Detail vs Simplified
|
|
240
|
+
|
|
241
|
+
SolFaces automatically adjusts detail based on size:
|
|
242
|
+
|
|
243
|
+
- **Full detail** (size >= 48): Gradient fills, specular highlights on eyes, cheek blush, chin shadow, face glow, eyelid strokes, jawline hints.
|
|
244
|
+
- **Simplified** (size < 48): Flat shapes optimized for small sizes — no gradients, no cheeks, no specular.
|
|
245
|
+
|
|
246
|
+
Override with the `detail` option:
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
renderSolFaceSVG("7xKXqR...", { detail: "full" }); // Force full detail at any size
|
|
250
|
+
renderSolFaceSVG("7xKXqR...", { detail: "simplified" }); // Force simplified
|
|
251
|
+
renderSolFaceSVG("7xKXqR...", { detail: "auto" }); // Default — based on size
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Flat Mode
|
|
255
|
+
|
|
256
|
+
Disable all gradients globally. Useful for print, email clients, or minimal UIs:
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
import { flatTheme } from "solfaces/themes";
|
|
260
|
+
|
|
261
|
+
renderSolFaceSVG("7xKXqR...", { theme: flatTheme });
|
|
262
|
+
// Zero <linearGradient> or <radialGradient> elements in output
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Or set `flat: true` on any theme:
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
renderSolFaceSVG("7xKXqR...", { theme: { flat: true } });
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Pixel Art Mode (React Only)
|
|
272
|
+
|
|
273
|
+
Renders the SVG at a low pixel density then scales up with `image-rendering: pixelated`:
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
import { pixelTheme, pixelRetroTheme, pixelCleanTheme } from "solfaces/themes";
|
|
277
|
+
|
|
278
|
+
<SolFace walletAddress="7xKXqR..." theme={pixelTheme} /> // 16px density, rounded
|
|
279
|
+
<SolFace walletAddress="7xKXqR..." theme={pixelRetroTheme} /> // 12px + scanlines + shadow
|
|
280
|
+
<SolFace walletAddress="7xKXqR..." theme={pixelCleanTheme} /> // 24px, clean
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Liquid Glass Mode (React Only)
|
|
284
|
+
|
|
285
|
+
Backdrop-blur glass effect with specular highlights and rim lighting:
|
|
286
|
+
|
|
287
|
+
```tsx
|
|
288
|
+
import { glassTheme, glassDarkTheme } from "solfaces/themes";
|
|
289
|
+
|
|
290
|
+
<SolFace walletAddress="7xKXqR..." theme={glassTheme} />
|
|
291
|
+
<SolFace walletAddress="7xKXqR..." theme={glassDarkTheme} />
|
|
100
292
|
```
|
|
101
293
|
|
|
102
294
|
---
|
|
103
295
|
|
|
104
296
|
## AI Agent Identity
|
|
105
297
|
|
|
106
|
-
|
|
298
|
+
AI trading bots, autonomous agents, and on-chain programs are becoming users — they need a visual identity, a personality, and a recognizable presence. SolFaces gives every agent a deterministic face tied to their wallet, plus natural language self-descriptions they can use in system prompts to know and reference what they look like.
|
|
107
299
|
|
|
108
300
|
### System Prompt Integration
|
|
109
301
|
|
|
@@ -112,11 +304,11 @@ import { agentAppearancePrompt } from "solfaces";
|
|
|
112
304
|
|
|
113
305
|
const appearance = agentAppearancePrompt("7xKXqR...", "Atlas");
|
|
114
306
|
// → "My visual identity is a SolFace avatar (ID: a3f2b1c0) derived from
|
|
115
|
-
// my wallet address. I'm Atlas. I have a
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
307
|
+
// my wallet address. I'm Atlas. I have a squircle face with warm golden skin,
|
|
308
|
+
// almond-shaped hazel eyes with gently curved eyebrows, and flowing
|
|
309
|
+
// auburn wavy hair. I'm wearing aviator sunglasses. I have a playful grin.
|
|
310
|
+
// This appearance is deterministic — anyone who looks up my wallet will
|
|
311
|
+
// see the same face."
|
|
120
312
|
|
|
121
313
|
const systemPrompt = `You are Atlas, a DeFi trading agent. ${appearance}`;
|
|
122
314
|
```
|
|
@@ -134,11 +326,11 @@ describeAppearance("7xKXqR...", { format: "paragraph", perspective: "first", nam
|
|
|
134
326
|
|
|
135
327
|
// Structured (for data display)
|
|
136
328
|
describeAppearance("7xKXqR...", { format: "structured" });
|
|
137
|
-
// → "Face:
|
|
329
|
+
// → "Face: squircle\nSkin: warm golden\nEyes: almond-shaped, hazel\n..."
|
|
138
330
|
|
|
139
331
|
// Compact (for alt text, captions)
|
|
140
332
|
describeAppearance("7xKXqR...", { format: "compact" });
|
|
141
|
-
// → "
|
|
333
|
+
// → "squircle face, warm golden skin, hazel almond eyes, wavy auburn hair, aviator sunglasses, grinning"
|
|
142
334
|
```
|
|
143
335
|
|
|
144
336
|
### Alt Text & Accessibility
|
|
@@ -147,7 +339,7 @@ describeAppearance("7xKXqR...", { format: "compact" });
|
|
|
147
339
|
import { solFaceAltText } from "solfaces";
|
|
148
340
|
|
|
149
341
|
const alt = solFaceAltText("7xKXqR...");
|
|
150
|
-
// → "SolFace avatar:
|
|
342
|
+
// → "SolFace avatar: squircle face, warm golden skin, hazel almond eyes, ..."
|
|
151
343
|
```
|
|
152
344
|
|
|
153
345
|
### Python (AI Agent Backends)
|
|
@@ -206,36 +398,69 @@ const dataUrl = await renderSolFacePNGDataURL("7xKXqR...", { pngSize: 256 });
|
|
|
206
398
|
|
|
207
399
|
## Themes
|
|
208
400
|
|
|
209
|
-
SolFaces
|
|
401
|
+
SolFaces ships with 11 preset themes. Themes control colors, gradients, borders, rendering modes, and more.
|
|
210
402
|
|
|
211
403
|
### Available Presets
|
|
212
404
|
|
|
213
|
-
| Theme | Description |
|
|
214
|
-
|
|
215
|
-
| `
|
|
216
|
-
| `
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `
|
|
405
|
+
| Theme | Description | Works In |
|
|
406
|
+
|-------|-------------|----------|
|
|
407
|
+
| `default` | Base look with gradient-rich rendering — no overrides | All renderers |
|
|
408
|
+
| `dark` | Dark backgrounds with muted tones and subtle border | All renderers |
|
|
409
|
+
| `light` | Soft pastel backgrounds with rounded corners | All renderers |
|
|
410
|
+
| `mono` | Full grayscale — all colors replaced with grays | All renderers |
|
|
411
|
+
| `flat` | Disables all gradients — flat fill colors only | All renderers |
|
|
412
|
+
| `transparent` | Transparent background with flat rendering | All renderers |
|
|
413
|
+
| `glass` | Liquid glass effect with backdrop blur and specular highlights | React only |
|
|
414
|
+
| `glassDark` | Dark variant of liquid glass with deeper blur | React only |
|
|
415
|
+
| `pixel` | Pixel art mode at 16px density with rounded corners | React only |
|
|
416
|
+
| `pixelRetro` | Retro pixel art with scanlines and drop shadow | React only |
|
|
417
|
+
| `pixelClean` | Clean pixel art at 24px density | React only |
|
|
418
|
+
|
|
419
|
+
### Using Themes
|
|
420
|
+
|
|
421
|
+
```ts
|
|
422
|
+
import { renderSolFaceSVG } from "solfaces";
|
|
423
|
+
import { darkTheme } from "solfaces/themes";
|
|
424
|
+
|
|
425
|
+
const svg = renderSolFaceSVG("7xKXqR...", { theme: darkTheme });
|
|
426
|
+
```
|
|
223
427
|
|
|
224
428
|
### Custom Themes
|
|
225
429
|
|
|
430
|
+
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.
|
|
431
|
+
|
|
226
432
|
```ts
|
|
433
|
+
import type { SolFaceTheme } from "solfaces";
|
|
434
|
+
|
|
227
435
|
const myTheme: SolFaceTheme = {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
436
|
+
// Color palettes (arrays — one color per trait variant)
|
|
437
|
+
skinColors: ["#fce4d4", "#f5d0b0", "#e8b88a", "#d4956a", "#b5724a", "#8d5524", "#6b3f1d", "#4a2c17", "#3a1f10", "#2a1008"],
|
|
438
|
+
eyeColors: ["#333", "#4a80c4", "#5a9a5a", "#c89430", "#8a8a8a"],
|
|
439
|
+
hairColors: ["#1a1a1a", "#4a3728", "#8b6b4a", "#c44a20", "#d4a844", "#6090e0", "#14F195", "#e040c0", "#ff6b6b", "#4ecdc4"],
|
|
440
|
+
bgColors: ["#14F195", "#4a90e2", "#9945FF", "#f0e68c", "#e06070", "#ff8c42", "#5bc0be", "#8338ec", "#ff006e", "#3a86ff"],
|
|
441
|
+
|
|
442
|
+
// Individual color overrides
|
|
232
443
|
mouthColor: "#e06070",
|
|
233
444
|
eyebrowColor: "#aaa",
|
|
234
|
-
accessoryColor: "#888",
|
|
235
|
-
eyeWhiteColor: "#e0e0e0",
|
|
236
|
-
noseColor: "#c68642aa",
|
|
445
|
+
accessoryColor: "#888", // Default glasses/earring/headband color
|
|
446
|
+
eyeWhiteColor: "#e0e0e0", // Sclera + teeth color (important for dark themes)
|
|
447
|
+
noseColor: "#c68642aa", // Nose color (defaults to skin-derived)
|
|
448
|
+
glassesColor: "#333", // Glasses frame color (overrides accessoryColor)
|
|
449
|
+
earringColor: "#ffd700", // Earring color (overrides accessoryColor)
|
|
450
|
+
headbandColor: "#e04080", // Headband color (overrides accessoryColor)
|
|
451
|
+
|
|
452
|
+
// Rendering control
|
|
453
|
+
flat: false, // Set true to disable all gradients
|
|
454
|
+
cheekEnabled: true, // Enable/disable cheek blush
|
|
455
|
+
cheekColor: "#ff8080", // Custom cheek color
|
|
456
|
+
cheekOpacity: 0.3, // Cheek blush opacity
|
|
457
|
+
skinOpacity: 1, // Skin fill opacity
|
|
458
|
+
shadowEnabled: true, // Enable/disable chin shadow
|
|
459
|
+
glowIntensity: 0.15, // Face glow strength
|
|
460
|
+
|
|
461
|
+
// Layout
|
|
237
462
|
bgOpacity: 1,
|
|
238
|
-
bgRadius:
|
|
463
|
+
bgRadius: 14,
|
|
239
464
|
border: { color: "#14F195", width: 2 },
|
|
240
465
|
};
|
|
241
466
|
```
|
|
@@ -248,25 +473,98 @@ import { getPresetTheme } from "solfaces/themes";
|
|
|
248
473
|
const myTheme = getPresetTheme("dark", {
|
|
249
474
|
bgRadius: 999,
|
|
250
475
|
border: { color: "#14F195", width: 1 },
|
|
476
|
+
eyeWhiteColor: "#d0c8c0", // Warmer eye whites for dark mode
|
|
251
477
|
});
|
|
252
478
|
```
|
|
253
479
|
|
|
254
|
-
###
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
480
|
+
### Theme Field Reference
|
|
481
|
+
|
|
482
|
+
**Color palettes** (arrays — one per trait variant):
|
|
483
|
+
|
|
484
|
+
| Field | Type | What it controls |
|
|
485
|
+
|-------|------|-----------------|
|
|
486
|
+
| `skinColors` | `string[]` | 10 skin tone colors |
|
|
487
|
+
| `eyeColors` | `string[]` | 5 iris/pupil colors |
|
|
488
|
+
| `hairColors` | `string[]` | 10 hair fill colors |
|
|
489
|
+
| `bgColors` | `string[]` | 10 background fill colors |
|
|
490
|
+
|
|
491
|
+
**Individual color overrides:**
|
|
492
|
+
|
|
493
|
+
| Field | Type | What it controls |
|
|
494
|
+
|-------|------|-----------------|
|
|
495
|
+
| `mouthColor` | `string` | Mouth stroke/fill |
|
|
496
|
+
| `eyebrowColor` | `string` | Eyebrow stroke |
|
|
497
|
+
| `accessoryColor` | `string` | Default accessory color (glasses, earring, headband) |
|
|
498
|
+
| `eyeWhiteColor` | `string` | Sclera (eye white) and teeth color — set for dark themes |
|
|
499
|
+
| `noseColor` | `string` | Nose color (defaults to skin-derived + transparency) |
|
|
500
|
+
| `glassesColor` | `string` | Glasses frame color (overrides accessoryColor) |
|
|
501
|
+
| `earringColor` | `string` | Earring color (overrides accessoryColor) |
|
|
502
|
+
| `headbandColor` | `string` | Headband color (overrides accessoryColor) |
|
|
503
|
+
|
|
504
|
+
**Rendering control:**
|
|
505
|
+
|
|
506
|
+
| Field | Type | What it controls |
|
|
507
|
+
|-------|------|-----------------|
|
|
508
|
+
| `flat` | `boolean` | Disable all gradients (flat fill colors only) |
|
|
509
|
+
| `cheekEnabled` | `boolean` | Enable/disable cheek blush |
|
|
510
|
+
| `cheekColor` | `string` | Custom cheek color |
|
|
511
|
+
| `cheekOpacity` | `number` | Cheek blush opacity (0-1) |
|
|
512
|
+
| `skinOpacity` | `number` | Skin fill opacity (0-1) |
|
|
513
|
+
| `shadowEnabled` | `boolean` | Enable/disable chin shadow and face overlays |
|
|
514
|
+
|
|
515
|
+
**Layout:**
|
|
516
|
+
|
|
517
|
+
| Field | Type | What it controls |
|
|
518
|
+
|-------|------|-----------------|
|
|
519
|
+
| `bgOpacity` | `number` | Background opacity (0-1) |
|
|
520
|
+
| `bgRadius` | `number` | SVG rect border radius (999 = circle) |
|
|
521
|
+
| `border` | `{ color, width }` | Optional border around avatar |
|
|
522
|
+
|
|
523
|
+
### Pixel Art Customization (React Only)
|
|
524
|
+
|
|
525
|
+
All `_pixel*` fields are React-only. Set `_pixel: true` to enable pixel art mode.
|
|
526
|
+
|
|
527
|
+
| Field | Type | Default | What it controls |
|
|
528
|
+
|-------|------|---------|-----------------|
|
|
529
|
+
| `_pixel` | `boolean` | `false` | Enable pixel art mode |
|
|
530
|
+
| `_pixelDensity` | `number` | `16` | Render resolution before upscale (lower = blockier) |
|
|
531
|
+
| `_pixelRounded` | `boolean` | `true` | Rounded corners on pixel container |
|
|
532
|
+
| `_pixelOutline` | `boolean` | `false` | Draw outline around pixel art |
|
|
533
|
+
| `_pixelOutlineColor` | `string` | `"#000"` | Outline color |
|
|
534
|
+
| `_pixelOutlineWidth` | `number` | `1` | Outline width in pixels |
|
|
535
|
+
| `_pixelContrast` | `number` | — | CSS contrast filter |
|
|
536
|
+
| `_pixelSaturation` | `number` | — | CSS saturation filter |
|
|
537
|
+
| `_pixelBrightness` | `number` | — | CSS brightness filter |
|
|
538
|
+
| `_pixelScanlines` | `boolean` | `false` | Horizontal scanline overlay |
|
|
539
|
+
| `_pixelScanlineOpacity` | `number` | `0.08` | Scanline opacity |
|
|
540
|
+
| `_pixelScanlineSpacing` | `number` | `2` | Scanline spacing in pixels |
|
|
541
|
+
| `_pixelGrid` | `boolean` | `false` | Pixel grid overlay |
|
|
542
|
+
| `_pixelGridOpacity` | `number` | — | Grid opacity |
|
|
543
|
+
| `_pixelGridColor` | `string` | — | Grid color |
|
|
544
|
+
| `_pixelShadow` | `boolean` | `false` | Drop shadow behind pixel art |
|
|
545
|
+
| `_pixelShadowColor` | `string` | `"rgba(0,0,0,0.3)"` | Shadow color |
|
|
546
|
+
| `_pixelShadowOffset` | `number` | `2` | Shadow offset in pixels |
|
|
547
|
+
|
|
548
|
+
### Liquid Glass Customization (React Only)
|
|
549
|
+
|
|
550
|
+
All glass fields are React-only. Set `_glass: true` to enable liquid glass mode.
|
|
551
|
+
|
|
552
|
+
| Field | Type | Default | What it controls |
|
|
553
|
+
|-------|------|---------|-----------------|
|
|
554
|
+
| `_glass` | `boolean` | `false` | Enable liquid glass mode |
|
|
555
|
+
| `_blurRadius` | `number` | `12` | Backdrop blur radius |
|
|
556
|
+
| `_saturate` | `number` | `1.8` | Backdrop saturation multiplier |
|
|
557
|
+
| `_tintColor` | `string` | `"rgba(255,255,255,1)"` | Glass tint color |
|
|
558
|
+
| `_tintOpacity` | `number` | `0.12` | Glass tint opacity |
|
|
559
|
+
| `_borderColor` | `string` | `"rgba(255,255,255,0.25)"` | Glass border color |
|
|
560
|
+
| `_borderWidth` | `number` | `1` | Glass border width |
|
|
561
|
+
| `_borderOpacity` | `number` | `0.25` | Glass border opacity |
|
|
562
|
+
| `_specularColor` | `string` | `"rgba(255,255,255,1)"` | Specular highlight color |
|
|
563
|
+
| `_specularOpacity` | `number` | `0.25` | Specular highlight strength |
|
|
564
|
+
| `_specularEnd` | `number` | `50` | Specular gradient end (%) |
|
|
565
|
+
| `_lightAngle` | `number` | `135` | Light source angle (degrees) |
|
|
566
|
+
| `_rimIntensity` | `number` | `0.08` | Rim lighting intensity |
|
|
567
|
+
| `_shadow` | `string` | `"0 8px 32px rgba(0,0,0,0.12)"` | CSS box-shadow |
|
|
270
568
|
|
|
271
569
|
---
|
|
272
570
|
|
|
@@ -296,9 +594,10 @@ const result = await handleToolCall("generate_solface_svg", {
|
|
|
296
594
|
|------|-------------|
|
|
297
595
|
| `generate_solface_svg` | Render SVG avatar from wallet address |
|
|
298
596
|
| `describe_solface` | Natural language description of an avatar |
|
|
299
|
-
| `get_solface_traits` | Raw trait data with labels and
|
|
597
|
+
| `get_solface_traits` | Raw trait data with labels, hash, and name |
|
|
300
598
|
| `get_agent_identity` | System prompt snippet for AI agent identity |
|
|
301
599
|
| `list_solface_themes` | List available preset themes |
|
|
600
|
+
| `derive_solname` | Deterministic name from wallet via SHA-256 |
|
|
302
601
|
|
|
303
602
|
### MCP Server (Claude Code / Cursor)
|
|
304
603
|
|
|
@@ -327,14 +626,7 @@ import {
|
|
|
327
626
|
|
|
328
627
|
### Skill File for AI Agents
|
|
329
628
|
|
|
330
|
-
SolFaces includes a comprehensive `
|
|
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
|
|
629
|
+
SolFaces includes a comprehensive `SKILL.md` (with 3 reference files in `reference/`) that teaches AI agents how to integrate, customize, and use SolFaces. Feed it to any agent (Claude, GPT, custom bots) as context.
|
|
338
630
|
|
|
339
631
|
---
|
|
340
632
|
|
|
@@ -356,14 +648,15 @@ Templates included for: **Next.js App Router**, **Express**, **Hono (Cloudflare
|
|
|
356
648
|
|
|
357
649
|
## Python Port
|
|
358
650
|
|
|
359
|
-
Full Python implementation with identical trait generation to JavaScript. Zero dependencies.
|
|
651
|
+
Full Python implementation with identical trait generation to JavaScript. Zero dependencies. Includes gradient-rich rendering matching the TypeScript renderer.
|
|
360
652
|
|
|
361
653
|
```python
|
|
362
|
-
from solfaces import generate_traits, render_svg, describe_appearance
|
|
654
|
+
from solfaces import generate_traits, render_svg, describe_appearance, derive_name
|
|
363
655
|
|
|
364
656
|
traits = generate_traits("7xKXqR...")
|
|
365
657
|
svg = render_svg("7xKXqR...", size=256)
|
|
366
658
|
desc = describe_appearance("7xKXqR...")
|
|
659
|
+
name = derive_name("7xKXqR...")
|
|
367
660
|
prompt = agent_appearance_prompt("7xKXqR...", "Atlas")
|
|
368
661
|
```
|
|
369
662
|
|
|
@@ -375,8 +668,11 @@ python solfaces.py 7xKXqR... --svg # Output SVG
|
|
|
375
668
|
python solfaces.py 7xKXqR... --json # Output JSON
|
|
376
669
|
python solfaces.py 7xKXqR... --describe # Natural language
|
|
377
670
|
python solfaces.py 7xKXqR... --svg --size 512 # Custom size
|
|
671
|
+
python solfaces.py 7xKXqR... --svg --flat # Flat mode (no gradients)
|
|
378
672
|
```
|
|
379
673
|
|
|
674
|
+
> **Note:** Pixel art and liquid glass modes are React-only (CSS-dependent) and not available in the Python port.
|
|
675
|
+
|
|
380
676
|
---
|
|
381
677
|
|
|
382
678
|
## CDN / Script Tag
|
|
@@ -390,6 +686,8 @@ For sites without a build step — Webflow, Notion embeds, plain HTML, WordPress
|
|
|
390
686
|
<div data-solface="7xKXqR..." data-solface-size="48"></div>
|
|
391
687
|
<div data-solface="DRpbCBMx..." data-solface-size="48" data-solface-theme="dark"></div>
|
|
392
688
|
<div data-solface="9WzDXwBb..." data-solface-blink="true"></div>
|
|
689
|
+
<div data-solface="Abc123..." data-solface-flat="true"></div>
|
|
690
|
+
<div data-solface="Def456..." data-solface-detail="full"></div>
|
|
393
691
|
|
|
394
692
|
<!-- Global API available as window.SolFaces -->
|
|
395
693
|
<script>
|
|
@@ -397,6 +695,7 @@ For sites without a build step — Webflow, Notion embeds, plain HTML, WordPress
|
|
|
397
695
|
SolFaces.setImg("#pfp", "7xKXqR...");
|
|
398
696
|
const svg = SolFaces.renderSVG("7xKXqR...");
|
|
399
697
|
const desc = SolFaces.describe("7xKXqR...");
|
|
698
|
+
const name = SolFaces.deriveName("7xKXqR...");
|
|
400
699
|
const prompt = SolFaces.agentPrompt("7xKXqR...", "Atlas");
|
|
401
700
|
</script>
|
|
402
701
|
```
|
|
@@ -407,23 +706,33 @@ For sites without a build step — Webflow, Notion embeds, plain HTML, WordPress
|
|
|
407
706
|
|
|
408
707
|
| Function | Returns | Description |
|
|
409
708
|
|----------|---------|-------------|
|
|
709
|
+
| `deriveName(wallet, format?)` | `string` | Deterministic name from wallet (SHA-256) |
|
|
710
|
+
| `deriveIdentity(wallet)` | `SolNameIdentity` | Full identity bundle from wallet |
|
|
410
711
|
| `generateTraits(wallet, overrides?)` | `SolFaceTraits` | Deterministic traits from wallet |
|
|
712
|
+
| `getTraitLabels(traits)` | `Record<string, string>` | Human-readable trait names |
|
|
713
|
+
| `traitHash(wallet)` | `string` | 8-char hex hash |
|
|
714
|
+
| `resolveTheme(name?, themes?)` | `SolFaceTheme \| undefined` | Look up theme by name from a map |
|
|
715
|
+
| `mergeTheme(base, overrides)` | `SolFaceTheme` | Merge two themes |
|
|
716
|
+
| `effectiveAccessory(traits)` | `number` | Accessory index (earring suppressed for long/bob hair) |
|
|
411
717
|
| `renderSolFaceSVG(wallet, options?)` | `string` | Raw SVG markup |
|
|
412
718
|
| `renderSolFaceDataURI(wallet, options?)` | `string` | Data URI for `<img>` tags |
|
|
413
719
|
| `renderSolFaceBase64(wallet, options?)` | `string` | Base64 data URI |
|
|
414
720
|
| `renderSolFacePNG(wallet, options?)` | `Promise<Buffer>` | PNG buffer (Node) |
|
|
415
721
|
| `renderSolFacePNGBrowser(wallet, options?)` | `Promise<Blob>` | PNG blob (browser) |
|
|
722
|
+
| `renderSolFacePNGDataURL(wallet, options?)` | `Promise<string>` | PNG data URL (browser) |
|
|
416
723
|
| `describeAppearance(wallet, options?)` | `string` | Natural language description |
|
|
724
|
+
| `describeTraits(traits, options?)` | `string` | Describe from pre-generated traits |
|
|
417
725
|
| `agentAppearancePrompt(wallet, name?)` | `string` | System prompt for AI agents |
|
|
418
726
|
| `solFaceAltText(wallet)` | `string` | Accessible alt text |
|
|
419
|
-
| `
|
|
420
|
-
| `
|
|
421
|
-
| `
|
|
422
|
-
| `
|
|
423
|
-
| `
|
|
424
|
-
| `
|
|
425
|
-
| `
|
|
426
|
-
| `
|
|
727
|
+
| `hexToRgb(hex)` | `[r, g, b]` | Parse hex color |
|
|
728
|
+
| `rgbToHex(r, g, b)` | `string` | Convert RGB to hex |
|
|
729
|
+
| `darken(hex, pct)` | `string` | Darken a color |
|
|
730
|
+
| `lighten(hex, pct)` | `string` | Lighten a color |
|
|
731
|
+
| `blend(a, b, t)` | `string` | Blend two colors |
|
|
732
|
+
| `luminance(hex)` | `number` | Perceived luminance (0-255) |
|
|
733
|
+
| `deriveSkinColors(skinHex)` | `DerivedColors` | Full skin-luminance color derivation |
|
|
734
|
+
| `SOLFACE_TOOLS` | `SolFaceTool[]` | All 6 agent tool definitions |
|
|
735
|
+
| `handleToolCall(name, params)` | `unknown` | Universal agent tool dispatcher |
|
|
427
736
|
|
|
428
737
|
### React Component Props
|
|
429
738
|
|
|
@@ -431,25 +740,77 @@ For sites without a build step — Webflow, Notion embeds, plain HTML, WordPress
|
|
|
431
740
|
<SolFace
|
|
432
741
|
walletAddress="7xKXqR..." // Required
|
|
433
742
|
size={48} // Default: 64
|
|
434
|
-
enableBlink={true} // Default: false — or
|
|
743
|
+
enableBlink={true} // Default: false — or custom timing below
|
|
435
744
|
theme={darkTheme} // Optional theme
|
|
745
|
+
detail="full" // "full" | "simplified" | "auto"
|
|
436
746
|
traitOverrides={{ hairStyle: 0 }} // Pin specific traits
|
|
437
747
|
colorOverrides={{ hair: "#ff0000" }} // Override individual colors
|
|
438
748
|
className="my-avatar" // CSS class
|
|
439
749
|
style={{ borderRadius: "50%" }} // Inline styles
|
|
440
|
-
onClick={handleClick} // All SVG props supported
|
|
750
|
+
onClick={handleClick} // All standard SVG element props supported
|
|
751
|
+
/>
|
|
752
|
+
|
|
753
|
+
// Custom blink timing
|
|
754
|
+
<SolFace
|
|
755
|
+
walletAddress="7xKXqR..."
|
|
756
|
+
enableBlink={{ duration: 3, delay: 1 }} // 3s cycle, 1s initial delay
|
|
441
757
|
/>
|
|
442
758
|
```
|
|
443
759
|
|
|
760
|
+
### RenderOptions
|
|
761
|
+
|
|
762
|
+
```ts
|
|
763
|
+
interface RenderOptions {
|
|
764
|
+
size?: number; // Default: 64
|
|
765
|
+
theme?: SolFaceTheme; // Theme object
|
|
766
|
+
enableBlink?: boolean | { // Blink animation (boolean or custom timing)
|
|
767
|
+
duration?: number; // Blink cycle duration in seconds (default: 4)
|
|
768
|
+
delay?: number; // Initial delay in seconds (default: 0)
|
|
769
|
+
};
|
|
770
|
+
detail?: "full" | "simplified" | "auto"; // Detail level (default: "auto")
|
|
771
|
+
traitOverrides?: Partial<SolFaceTraits>; // Pin specific traits
|
|
772
|
+
className?: string; // CSS class on SVG element
|
|
773
|
+
colorOverrides?: { // Override individual colors per instance
|
|
774
|
+
skin?: string;
|
|
775
|
+
eyes?: string;
|
|
776
|
+
hair?: string;
|
|
777
|
+
bg?: string;
|
|
778
|
+
mouth?: string;
|
|
779
|
+
eyebrow?: string;
|
|
780
|
+
accessory?: string;
|
|
781
|
+
nose?: string;
|
|
782
|
+
eyeWhite?: string;
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
### Per-Instance Color Overrides
|
|
788
|
+
|
|
789
|
+
Override any color on a specific avatar without changing the global theme:
|
|
790
|
+
|
|
791
|
+
```tsx
|
|
792
|
+
// React
|
|
793
|
+
<SolFace walletAddress="7xKXqR..." colorOverrides={{ hair: "#ff0000", bg: "#000" }} />
|
|
794
|
+
|
|
795
|
+
// String renderer
|
|
796
|
+
renderSolFaceSVG("7xKXqR...", {
|
|
797
|
+
theme: darkTheme,
|
|
798
|
+
colorOverrides: { skin: "#ffd5b0", eyes: "#00ff00" },
|
|
799
|
+
});
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
Available keys: `skin`, `eyes`, `hair`, `bg`, `mouth`, `eyebrow`, `accessory`, `nose`, `eyeWhite`.
|
|
803
|
+
|
|
444
804
|
### Import Paths
|
|
445
805
|
|
|
446
806
|
| Path | Contents | React? |
|
|
447
807
|
|------|----------|--------|
|
|
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` |
|
|
808
|
+
| `solfaces` | Core + colors + themes + names + describe + rasterize + agent tools | No |
|
|
809
|
+
| `solfaces/core` | Engine only (traits, renderer, colors, describe) | No |
|
|
810
|
+
| `solfaces/react` | React component (base + pixel + glass modes) | Yes |
|
|
811
|
+
| `solfaces/vanilla` | DOM helpers (mount, setImg, autoInit) | No |
|
|
812
|
+
| `solfaces/themes` | 11 preset themes | No |
|
|
813
|
+
| `solfaces/names` | SolNames derivation + validation | No |
|
|
453
814
|
| `solfaces/agent` | AI agent tool definitions + framework adapters | No |
|
|
454
815
|
| `solfaces/cdn` | IIFE for `<script>` tags | No |
|
|
455
816
|
|
|
@@ -459,22 +820,26 @@ For sites without a build step — Webflow, Notion embeds, plain HTML, WordPress
|
|
|
459
820
|
|
|
460
821
|
| Trait | Variants | Options |
|
|
461
822
|
|-------|----------|---------|
|
|
462
|
-
| Face Shape | 4 |
|
|
463
|
-
| Skin Color |
|
|
464
|
-
| Eye Style | 8 | Round,
|
|
465
|
-
| Eye Color | 5 |
|
|
466
|
-
| Eyebrows | 5 |
|
|
467
|
-
| Nose | 4 |
|
|
468
|
-
| Mouth |
|
|
469
|
-
| Hair Style |
|
|
470
|
-
| Hair Color |
|
|
471
|
-
| Accessory |
|
|
472
|
-
| Background |
|
|
473
|
-
|
|
474
|
-
**Total unique combinations: ~
|
|
823
|
+
| Face Shape | 4 | Squircle (all — preserved for PRNG ordering) |
|
|
824
|
+
| Skin Color | 10 | Porcelain, Ivory, Fair, Light, Sand, Golden, Warm, Caramel, Brown, Deep |
|
|
825
|
+
| Eye Style | 8 | Round, Minimal, Almond, Wide, Relaxed, Joyful, Bright, Gentle |
|
|
826
|
+
| Eye Color | 5 | Chocolate, Sky, Emerald, Hazel, Storm |
|
|
827
|
+
| Eyebrows | 5 | Wispy, Straight, Natural, Arched, Angled |
|
|
828
|
+
| Nose | 4 | Shadow, Button, Soft, Nostrils |
|
|
829
|
+
| Mouth | 8 | Smile, Calm, Happy, Oh, Smirk, Grin, Flat, Pout |
|
|
830
|
+
| Hair Style | 10 | Bald, Short, Curly, Side Sweep, Puff, Long, Bob, Buzz, Wavy, Topknot |
|
|
831
|
+
| Hair Color | 10 | Black, Espresso, Walnut, Honey, Copper, Silver, Charcoal, Burgundy, Strawberry, Ginger |
|
|
832
|
+
| Accessory | 10 | None, Beauty Mark, Round Glasses, Rect Glasses, Earring, Headband, Freckles, Stud Earrings, Aviators, Band-Aid |
|
|
833
|
+
| Background | 10 | Rose, Olive, Sage, Fern, Mint, Ocean, Sky, Lavender, Orchid, Blush |
|
|
834
|
+
|
|
835
|
+
**Total unique combinations: ~2,560,000,000**
|
|
475
836
|
|
|
476
837
|
Algorithm: **djb2 hash** → **mulberry32 PRNG** → sequential trait sampling. Sub-millisecond. Deterministic across JS and Python.
|
|
477
838
|
|
|
839
|
+
### Color Derivation
|
|
840
|
+
|
|
841
|
+
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.
|
|
842
|
+
|
|
478
843
|
---
|
|
479
844
|
|
|
480
845
|
## Architecture
|
|
@@ -483,32 +848,59 @@ Algorithm: **djb2 hash** → **mulberry32 PRNG** → sequential trait sampling.
|
|
|
483
848
|
solfaces/
|
|
484
849
|
├── src/
|
|
485
850
|
│ ├── core/
|
|
851
|
+
│ │ ├── colors.ts # Color math: darken, lighten, blend, deriveSkinColors
|
|
486
852
|
│ │ ├── traits.ts # Types, palettes, theme system, trait generation
|
|
487
|
-
│ │ ├── renderer.ts # SVG string renderer,
|
|
488
|
-
│ │ ├── describe.ts #
|
|
853
|
+
│ │ ├── renderer.ts # SVG string renderer (gradient-rich, detail levels)
|
|
854
|
+
│ │ ├── describe.ts # (no names.ts — moved to names/)
|
|
489
855
|
│ │ ├── rasterize.ts # PNG output (sharp / resvg / canvas)
|
|
490
856
|
│ │ └── index.ts
|
|
857
|
+
│ ├── names/
|
|
858
|
+
│ │ ├── constants.ts # 1000 adjectives, 1000 nouns, blocked combos
|
|
859
|
+
│ │ ├── sha256.ts # Pure-JS SHA-256 (sync, zero deps)
|
|
860
|
+
│ │ ├── derive.ts # deriveName(), deriveIdentity()
|
|
861
|
+
│ │ ├── validate.ts # isValidSolName(), parseSolName()
|
|
862
|
+
│ │ └── index.ts
|
|
491
863
|
│ ├── react/
|
|
492
|
-
│ │ ├── SolFace.tsx # React component
|
|
864
|
+
│ │ ├── SolFace.tsx # React component (base + pixel art + liquid glass)
|
|
865
|
+
│ │ ├── useSolName.ts # useSolName() hook
|
|
493
866
|
│ │ └── index.ts
|
|
494
867
|
│ ├── vanilla/
|
|
495
868
|
│ │ └── index.ts # mountSolFace, setSolFaceImg, autoInit
|
|
496
869
|
│ ├── themes/
|
|
497
|
-
│ │ ├── presets.ts #
|
|
870
|
+
│ │ ├── presets.ts # 11 preset themes
|
|
498
871
|
│ │ └── index.ts
|
|
499
872
|
│ ├── agent/
|
|
500
|
-
│ │ ├── tools.ts #
|
|
873
|
+
│ │ ├── tools.ts # 6 canonical tool definitions + handlers
|
|
501
874
|
│ │ ├── index.ts # Format adapters (MCP, OpenAI, Anthropic, Vercel AI)
|
|
502
875
|
│ │ └── mcp-server.ts # Standalone MCP server (npx solfaces)
|
|
503
876
|
│ ├── cdn.ts # IIFE bundle for <script> tag
|
|
504
877
|
│ ├── api-templates.ts # Copy-paste route handlers
|
|
505
878
|
│ └── index.ts
|
|
506
879
|
├── python/
|
|
507
|
-
│ └── solfaces.py # Full Python port (zero deps)
|
|
880
|
+
│ └── solfaces.py # Full Python port (zero deps, gradient rendering)
|
|
508
881
|
├── package.json
|
|
509
882
|
└── tsup.config.ts
|
|
510
883
|
```
|
|
511
884
|
|
|
885
|
+
### Key Design Decisions
|
|
886
|
+
|
|
887
|
+
- **`colors.ts` is the single source of truth** for all color math. Both `renderer.ts` and `SolFace.tsx` import from it, preventing renderer drift.
|
|
888
|
+
- **`effectiveAccessory()`** handles earring suppression: long and bob hairstyles suppress earring accessories.
|
|
889
|
+
- **`_` prefix** on theme fields marks React-only features (pixel, glass). The string renderer ignores these.
|
|
890
|
+
- **Detail levels** are resolved at render time: `"auto"` → full if size >= 48, simplified otherwise.
|
|
891
|
+
|
|
892
|
+
---
|
|
893
|
+
|
|
894
|
+
## Migration from v1
|
|
895
|
+
|
|
896
|
+
v2.0.0 is a breaking release:
|
|
897
|
+
|
|
898
|
+
- **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.
|
|
899
|
+
- **Old themes removed.** `solana`, `neon`, `jupiter`, `phantom`, `circle` themes are gone. Use `dark`, `light`, `mono`, `flat`, `transparent`, or the new `glass`/`pixel` themes.
|
|
900
|
+
- **New rendering engine.** Gradient-rich rendering with skin-luminance-driven colors, ears, hair-back layers, and face overlays.
|
|
901
|
+
- **New theme fields.** `flat`, `cheekEnabled`, `shadowEnabled`, `glowIntensity`, and React-only `_glass*`/`_pixel*` fields.
|
|
902
|
+
- **`colorOverrides` still supported.** Per-instance color overrides work the same as v1.
|
|
903
|
+
|
|
512
904
|
---
|
|
513
905
|
|
|
514
906
|
## License
|