universal-profile
Manage LUKSO Universal Profiles — identity, permissions, tokens, and blockchain operations via direct or gasless relay transactions
Install
mkdir -p .claude/skills/universal-profile && curl -L -o skill.zip "https://mcp.directory/api/skills/download/6943" && unzip -o skill.zip -d .claude/skills/universal-profile && rm skill.zipInstalls to .claude/skills/universal-profile
About this skill
Universal Profile Skill
Authorize your bot: create a profile at my.universalprofile.cloud, generate a controller key, authorize via Authorization UI.
Core Concepts
- UP (Universal Profile) = smart contract account (LSP0/ERC725Account). This is the on-chain identity.
- KeyManager (LSP6) = access control. Controllers have permission bitmasks.
- Controller = EOA with permissions to act on behalf of the UP.
- All calls to external contracts MUST route through UP via
execute()somsg.sender= UP address. - Exception:
setData()/setDataBatch()can be called directly on UP (checks permissions internally).
Execution Models
Direct (all chains — controller pays gas)
Controller → UP.execute(operation, target, value, data) → Target
The controller calls execute() directly on the UP contract. The UP internally verifies permissions via its KeyManager (LSP20 lsp20VerifyCall). Do NOT call the KeyManager's execute() function directly. Always call the UP.
Gasless Relay (LUKSO ONLY — chains 42/4201)
Controller signs LSP25 → Relay API submits → KeyManager.executeRelayCall() → UP
The controller signs a message, then the LUKSO relay service submits the transaction. Do NOT call executeRelayCall() yourself — the relay API does this.
⚠️ CRITICAL: The relay/gasless option exists ONLY on LUKSO mainnet (42) and testnet (4201). On Base, Ethereum, and all other chains, the controller must hold native ETH and pay gas directly. There is no gasless alternative.
Typical gas costs: LUKSO ~free via relay, Base ~$0.001-0.01/tx, Ethereum ~$0.10-1.00/tx.
Networks
| Chain | ID | RPC | Explorer | Relay | Token |
|---|---|---|---|---|---|
| LUKSO | 42 | https://42.rpc.thirdweb.com | https://explorer.lukso.network | https://relayer.mainnet.lukso.network/api | LYX |
| LUKSO Testnet | 4201 | https://rpc.testnet.lukso.network | https://explorer.testnet.lukso.network | https://relayer.testnet.lukso.network/api | LYXt |
| Base | 8453 | https://mainnet.base.org | https://basescan.org | ❌ | ETH |
| Ethereum | 1 | https://eth.llamarpc.com | https://etherscan.io | ❌ | ETH |
CLI
up status # Config, keys, connectivity
up profile info [<address>] [--chain <chain>] # Profile details
up profile configure <address> [--chain lukso] # Save UP for use
up key generate [--save] [--password <pw>] # Generate controller keypair
up permissions encode <perm1> [<perm2> ...] # Encode to bytes32
up permissions decode <hex> # Decode to names
up permissions presets # List presets
up authorize url [--permissions <preset|hex>] # Generate auth URL
up quota # Check relay gas quota (LUKSO only)
Presets: read-only 🟢 | token-operator 🟡 | nft-trader 🟡 | defi-trader 🟠 | profile-manager 🟡 | full-access 🔴
Credentials
Config lookup order: UP_CREDENTIALS_PATH env → ~/.openclaw/universal-profile/config.json → ~/.clawdbot/universal-profile/config.json
Key lookup order: UP_KEY_PATH env → ~/.openclaw/credentials/universal-profile-key.json → ~/.clawdbot/credentials/universal-profile-key.json
Canonical path for new credentials: ~/.openclaw/credentials/universal-profile-key.json
Skill config path: ~/.openclaw/skills/universal-profile/config.json
Expected JSON format:
{
"universalProfile": {
"address": "0xYourUniversalProfileAddress"
},
"controller": {
"address": "0xYourControllerAddress",
"privateKey": "0xYourPrivateKey"
}
}
Key file permissions: chmod 600. Keys loaded only for signing, then cleared. The skill warns if credential files are readable by group/others.
Permissions (bytes32 BitArray)
| Permission | Hex | Risk | Notes |
|---|---|---|---|
| CHANGEOWNER | 0x01 | 🔴 | |
| ADDCONTROLLER | 0x02 | 🟠 | |
| EDITPERMISSIONS | 0x04 | 🟠 | |
| ADDEXTENSIONS | 0x08 | 🟡 | |
| CHANGEEXTENSIONS | 0x10 | 🟡 | |
| ADDUNIVERSALRECEIVERDELEGATE | 0x20 | 🟡 | |
| CHANGEUNIVERSALRECEIVERDELEGATE | 0x40 | 🟡 | |
| REENTRANCY | 0x80 | 🟡 | |
| SUPER_TRANSFERVALUE | 0x0100 | 🟠 | Any recipient |
| TRANSFERVALUE | 0x0200 | 🟡 | AllowedCalls only |
| SUPER_CALL | 0x0400 | 🟠 | Any contract |
| CALL | 0x0800 | 🟡 | AllowedCalls only |
| SUPER_STATICCALL | 0x1000 | 🟢 | |
| STATICCALL | 0x2000 | 🟢 | |
| SUPER_DELEGATECALL | 0x4000 | 🔴 | |
| DELEGATECALL | 0x8000 | 🔴 | |
| DEPLOY | 0x010000 | 🟡 | |
| SUPER_SETDATA | 0x020000 | 🟠 | Any key |
| SETDATA | 0x040000 | 🟡 | AllowedERC725YDataKeys only |
| ENCRYPT | 0x080000 | 🟢 | |
| DECRYPT | 0x100000 | 🟢 | |
| SIGN | 0x200000 | 🟢 | |
| EXECUTE_RELAY_CALL | 0x400000 | 🟢 |
SUPER variants = unrestricted. Regular = restricted to AllowedCalls/AllowedERC725YDataKeys. Prefer restricted.
Transactions
Direct Execution (all chains)
// Controller calls UP.execute() directly — works on LUKSO, Base, Ethereum
const provider = new ethers.JsonRpcProvider(rpcUrl); // use correct RPC for chain
const wallet = new ethers.Wallet(controllerPrivateKey, provider);
const up = new ethers.Contract(upAddress, ['function execute(uint256,address,uint256,bytes) payable returns (bytes)'], wallet);
await (await up.execute(0, recipient, ethers.parseEther('0.01'), '0x')).wait();
Gasless Relay (LUKSO only)
LSP25 Relay Signature — EIP-191 v0, do NOT use signMessage():
const encoded = ethers.solidityPacked(
['uint256','uint256','uint256','uint256','uint256','bytes'],
[25, chainId, nonce, validityTimestamps, msgValue, payload]
);
const prefix = new Uint8Array([0x19, 0x00]);
const msg = new Uint8Array([...prefix, ...ethers.getBytes(kmAddress), ...ethers.getBytes(encoded)]);
const signature = ethers.Signature.from(new ethers.SigningKey(privateKey).sign(ethers.keccak256(msg))).serialized;
Relay API:
POST https://relayer.mainnet.lukso.network/api/execute
{ "address": "0xUP", "transaction": { "abi": "0xpayload", "signature": "0x...", "nonce": 0, "validityTimestamps": "0x0" } }
The payload for relay calls is the full UP.execute(...) calldata. The relay service calls KeyManager.executeRelayCall() — you never call the KM directly.
For setData via relay, the payload is the setData(...) calldata (NOT wrapped in execute()).
Nonce channels: getNonce(controller, channelId) — same channel = sequential, different = parallel.
Validity timestamps: (startTimestamp << 128) | endTimestamp. Use 0 for no restriction.
Cross-Chain Deployment (LSP23)
UPs can be redeployed at the same address on other chains by replaying the original LSP23 factory calldata.
Factory & Implementations (identical addresses on LUKSO, Base, Ethereum)
| Contract | Address |
|---|---|
| LSP23 Factory | 0x2300000A84D25dF63081feAa37ba6b62C4c89a30 |
| UniversalProfileInit v0.14.0 | 0x3024D38EA2434BA6635003Dc1BDC0daB5882ED4F |
| LSP6KeyManagerInit v0.14.0 | 0x2Fe3AeD98684E7351aD2D408A43cE09a738BF8a4 |
| PostDeploymentModule | 0x000000000066093407b6704B89793beFfD0D8F00 |
Workflow
- Retrieve original deployment calldata:
node commands/cross-chain-deploy-data.js <upAddress> [--verify] - Fund controller with ETH on target chain
- Submit same calldata to factory:
wallet.sendTransaction({ to: factoryAddress, data: calldata, value: 0n }) - Authorize controller on new chain via Authorization UI (permissions are per-chain)
Limitations
- Legacy UPs (pre-LSP23, old lsp-factory) have no deployment events
- Determinism requires identical salt + implementations + init data
LSP Ecosystem
| LSP | Interface ID | Name | Purpose |
|---|---|---|---|
| LSP0 | 0x24871b3d | ERC725Account | Smart contract account (UP) |
| LSP1 | 0x6bb56a14 | UniversalReceiver | Notification hooks |
| LSP2 | — | ERC725Y JSON Schema | Key encoding |
| LSP3 | — | Profile Metadata | Name, avatar, links, tags |
| LSP4 | — | Digital Asset Metadata | Token name, symbol, type |
| LSP5 | — | ReceivedAssets | Tracks owned tokens/NFTs |
| LSP6 | 0x23f34c62 | KeyManager | Permission-based access control |
| LSP7 | 0xc52d6008 | DigitalAsset | Fungible tokens (like ERC20) |
| LSP8 | 0x3a271706 | IdentifiableDigitalAsset | NFTs (bytes32 token IDs) |
| LSP9 | 0x28af17e6 | Vault | Sub-account for asset segregation |
| LSP14 | 0x94be5999 | Ownable2Step | Two-step ownership transfer |
| LSP25 | 0x5ac79908 | ExecuteRelayCall | Gasless meta-transactions (LUKSO only) |
| LSP26 | 0x2b299cea | FollowerSystem | On-chain follow/unfollow |
| LSP28 | — | TheGrid | Customizable profile grid layouts |
Full ABIs, interface IDs, and ERC725Y data keys in lib/constants.js.
LSP26 Follow/Unfollow
Contract: 0xf01103E5a9909Fc0DBe8166dA7085e0285daDDcA (LUKSO mainnet).
MUST route through UP via execute() — never call directly from controller.
const followData = lsp26Iface.encodeFunctionData('follow', [targetAddress]);
// Direct: km.execute(up.encodeFunctionData('execute', [0, LSP26_ADDR, 0, followData]))
// Relay: sign + submit via relay API
VerifiableURI (LSP2)
Format: 0x + 00006f357c6a0020 (8-byte header) + keccak256hash (32 bytes) + url as UTF-8 hex
Header = verificationMethod(2) + hashFunction(4=keccak256(utf8)) + hashLength(2=0x0020).
Decoding: skip 80 hex chars (2 + 8 + 4 + 64 + 2 prefix), rest = UTF-8 URL.
Common mistakes: forgetting 0020 hash length bytes, not pinning IPFS before on-chain tx, hash mismatch from re-serialization.
LSP3 Profile Update Procedure
- Read current:
getData(0x5ef83ad9559033e6e941db7d7c495acdce616347d28e90c7ce47cbfcfcad3bc5)→ decode VerifiableURI → fetch JSON - Modify JSON
- Use
{ verification: { method: "keccak256(bytes)", data: "0x..." }, url: "ipfs://..." }for images - Pin images + JSON to IPFS, verify accessible via gateway
- Compute `keccak256(exactJson
Content truncated.
More by openclaw
View all skills by openclaw →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversEnhance software testing with Playwright MCP: Fast, reliable browser automation, an innovative alternative to Selenium s
Securely manage Clerk authentication, users, sessions, orgs, and authorization for seamless identity and access control.
Integrate your Slack app to manage channels, messages, status on Slack, reactions, and user profiles securely via OAuth.
Bridge AI with the LinkedIn API to auto connect, manage profiles, and integrate with Pipedrive for powerful prospecting
Leverage LinkedIn API to automate connections, search profiles, manage posts, and enhance sales or recruitment using pow
Keycloak Admin plugin enables seamless user and realm management for automated identity and access control solutions.
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.