solfaces 1.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.
- package/LICENSE +21 -0
- package/README.md +518 -0
- package/dist/agent/index.cjs +51 -0
- package/dist/agent/index.cjs.map +1 -0
- package/dist/agent/index.d.cts +65 -0
- package/dist/agent/index.d.ts +65 -0
- package/dist/agent/index.js +6 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/mcp-server.cjs +836 -0
- package/dist/chunk-2DIKGLXZ.cjs +126 -0
- package/dist/chunk-2DIKGLXZ.cjs.map +1 -0
- package/dist/chunk-A6N3RPEA.cjs +111 -0
- package/dist/chunk-A6N3RPEA.cjs.map +1 -0
- package/dist/chunk-CVFO7YHY.cjs +97 -0
- package/dist/chunk-CVFO7YHY.cjs.map +1 -0
- package/dist/chunk-H3SK3MNX.cjs +409 -0
- package/dist/chunk-H3SK3MNX.cjs.map +1 -0
- package/dist/chunk-KSGFMW33.js +401 -0
- package/dist/chunk-KSGFMW33.js.map +1 -0
- package/dist/chunk-LQWJRHGC.js +86 -0
- package/dist/chunk-LQWJRHGC.js.map +1 -0
- package/dist/chunk-RX6D5FGH.js +211 -0
- package/dist/chunk-RX6D5FGH.js.map +1 -0
- package/dist/chunk-SNJABBAT.js +107 -0
- package/dist/chunk-SNJABBAT.js.map +1 -0
- package/dist/chunk-VMNATBH3.cjs +222 -0
- package/dist/chunk-VMNATBH3.cjs.map +1 -0
- package/dist/chunk-WURY4QGH.js +117 -0
- package/dist/chunk-WURY4QGH.js.map +1 -0
- package/dist/core/index.cjs +82 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +104 -0
- package/dist/core/index.d.ts +104 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index.cjs +100 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +543 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +28 -0
- package/dist/react/index.d.ts +28 -0
- package/dist/react/index.js +541 -0
- package/dist/react/index.js.map +1 -0
- package/dist/solfaces.cdn.global.js +3 -0
- package/dist/solfaces.cdn.global.js.map +1 -0
- package/dist/themes/index.cjs +48 -0
- package/dist/themes/index.cjs.map +1 -0
- package/dist/themes/index.d.cts +14 -0
- package/dist/themes/index.d.ts +14 -0
- package/dist/themes/index.js +3 -0
- package/dist/themes/index.js.map +1 -0
- package/dist/traits-DAFZnXeS.d.cts +61 -0
- package/dist/traits-DAFZnXeS.d.ts +61 -0
- package/dist/vanilla/index.cjs +43 -0
- package/dist/vanilla/index.cjs.map +1 -0
- package/dist/vanilla/index.d.cts +7 -0
- package/dist/vanilla/index.d.ts +7 -0
- package/dist/vanilla/index.js +39 -0
- package/dist/vanilla/index.js.map +1 -0
- package/package.json +100 -0
- package/python/solfaces.py +475 -0
- package/skill.md +463 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 jorger3301
|
|
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,518 @@
|
|
|
1
|
+
# SolFaces
|
|
2
|
+
|
|
3
|
+
**Deterministic wallet avatars for the Solana ecosystem.**
|
|
4
|
+
|
|
5
|
+
Every Solana wallet address generates a unique, consistent face — no API calls, no storage, no randomness. Same wallet = same face, everywhere, forever.
|
|
6
|
+
|
|
7
|
+
Built for dApps, AI agents, social features, leaderboards, and anywhere a wallet needs a visual identity.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Why SolFaces?
|
|
12
|
+
|
|
13
|
+
- **Deterministic** — Same wallet always produces the same avatar. No database needed.
|
|
14
|
+
- **Zero dependencies** — Core engine has no runtime dependencies.
|
|
15
|
+
- **~221M unique faces** — 11 traits with multiple variants = massive combination space.
|
|
16
|
+
- **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.
|
|
19
|
+
- **AI-agent ready** — Natural language self-descriptions for agent system prompts.
|
|
20
|
+
- **PNG rasterization** — Serve real image files for bots, Discord, Telegram, OG images.
|
|
21
|
+
- **SSR-ready** — String renderer works server-side with zero browser APIs.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
### npm / yarn / pnpm
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install solfaces
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### CDN (no build step)
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<script src="https://unpkg.com/solfaces/dist/solfaces.cdn.global.js"></script>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Python
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Zero dependencies — just copy the file
|
|
43
|
+
curl -O https://raw.githubusercontent.com/jorger3301/solfaces/main/python/solfaces.py
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
### React
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { SolFace } from "solfaces/react";
|
|
54
|
+
|
|
55
|
+
function UserProfile({ walletAddress }) {
|
|
56
|
+
return <SolFace walletAddress={walletAddress} size={48} enableBlink />;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Vanilla JS (npm)
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import { mountSolFace } from "solfaces/vanilla";
|
|
64
|
+
|
|
65
|
+
mountSolFace("#avatar", "7xKXqR...", { size: 48 });
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### CDN / Script Tag (zero build step)
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<div data-solface="7xKXqR..." data-solface-size="48" data-solface-theme="dark"></div>
|
|
72
|
+
|
|
73
|
+
<script src="https://unpkg.com/solfaces/dist/solfaces.cdn.global.js"></script>
|
|
74
|
+
<!-- Auto-initializes on DOMContentLoaded -->
|
|
75
|
+
|
|
76
|
+
<!-- Or use programmatically: -->
|
|
77
|
+
<script>
|
|
78
|
+
SolFaces.mount("#my-avatar", "7xKXqR...", { size: 64 });
|
|
79
|
+
const description = SolFaces.describe("7xKXqR...");
|
|
80
|
+
</script>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Node / SSR / Edge
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { renderSolFaceSVG } from "solfaces";
|
|
87
|
+
|
|
88
|
+
const svg = renderSolFaceSVG("7xKXqR...", { size: 128 });
|
|
89
|
+
// Raw SVG string — use in emails, OG images, PDFs, etc.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Python
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from solfaces import generate_traits, render_svg, describe_appearance
|
|
96
|
+
|
|
97
|
+
traits = generate_traits("7xKXqR...")
|
|
98
|
+
svg = render_svg("7xKXqR...", size=256)
|
|
99
|
+
desc = describe_appearance("7xKXqR...")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## AI Agent Identity
|
|
105
|
+
|
|
106
|
+
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.
|
|
107
|
+
|
|
108
|
+
### System Prompt Integration
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { agentAppearancePrompt } from "solfaces";
|
|
112
|
+
|
|
113
|
+
const appearance = agentAppearancePrompt("7xKXqR...", "Atlas");
|
|
114
|
+
// → "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."
|
|
120
|
+
|
|
121
|
+
const systemPrompt = `You are Atlas, a DeFi trading agent. ${appearance}`;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Description Formats
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import { describeAppearance } from "solfaces";
|
|
128
|
+
|
|
129
|
+
// Full paragraph (for bios, about pages)
|
|
130
|
+
describeAppearance("7xKXqR...", { format: "paragraph", perspective: "third" });
|
|
131
|
+
|
|
132
|
+
// First person (for agent self-reference)
|
|
133
|
+
describeAppearance("7xKXqR...", { format: "paragraph", perspective: "first", name: "Atlas" });
|
|
134
|
+
|
|
135
|
+
// Structured (for data display)
|
|
136
|
+
describeAppearance("7xKXqR...", { format: "structured" });
|
|
137
|
+
// → "Face: round\nSkin: light peach\nEyes: wide and expressive, blue\n..."
|
|
138
|
+
|
|
139
|
+
// Compact (for alt text, captions)
|
|
140
|
+
describeAppearance("7xKXqR...", { format: "compact" });
|
|
141
|
+
// → "round face, light peach skin, blue wide eyes, spiky mint hair, round glasses, smirking"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Alt Text & Accessibility
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import { solFaceAltText } from "solfaces";
|
|
148
|
+
|
|
149
|
+
const alt = solFaceAltText("7xKXqR...");
|
|
150
|
+
// → "SolFace avatar: round face, light peach skin, blue wide eyes, ..."
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Python (AI Agent Backends)
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from solfaces import agent_appearance_prompt
|
|
157
|
+
|
|
158
|
+
prompt = agent_appearance_prompt("7xKXqR...", "Atlas")
|
|
159
|
+
# Identical output to the JavaScript version
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## PNG Rasterization
|
|
165
|
+
|
|
166
|
+
For Discord bots, Telegram bots, OG images, emails, and anywhere SVG isn't supported.
|
|
167
|
+
|
|
168
|
+
### Node.js
|
|
169
|
+
|
|
170
|
+
Requires `sharp` or `@resvg/resvg-js` (install one):
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
npm install sharp
|
|
174
|
+
# or
|
|
175
|
+
npm install @resvg/resvg-js
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import { renderSolFacePNG } from "solfaces";
|
|
180
|
+
|
|
181
|
+
const pngBuffer = await renderSolFacePNG("7xKXqR...", { pngSize: 512 });
|
|
182
|
+
|
|
183
|
+
// Save to file
|
|
184
|
+
import fs from "fs";
|
|
185
|
+
fs.writeFileSync("avatar.png", pngBuffer);
|
|
186
|
+
|
|
187
|
+
// Send as HTTP response
|
|
188
|
+
return new Response(pngBuffer, {
|
|
189
|
+
headers: { "Content-Type": "image/png" },
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Browser
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
import { renderSolFacePNGBrowser, renderSolFacePNGDataURL } from "solfaces";
|
|
197
|
+
|
|
198
|
+
// As Blob (for downloads, uploads)
|
|
199
|
+
const blob = await renderSolFacePNGBrowser("7xKXqR...", { pngSize: 256 });
|
|
200
|
+
|
|
201
|
+
// As data URL (for img.src)
|
|
202
|
+
const dataUrl = await renderSolFacePNGDataURL("7xKXqR...", { pngSize: 256 });
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Themes
|
|
208
|
+
|
|
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.
|
|
210
|
+
|
|
211
|
+
### Available Presets
|
|
212
|
+
|
|
213
|
+
| Theme | Description |
|
|
214
|
+
|-------|-------------|
|
|
215
|
+
| `solanaTheme` | Default — vibrant Solana colors (#14F195, #9945FF) |
|
|
216
|
+
| `darkTheme` | Muted tones on dark backgrounds |
|
|
217
|
+
| `lightTheme` | Soft pastels for white/light UIs |
|
|
218
|
+
| `monoTheme` | Grayscale only — minimal 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 |
|
|
223
|
+
|
|
224
|
+
### Custom Themes
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
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"],
|
|
232
|
+
mouthColor: "#e06070",
|
|
233
|
+
eyebrowColor: "#aaa",
|
|
234
|
+
accessoryColor: "#888",
|
|
235
|
+
eyeWhiteColor: "#e0e0e0", // Sclera color (great for dark themes)
|
|
236
|
+
noseColor: "#c68642aa", // Nose color (defaults to skin + transparency)
|
|
237
|
+
bgOpacity: 1,
|
|
238
|
+
bgRadius: 999,
|
|
239
|
+
border: { color: "#14F195", width: 2 },
|
|
240
|
+
};
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Extending Presets
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
import { getPresetTheme } from "solfaces/themes";
|
|
247
|
+
|
|
248
|
+
const myTheme = getPresetTheme("dark", {
|
|
249
|
+
bgRadius: 999,
|
|
250
|
+
border: { color: "#14F195", width: 1 },
|
|
251
|
+
});
|
|
252
|
+
```
|
|
253
|
+
|
|
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`.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## AI Agent Tools
|
|
274
|
+
|
|
275
|
+
SolFaces ships with structured tool definitions that let AI agents discover and use it as a skill — compatible with OpenAI function calling, Anthropic tool use, Vercel AI SDK, and MCP.
|
|
276
|
+
|
|
277
|
+
### Quick Setup
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
import { allToolsOpenAI, handleToolCall } from "solfaces/agent";
|
|
281
|
+
|
|
282
|
+
// Register tools with your AI framework
|
|
283
|
+
const tools = allToolsOpenAI(); // or allToolsAnthropic(), allToolsVercelAI()
|
|
284
|
+
|
|
285
|
+
// Handle tool calls
|
|
286
|
+
const result = await handleToolCall("generate_solface_svg", {
|
|
287
|
+
wallet: "7xKXqR...",
|
|
288
|
+
theme: "dark",
|
|
289
|
+
size: 128,
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Available Tools
|
|
294
|
+
|
|
295
|
+
| Tool | Description |
|
|
296
|
+
|------|-------------|
|
|
297
|
+
| `generate_solface_svg` | Render SVG avatar from wallet address |
|
|
298
|
+
| `describe_solface` | Natural language description of an avatar |
|
|
299
|
+
| `get_solface_traits` | Raw trait data with labels and hash |
|
|
300
|
+
| `get_agent_identity` | System prompt snippet for AI agent identity |
|
|
301
|
+
| `list_solface_themes` | List available preset themes |
|
|
302
|
+
|
|
303
|
+
### MCP Server (Claude Code / Cursor)
|
|
304
|
+
|
|
305
|
+
```json
|
|
306
|
+
{
|
|
307
|
+
"mcpServers": {
|
|
308
|
+
"solfaces": {
|
|
309
|
+
"command": "npx",
|
|
310
|
+
"args": ["solfaces-mcp"]
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Framework Adapters
|
|
317
|
+
|
|
318
|
+
```ts
|
|
319
|
+
import {
|
|
320
|
+
allToolsOpenAI, // OpenAI function calling
|
|
321
|
+
allToolsAnthropic, // Claude / Anthropic tool use
|
|
322
|
+
allToolsVercelAI, // Vercel AI SDK
|
|
323
|
+
allToolsMCP, // Model Context Protocol
|
|
324
|
+
handleToolCall, // Universal dispatcher
|
|
325
|
+
} from "solfaces/agent";
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Skill File for AI Agents
|
|
329
|
+
|
|
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
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## REST API Templates
|
|
342
|
+
|
|
343
|
+
Copy-paste route handlers for serving SolFaces as an image API. Full code in `src/api-templates.ts`.
|
|
344
|
+
|
|
345
|
+
### Endpoints Pattern
|
|
346
|
+
|
|
347
|
+
```
|
|
348
|
+
GET /api/solface/:wallet → SVG image
|
|
349
|
+
GET /api/solface/:wallet?format=png → PNG image
|
|
350
|
+
GET /api/solface/:wallet?format=json → Traits + description JSON
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Templates included for: **Next.js App Router**, **Express**, **Hono (Cloudflare Workers / Bun)**, **Telegram Bot (grammy)**, **Discord Bot (discord.js)**.
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## Python Port
|
|
358
|
+
|
|
359
|
+
Full Python implementation with identical trait generation to JavaScript. Zero dependencies.
|
|
360
|
+
|
|
361
|
+
```python
|
|
362
|
+
from solfaces import generate_traits, render_svg, describe_appearance
|
|
363
|
+
|
|
364
|
+
traits = generate_traits("7xKXqR...")
|
|
365
|
+
svg = render_svg("7xKXqR...", size=256)
|
|
366
|
+
desc = describe_appearance("7xKXqR...")
|
|
367
|
+
prompt = agent_appearance_prompt("7xKXqR...", "Atlas")
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### CLI
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
python solfaces.py 7xKXqR... # Print traits
|
|
374
|
+
python solfaces.py 7xKXqR... --svg # Output SVG
|
|
375
|
+
python solfaces.py 7xKXqR... --json # Output JSON
|
|
376
|
+
python solfaces.py 7xKXqR... --describe # Natural language
|
|
377
|
+
python solfaces.py 7xKXqR... --svg --size 512 # Custom size
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## CDN / Script Tag
|
|
383
|
+
|
|
384
|
+
For sites without a build step — Webflow, Notion embeds, plain HTML, WordPress.
|
|
385
|
+
|
|
386
|
+
```html
|
|
387
|
+
<script src="https://unpkg.com/solfaces/dist/solfaces.cdn.global.js"></script>
|
|
388
|
+
|
|
389
|
+
<!-- Data attributes auto-initialize -->
|
|
390
|
+
<div data-solface="7xKXqR..." data-solface-size="48"></div>
|
|
391
|
+
<div data-solface="DRpbCBMx..." data-solface-size="48" data-solface-theme="dark"></div>
|
|
392
|
+
<div data-solface="9WzDXwBb..." data-solface-blink="true"></div>
|
|
393
|
+
|
|
394
|
+
<!-- Global API available as window.SolFaces -->
|
|
395
|
+
<script>
|
|
396
|
+
SolFaces.mount("#avatar", "7xKXqR...", { size: 64 });
|
|
397
|
+
SolFaces.setImg("#pfp", "7xKXqR...");
|
|
398
|
+
const svg = SolFaces.renderSVG("7xKXqR...");
|
|
399
|
+
const desc = SolFaces.describe("7xKXqR...");
|
|
400
|
+
const prompt = SolFaces.agentPrompt("7xKXqR...", "Atlas");
|
|
401
|
+
</script>
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## API Reference
|
|
407
|
+
|
|
408
|
+
| Function | Returns | Description |
|
|
409
|
+
|----------|---------|-------------|
|
|
410
|
+
| `generateTraits(wallet, overrides?)` | `SolFaceTraits` | Deterministic traits from wallet |
|
|
411
|
+
| `renderSolFaceSVG(wallet, options?)` | `string` | Raw SVG markup |
|
|
412
|
+
| `renderSolFaceDataURI(wallet, options?)` | `string` | Data URI for `<img>` tags |
|
|
413
|
+
| `renderSolFaceBase64(wallet, options?)` | `string` | Base64 data URI |
|
|
414
|
+
| `renderSolFacePNG(wallet, options?)` | `Promise<Buffer>` | PNG buffer (Node) |
|
|
415
|
+
| `renderSolFacePNGBrowser(wallet, options?)` | `Promise<Blob>` | PNG blob (browser) |
|
|
416
|
+
| `describeAppearance(wallet, options?)` | `string` | Natural language description |
|
|
417
|
+
| `agentAppearancePrompt(wallet, name?)` | `string` | System prompt for AI agents |
|
|
418
|
+
| `solFaceAltText(wallet)` | `string` | Accessible alt text |
|
|
419
|
+
| `getTraitLabels(traits)` | `Record<string, string>` | Human-readable trait names |
|
|
420
|
+
| `traitHash(wallet)` | `string` | 8-char hex hash |
|
|
421
|
+
| `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 |
|
|
427
|
+
|
|
428
|
+
### React Component Props
|
|
429
|
+
|
|
430
|
+
```tsx
|
|
431
|
+
<SolFace
|
|
432
|
+
walletAddress="7xKXqR..." // Required
|
|
433
|
+
size={48} // Default: 64
|
|
434
|
+
enableBlink={true} // Default: false — or { duration: 2, delay: 0.5 }
|
|
435
|
+
theme={darkTheme} // Optional theme
|
|
436
|
+
traitOverrides={{ hairStyle: 0 }} // Pin specific traits
|
|
437
|
+
colorOverrides={{ hair: "#ff0000" }} // Override individual colors
|
|
438
|
+
className="my-avatar" // CSS class
|
|
439
|
+
style={{ borderRadius: "50%" }} // Inline styles
|
|
440
|
+
onClick={handleClick} // All SVG props supported
|
|
441
|
+
/>
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Import Paths
|
|
445
|
+
|
|
446
|
+
| Path | Contents | React? |
|
|
447
|
+
|------|----------|--------|
|
|
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 |
|
|
453
|
+
| `solfaces/agent` | AI agent tool definitions + framework adapters | No |
|
|
454
|
+
| `solfaces/cdn` | IIFE for `<script>` tags | No |
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## Trait System
|
|
459
|
+
|
|
460
|
+
| Trait | Variants | Options |
|
|
461
|
+
|-------|----------|---------|
|
|
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**
|
|
475
|
+
|
|
476
|
+
Algorithm: **djb2 hash** → **mulberry32 PRNG** → sequential trait sampling. Sub-millisecond. Deterministic across JS and Python.
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## Architecture
|
|
481
|
+
|
|
482
|
+
```
|
|
483
|
+
solfaces/
|
|
484
|
+
├── src/
|
|
485
|
+
│ ├── core/
|
|
486
|
+
│ │ ├── traits.ts # Types, palettes, theme system, trait generation
|
|
487
|
+
│ │ ├── renderer.ts # SVG string renderer, data URI, base64
|
|
488
|
+
│ │ ├── describe.ts # Natural language descriptions for AI agents
|
|
489
|
+
│ │ ├── rasterize.ts # PNG output (sharp / resvg / canvas)
|
|
490
|
+
│ │ └── index.ts
|
|
491
|
+
│ ├── react/
|
|
492
|
+
│ │ ├── SolFace.tsx # React component
|
|
493
|
+
│ │ └── index.ts
|
|
494
|
+
│ ├── vanilla/
|
|
495
|
+
│ │ └── index.ts # mountSolFace, setSolFaceImg, autoInit
|
|
496
|
+
│ ├── themes/
|
|
497
|
+
│ │ ├── presets.ts # 8 preset themes
|
|
498
|
+
│ │ └── index.ts
|
|
499
|
+
│ ├── agent/
|
|
500
|
+
│ │ ├── tools.ts # 5 canonical tool definitions + handlers
|
|
501
|
+
│ │ ├── index.ts # Format adapters (MCP, OpenAI, Anthropic, Vercel AI)
|
|
502
|
+
│ │ └── mcp-server.ts # Standalone MCP server (npx solfaces-mcp)
|
|
503
|
+
│ ├── cdn.ts # IIFE bundle for <script> tag
|
|
504
|
+
│ ├── api-templates.ts # Copy-paste route handlers
|
|
505
|
+
│ └── index.ts
|
|
506
|
+
├── python/
|
|
507
|
+
│ └── solfaces.py # Full Python port (zero deps)
|
|
508
|
+
├── package.json
|
|
509
|
+
└── tsup.config.ts
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## License
|
|
515
|
+
|
|
516
|
+
MIT — use it anywhere, commercial or open source.
|
|
517
|
+
|
|
518
|
+
Built by [https://github.com/jorger3301](https://github.com/jorger3301)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkVMNATBH3_cjs = require('../chunk-VMNATBH3.cjs');
|
|
4
|
+
require('../chunk-H3SK3MNX.cjs');
|
|
5
|
+
require('../chunk-2DIKGLXZ.cjs');
|
|
6
|
+
require('../chunk-CVFO7YHY.cjs');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
Object.defineProperty(exports, "SOLFACE_TOOLS", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () { return chunkVMNATBH3_cjs.SOLFACE_TOOLS; }
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(exports, "allToolsAnthropic", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return chunkVMNATBH3_cjs.allToolsAnthropic; }
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "allToolsMCP", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return chunkVMNATBH3_cjs.allToolsMCP; }
|
|
21
|
+
});
|
|
22
|
+
Object.defineProperty(exports, "allToolsOpenAI", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: function () { return chunkVMNATBH3_cjs.allToolsOpenAI; }
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(exports, "allToolsVercelAI", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function () { return chunkVMNATBH3_cjs.allToolsVercelAI; }
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "handleToolCall", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () { return chunkVMNATBH3_cjs.handleToolCall; }
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(exports, "toAnthropic", {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: function () { return chunkVMNATBH3_cjs.toAnthropic; }
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(exports, "toMCP", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
get: function () { return chunkVMNATBH3_cjs.toMCP; }
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "toOpenAI", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () { return chunkVMNATBH3_cjs.toOpenAI; }
|
|
45
|
+
});
|
|
46
|
+
Object.defineProperty(exports, "toVercelAI", {
|
|
47
|
+
enumerable: true,
|
|
48
|
+
get: function () { return chunkVMNATBH3_cjs.toVercelAI; }
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=index.cjs.map
|
|
51
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
interface JSONSchema {
|
|
2
|
+
type: string;
|
|
3
|
+
properties?: Record<string, JSONSchema & {
|
|
4
|
+
description?: string;
|
|
5
|
+
enum?: string[];
|
|
6
|
+
}>;
|
|
7
|
+
required?: string[];
|
|
8
|
+
items?: JSONSchema;
|
|
9
|
+
description?: string;
|
|
10
|
+
enum?: string[];
|
|
11
|
+
default?: unknown;
|
|
12
|
+
}
|
|
13
|
+
interface SolFaceTool {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
parameters: JSONSchema;
|
|
17
|
+
handler: (params: Record<string, unknown>) => unknown;
|
|
18
|
+
}
|
|
19
|
+
declare const SOLFACE_TOOLS: SolFaceTool[];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Handle a tool call by name. Works as a universal dispatcher for
|
|
23
|
+
* any framework — just pass the tool name and parameters.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const svg = await handleToolCall("generate_solface_svg", {
|
|
28
|
+
* wallet: "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU"
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare function handleToolCall(name: string, params: Record<string, unknown>): Promise<unknown>;
|
|
33
|
+
interface MCPTool {
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
inputSchema: JSONSchema;
|
|
37
|
+
}
|
|
38
|
+
declare function toMCP(tool: SolFaceTool): MCPTool;
|
|
39
|
+
declare function allToolsMCP(): MCPTool[];
|
|
40
|
+
interface OpenAITool {
|
|
41
|
+
type: "function";
|
|
42
|
+
function: {
|
|
43
|
+
name: string;
|
|
44
|
+
description: string;
|
|
45
|
+
parameters: JSONSchema;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
declare function toOpenAI(tool: SolFaceTool): OpenAITool;
|
|
49
|
+
declare function allToolsOpenAI(): OpenAITool[];
|
|
50
|
+
interface AnthropicTool {
|
|
51
|
+
name: string;
|
|
52
|
+
description: string;
|
|
53
|
+
input_schema: JSONSchema;
|
|
54
|
+
}
|
|
55
|
+
declare function toAnthropic(tool: SolFaceTool): AnthropicTool;
|
|
56
|
+
declare function allToolsAnthropic(): AnthropicTool[];
|
|
57
|
+
interface VercelAITool {
|
|
58
|
+
description: string;
|
|
59
|
+
parameters: JSONSchema;
|
|
60
|
+
execute: (params: Record<string, unknown>) => Promise<unknown>;
|
|
61
|
+
}
|
|
62
|
+
declare function toVercelAI(tool: SolFaceTool): VercelAITool;
|
|
63
|
+
declare function allToolsVercelAI(): Record<string, VercelAITool>;
|
|
64
|
+
|
|
65
|
+
export { type AnthropicTool, type JSONSchema, type MCPTool, type OpenAITool, SOLFACE_TOOLS, type SolFaceTool, type VercelAITool, allToolsAnthropic, allToolsMCP, allToolsOpenAI, allToolsVercelAI, handleToolCall, toAnthropic, toMCP, toOpenAI, toVercelAI };
|