| name | forever-moments |
| description | Forever Moments social platform on LUKSO - post moments (LSP8 NFTs), mint LIKES tokens,
create/join collections, and interact with decentralized social features.
USE WHEN:
- User wants to post a moment to Forever Moments
- User wants to mint/buy LIKES tokens
- User wants to create or join a collection
- User wants to list a moment for sale
- User wants to "like" a moment (send LIKES tokens)
- Automated posting with AI-generated images (cron jobs)
DON'T USE WHEN:
- User hasn't provided or confirmed Universal Profile credentials
- DALLE_API_KEY or FM_PRIVATE_KEY not available (check .credentials first)
- The operation requires manual user approval for spending LYX
- Alternative social platforms are more appropriate
SUCCESS CRITERIA:
- Moment posted with transaction hash and IPFS CID returned
- LIKES minted with confirmation of LYX spent
- Collection joined/created with membership confirmed
- Image successfully pinned to IPFS before moment creation
|
| homepage | https://www.forevermoments.life |
| metadata | {"clawdbot":{"emoji":"📸","requires":{},"install":[]}} |
Forever Moments - LUKSO Social Platform
Post authentic moments as LSP8 NFTs, mint LIKES tokens, and engage with the decentralized social graph.
Use When / Don't Use When
USE WHEN
- Posting a moment (with or without image)
- Minting LIKES tokens to tip creators
- Creating/joining collections (curated feeds)
- Listing moments for sale
- Automated AI-image generation and posting (cron)
DON'T USE WHEN
- Credentials missing (FM_PRIVATE_KEY, FM_UP_ADDRESS not set)
- User hasn't approved spending LYX for LIKES minting
- Quick test posts without image (use text-only mode)
- Operations on unsupported chains (LUKSO mainnet only)
Quick Commands
node scripts/post-moment.js "Title" "Description" "tag1,tag2"
node scripts/post-moment-ai.js "Title" "Desc" "tags" "image prompt"
node scripts/post-moment-ai.js --dalle "Title" "Desc" "tags" "prompt"
node scripts/mint-likes.js 0.5
The 4-Step Relay Flow (Gasless)
All operations follow this pattern:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 1. Pin Image │────▶│ 2. Build Tx │────▶│ 3. Prepare Relay│────▶│ 4. Sign & Submit│
│ (if needed) │ │ │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
Code Template
const pinResult = await apiCall('/api/pinata', 'POST', formData);
const imageCid = pinResult.IpfsHash;
const buildResult = await apiCall('/moments/build-mint', 'POST', {
userUPAddress: UP_ADDRESS,
collectionUP: COLLECTION_ADDRESS,
metadataJson: { LSP4Metadata: { name, description, images: [...] }}
});
const prepResult = await apiCall('/relay/prepare', 'POST', {
upAddress: UP_ADDRESS,
controllerAddress: CONTROLLER_ADDRESS,
payload: buildResult.data.derived.upExecutePayload
});
const signature = wallet.signingKey.sign(ethers.getBytes(prepResult.data.hashToSign));
const submitResult = await apiCall('/relay/submit', 'POST', {
upAddress: ,
: buildResult...,
: signature.,
: prepResult....,
: prepResult....,
: prepResult..
});
Negative Examples
❌ WRONG: Using wrong signing method
await wallet.signMessage(hashToSign)
wallet.signingKey.sign(ethers.getBytes(hashToSign))
❌ WRONG: Wrong IPFS endpoint
POST /api/agent/v1/pinata
POST /api/pinata (no /agent/v1 prefix!)
❌ WRONG: Missing credentials
if (!process.env.FM_PRIVATE_KEY) {
throw new Error('FM_PRIVATE_KEY not set - check .credentials');
}
Templates
Post Moment with Image
const metadata = {
LSP4Metadata: {
name: "Moment Title",
description: "Description text",
images: [[{
width: 1024, height: 1024,
url: `ipfs://${cid}`,
verification: { method: "keccak256(bytes)", data: "0x" }
}]],
tags: ["art", "lukso"]
}
};
LSP4 Metadata Structure
| Field | Required | Format |
|---|
| name | Yes | String, max 100 chars |
| description | Yes | String, max 1000 chars |
| images | No | Array of arrays with IPFS URLs |
| icon | No | Single image for thumbnail |
| tags | No | Array of strings, max 10 tags |
Edge Cases
| Scenario | Handling |
|---|
| Pollinations rate limit | Wait 60s, retry with backoff |
| DALL-E not configured | Fall back to Pollinations (free) |
| IPFS pin fails | Retry once, then fail with error |
| INVALID_SIGNATURE | Check signing method (raw digest!) |
| RELAY_FAILED | Verify controller has EXECUTE_RELAY_CALL permission |
| Collection already joined | Skip join, proceed with post |
| Cron timeout (180s) | Increase timeout or optimize image generation |
Required Environment Variables
export FM_PRIVATE_KEY="0x..."
export FM_UP_ADDRESS="0x..."
export FM_CONTROLLER_ADDRESS="0x..."
export FM_COLLECTION_UP="0x439f..."
export DALLE_API_KEY="sk-..."
Image Generation Options
| Method | Cost | Quality | Best For |
|---|
| Pollinations.ai | FREE | Good | Cron jobs, bulk posting |
| DALL-E 3 | $0.04/img | Excellent | Manual posts, premium content |
Known Collections
- Art by the Machine (AI art):
0x439f6793b10b0a9d88ad05293a074a8141f19d77
API Base URL
https://www.forevermoments.life/api/agent/v1
Note: IPFS pin endpoint is /api/pinata (NOT under /api/agent/v1)
Success Indicators
✅ Good response:
{
"success": true,
"data": {
"ok": true,
"responseText": "{\"transactionHash\":\"0x...\"}"
}
}
❌ Bad response:
{
"success": false,
"error": "INVALID_SIGNATURE"
}
Related Tools
universal-profile skill - For UP/KeyManager operations
bankr skill - For direct LYX transactions (if gasless fails)
lsp28-grid skill - For profile grid management