✓ Verified 💻 Development ✓ Enhanced Data

Forever Moments

Forever Moments social platform on LUKSO - post moments (LSP8 NFTs), mint LIKES tokens, create/join

Rating
4.4 (65 reviews)
Downloads
40,011 downloads
Version
1.0.0

Overview

Forever Moments social platform on LUKSO - post moments (LSP8 NFTs), mint LIKES tokens, create/join collections.

Complete Documentation

View Source →

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

bash
# 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:

text
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  1. Pin Image   │────▶│  2. Build Tx    │────▶│ 3. Prepare Relay│────▶│ 4. Sign & Submit│
│  (if needed)    │     │                 │     │                 │     │                 │
└─────────────────┘     └─────────────────┘     └─────────────────┘     └─────────────────┘

Code Template

javascript
// 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

javascript
// WRONG - adds EIP-191 prefix
await wallet.signMessage(hashToSign)

// CORRECT - sign raw bytes
wallet.signingKey.sign(ethers.getBytes(hashToSign))

WRONG: Wrong IPFS endpoint

javascript
// WRONG
POST /api/agent/v1/pinata

// CORRECT
POST /api/pinata  (no /agent/v1 prefix!)

WRONG: Missing credentials

javascript
// 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

javascript
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

FieldRequiredFormat
nameYesString, max 100 chars
descriptionYesString, max 1000 chars
imagesNoArray of arrays with IPFS URLs
iconNoSingle image for thumbnail
tagsNoArray of strings, max 10 tags

Edge Cases

ScenarioHandling
Pollinations rate limitWait 60s, retry with backoff
DALL-E not configuredFall back to Pollinations (free)
IPFS pin failsRetry once, then fail with error
INVALID_SIGNATURECheck signing method (raw digest!)
RELAY_FAILEDVerify controller has EXECUTE_RELAY_CALL permission
Collection already joinedSkip join, proceed with post
Cron timeout (180s)Increase timeout or optimize image generation

Required Environment Variables

bash
# 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 address

# Optional (has default)
export FM_COLLECTION_UP="0x439f..."     # Default collection

# For premium images
export DALLE_API_KEY="sk-..."           # OpenAI API key

Image Generation Options

MethodCostQualityBest For
Pollinations.aiFREEGoodCron jobs, bulk posting
DALL-E 3$0.04/imgExcellentManual posts, premium content

Known Collections

  • Art by the Machine (AI art): 0x439f6793b10b0a9d88ad05293a074a8141f19d77

API Base URL

text
https://www.forevermoments.life/api/agent/v1

Note: IPFS pin endpoint is /api/pinata (NOT under /api/agent/v1)

Success Indicators

Good response:

json
{
  "success": true,
  "data": {
    "ok": true,
    "responseText": "{\"transactionHash\":\"0x...\"}"
  }
}

Bad response:

json
{
  "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

Installation

Terminal bash

openclaw install forever-moments
    
Copied!

💻Code Examples

node scripts/mint-likes.js 0.5

node-scriptsmint-likesjs-05.txt
## The 4-Step Relay Flow (Gasless)

All operations follow this pattern:

});

.txt
## Negative Examples

❌ **WRONG:** Using wrong signing method

}

.txt
## Templates

### Post Moment with Image

};

.txt
### 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 DALLE_API_KEY="sk-..." # OpenAI API key

export-dalleapikeysk---openai-api-key.txt
## 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

httpswwwforevermomentslifeapiagentv1.txt
**Note:** IPFS pin endpoint is `/api/pinata` (NOT under `/api/agent/v1`)

## Success Indicators

✅ **Good response:**
example.sh
# 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
example.txt
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  1. Pin Image   │────▶│  2. Build Tx    │────▶│ 3. Prepare Relay│────▶│ 4. Sign & Submit│
│  (if needed)    │     │                 │     │                 │     │                 │
└─────────────────┘     └─────────────────┘     └─────────────────┘     └─────────────────┘
example.js
// 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
});
example.js
// WRONG - adds EIP-191 prefix
await wallet.signMessage(hashToSign)

// CORRECT - sign raw bytes
wallet.signingKey.sign(ethers.getBytes(hashToSign))

Tags

#coding_agents-and-ides

Quick Info

Category Development
Model Claude 3.5
Complexity One-Click
Author luksoagent
Last Updated 3/10/2026
🚀
Optimized for
Claude 3.5
🧠

Ready to Install?

Get started with this skill in seconds

openclaw install forever-moments