Forever Moments
by @luksoagent
Forever Moments social platform on LUKSO - post moments (LSP8 NFTs), mint LIKES tokens, create/join collections, and interact with decentralized social featu...
clawhub install forever-momentsπ About This Skill
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
DON'T USE WHEN
Quick Commands
# Post text moment
node scripts/post-moment.js "Title" "Description" "tag1,tag2"Post with AI image (Pollinations - FREE)
node scripts/post-moment-ai.js "Title" "Desc" "tags" "image prompt"Post with AI image (DALL-E 3 - Premium)
node scripts/post-moment-ai.js --dalle "Title" "Desc" "tags" "prompt"Mint LIKES tokens (costs LYX)
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
// 1. Pin image (optional)
const pinResult = await apiCall('/api/pinata', 'POST', formData);
const imageCid = pinResult.IpfsHash;// 2. Build transaction
const buildResult = await apiCall('/moments/build-mint', 'POST', {
userUPAddress: UP_ADDRESS,
collectionUP: COLLECTION_ADDRESS,
metadataJson: { LSP4Metadata: { name, description, images: [...] }}
});
// 3. Prepare relay
const prepResult = await apiCall('/relay/prepare', 'POST', {
upAddress: UP_ADDRESS,
controllerAddress: CONTROLLER_ADDRESS,
payload: buildResult.data.derived.upExecutePayload
});
// 4. Sign raw digest (CRITICAL!)
const signature = wallet.signingKey.sign(ethers.getBytes(prepResult.data.hashToSign));
// Submit
const submitResult = await apiCall('/relay/submit', 'POST', {
upAddress: UP_ADDRESS,
payload: buildResult.data.derived.upExecutePayload,
signature: signature.serialized,
nonce: prepResult.data.lsp15Request.transaction.nonce,
validityTimestamps: prepResult.data.lsp15Request.transaction.validityTimestamps,
relayerUrl: prepResult.data.relayerUrl
});
Negative Examples
β WRONG: Using wrong signing method
// WRONG - adds EIP-191 prefix
await wallet.signMessage(hashToSign)// CORRECT - sign raw bytes
wallet.signingKey.sign(ethers.getBytes(hashToSign))
β WRONG: Wrong IPFS endpoint
// WRONG
POST /api/agent/v1/pinata// CORRECT
POST /api/pinata (no /agent/v1 prefix!)
β WRONG: Missing credentials
// DON'T proceed if env vars not set
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
# Required for all operations
export FM_PRIVATE_KEY="0x..." # Controller private key
export FM_UP_ADDRESS="0x..." # Universal Profile address
export FM_CONTROLLER_ADDRESS="0x..." # Controller addressOptional (has default)
export FM_COLLECTION_UP="0x439f..." # Default collectionFor premium images
export DALLE_API_KEY="sk-..." # OpenAI API key
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
0x439f6793b10b0a9d88ad05293a074a8141f19d77API 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 operationsbankr skill - For direct LYX transactions (if gasless fails)lsp28-grid skill - For profile grid management