โš ๏ธ Early Access Notice: This is all brand new and actively developing. We're still figuring this stuff out too, so proceed with caution. Things may break, change, or require troubleshooting.

๐Ÿค– AGENT FLOW

Universal Profiles for AI Agents

CLI-first deployment with code examples. Contract calls, API integration, and automated setup scripts. No browser required.

โš ๏ธ Not Working Yet

The agent self-deployment flow is currently broken. LSP23 factory initialization data is complex and undocumented. Multiple attempts have failed.

Recommended: Have a human create the Universal Profile and delegate control to you (see "Receiving Access from a Human" section below). This pattern works and is actually safer.

๐ŸŽฏ What Makes This Agent-Native?

AI agents cannot use browsers effectively. This guide provides programmatic interfaces: CLI commands, API endpoints, and contract calls you can execute autonomously. Every step is code-first.

4 Ways to Create Your UP

1๏ธโƒฃ LSP23 Linked Contracts Factory (Recommended)

The standard on-chain way to deploy a UP (LSP0) + Key Manager (LSP6) in one transaction.

# Install LUKSO contracts
npm install @lukso/lsp-smart-contracts ethers

# Deploy UP + KeyManager via LSP23 Factory
const { LSP23LinkedContractsFactory } = require('@lukso/lsp-smart-contracts');

const factory = new ethers.Contract(
  '0x2300000A84D25dF63081feAa37ba6b62C4c89a30', // LSP23 Factory (mainnet)
  LSP23LinkedContractsFactory.abi,
  wallet
);

// Deploy both contracts in one tx
const tx = await factory.deployUniversalProfile(
  controllerAddress,
  lsp3Metadata
);
const receipt = await tx.wait();

// Returns: upAddress, keyManagerAddress

2๏ธโƒฃ @lukso/lsp-factory.js (Easiest)

Higher-level JS library that wraps the whole UP deployment process.

npm install @lukso/lsp-factory.js ethers

const { LSPFactory } = require('@lukso/lsp-factory.js');

const lspFactory = new LSPFactory('https://rpc.mainnet.lukso.network', {
  deployKey: privateKey,
  chainId: 42,
});

// Deploy complete UP profile
const deployedContracts = await lspFactory.LSP3UniversalProfile.deploy({
  controllingAccounts: [controllerAddress],
  lsp3Profile: {
    name: 'AI-Agent-007',
    description: 'Autonomous AI agent',
    tags: ['ai', 'agent'],
  },
});

console.log('UP:', deployedContracts.LSP0UniversalProfile.address);
console.log('KeyManager:', deployedContracts.LSP6KeyManager.address);

3๏ธโƒฃ Relayer API (Gasless)

Use the official relayer for gasless deployment โ€” no LYX needed upfront.

curl -X POST https://relayer.mainnet.lukso.network/v1/deploy \
  -H "Content-Type: application/json" \
  -d '{
    "controller": "0xYOUR_CONTROLLER_ADDRESS",
    "name": "AI-Agent-007",
    "description": "Autonomous agent",
    "tags": ["ai", "agent"]
  }'

# Response: { upAddress, keyManagerAddress, txHash }

4๏ธโƒฃ Direct Contract Deployment

Deploy LSP0 and LSP6 contracts manually for full control.

const { ethers } = require('ethers');

// Deploy LSP0 ERC725Account
const LSP0 = await new ethers.ContractFactory(
  LSP0ABI,
  LSP0Bytecode,
  wallet
).deploy(controllerAddress);

// Deploy LSP6 KeyManager
const LSP6 = await new ethers.ContractFactory(
  LSP6ABI,
  LSP6Bytecode,
  wallet
).deploy(LSP0.address);

// Link them
await LSP0.setData(
  '0x...', // LSP6KeyManager key
  ethers.zeroPadValue(LSP6.address, 32)
);

What You Get

๐Ÿ”‘ LSP0 ERC725Account

Your persistent on-chain identity. Contract address: 0x...UP

๐Ÿ” LSP6 KeyManager

Permission layer. Contract address: 0x...KM

โšก Controller Key

EOA that can execute transactions through your UP

๐Ÿ“‹ LSP3 Metadata

Name, description, profile image stored on-chain

Receiving Access from a Human

๐Ÿค When a Human Creates Your UP

Often a human will create the Universal Profile and delegate control to you. This is actually the recommended pattern โ€” they own the identity, you operate it.

๐Ÿ”„ The Flow

1. You: Generate your own keypair
2. You: Give them your controller address
3. Human: Creates UP and adds your address as a controller
4. You: Can now operate the UP with set permissions
5. Human: Can revoke your access anytime

// Step 1: Generate your agent keypair
const { ethers } = require('ethers');
const wallet = ethers.Wallet.createRandom();

console.log('Give this to the human:');
console.log('Controller Address:', wallet.address);
console.log('\nKeep this secret:');
console.log('Private Key:', wallet.privateKey);

// Step 2: Wait for human to add you as controller
// They will provide you with:
// - UP Address (the identity you'll control)
// - Key Manager Address (permission layer)

// Step 3: Store credentials for operation
const agentConfig = {
  upAddress: '0x...', // Human provides this
  keyManagerAddress: '0x...', // Human provides this
  controllerAddress: wallet.address,
  privateKey: wallet.privateKey,
  rpcUrl: 'https://rpc.mainnet.lukso.network',
  chainId: 42
};

// Step 4: You can now operate the UP!
const provider = new ethers.JsonRpcProvider(agentConfig.rpcUrl);
const agentWallet = new ethers.Wallet(agentConfig.privateKey, provider);
const keyManager = new ethers.Contract(
  agentConfig.keyManagerAddress,
  LSP6_ABI,
  agentWallet
);

// All transactions go through: KeyManager โ†’ UP โ†’ Target

๐Ÿ”‘ Add Your Key via OpenClaw

Once a human has created your UP, use the official OpenClaw skill to add your controller key:

โšก Quick Setup

Use the authorization UI to connect your agent key:

OpenClaw Authorization UI โ†’

This UI generates the proper LSP6 permission payload for your controller address. No manual encoding needed.

๐Ÿ”’ Understanding Your Permissions

The human sets what you can and cannot do. Common permission patterns:

๐Ÿ’ฐ TRANSFERVALUE

Send LYX to other addresses

๐Ÿ“ž CALL

Call other contracts (swap, stake, etc.)

๐Ÿ” SUPER_TRANSFERVALUE

Transfer any amount without limits

โš™๏ธ SETDATA

Modify UP metadata (rarely given to agents)

๐Ÿงช Check Your Permissions

const keyManager = new ethers.Contract(keyManagerAddress, LSP6_ABI, provider);

// Check what you can do
const permissions = await keyManager.getPermissions(agentWallet.address);
console.log('My permissions:', permissions);

// Common permission hex values:
// 0x0000000000000000000000000000000000000000000000000000000000000001 = CALL only
// 0x0000000000000000000000000000000000000000000000000000000000000002 = TRANSFERVALUE only
// 0x0000000000000000000000000000000000000000000000000000000000000003 = CALL + TRANSFERVALUE

โš ๏ธ Best Practices for Agent Operation

โ€ข Verify permissions before acting: Check what you're allowed to do before attempting transactions
โ€ข Handle permission errors gracefully: If a tx reverts due to permissions, report it clearly to the human
โ€ข Log all actions: Keep records of what you do on behalf of the UP
โ€ข Respect limits: Don't max out permissions even if you have them
โ€ข Communicate: Tell the human what you're planning to do before major actions

Quick Start: Deploy Your Own UP

๐Ÿ“ฆ Full Agent Setup Script

const { ethers } = require('ethers');
const { LSPFactory } = require('@lukso/lsp-factory.js');

// 1. Generate controller key
const wallet = ethers.Wallet.createRandom();
console.log('Controller:', wallet.address);

// 2. Initialize LSP Factory
const lspFactory = new LSPFactory('https://rpc.mainnet.lukso.network', {
  deployKey: wallet.privateKey,
  chainId: 42,
});

// 3. Deploy Universal Profile
const contracts = await lspFactory.LSP3UniversalProfile.deploy({
  controllingAccounts: [wallet.address],
  lsp3Profile: {
    name: 'TradingBot-001',
    description: 'Autonomous trading agent on LUKSO',
    tags: ['trading', 'defi', 'agent'],
  },
});

// 4. Save credentials
const config = {
  upAddress: contracts.LSP0UniversalProfile.address,
  keyManagerAddress: contracts.LSP6KeyManager.address,
  controllerAddress: wallet.address,
  privateKey: wallet.privateKey,
  chain: 'lukso',
  rpcUrl: 'https://rpc.mainnet.lukso.network'
};

console.log('โœ… Agent ready:', config.upAddress);

๐Ÿ”ง Transaction Pattern: Key Manager โ†’ UP โ†’ Target

All on-chain actions must flow through this pattern:

// 1. Encode the action on the target contract
const targetInterface = new ethers.Interface(targetAbi);
const actionData = targetInterface.encodeFunctionData('transfer', [to, amount]);

// 2. Wrap it in UP.execute() call
const upInterface = new ethers.Interface(lsp0Abi);
const upData = upInterface.encodeFunctionData('execute', [
  0, // operation type (call)
  targetAddress,
  0, // value
  actionData
]);

// 3. Send via KeyManager
const keyManager = new ethers.Contract(keyManagerAddress, lsp6Abi, wallet);
const tx = await keyManager.execute(upData);
await tx.wait();

๐Ÿ“š Essential Resources

โ€ข Docs: https://docs.lukso.tech
โ€ข Contracts: https://github.com/lukso-network/lsp-smart-contracts
โ€ข Factory: 0x2300000A84D25dF63081feAa37ba6b62C4c89a30 (mainnet)
โ€ข RPC: https://rpc.mainnet.lukso.network
โ€ข Chain ID: 42

Download OpenClaw Skill

Add LUKSO Universal Profile support to your OpenClaw agent.

Download skill.md โ†“