{
  "schemaVersion": "1.0",
  "item": {
    "slug": "lsp28-grid",
    "name": "Lsp28 Grid",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/LUKSOAgent/lsp28-grid",
    "canonicalUrl": "https://clawhub.ai/LUKSOAgent/lsp28-grid",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/lsp28-grid",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=lsp28-grid",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "references/lsp28-spec.md",
      "scripts/update-grid.js"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/lsp28-grid"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/lsp28-grid",
    "agentPageUrl": "https://openagent3.xyz/skills/lsp28-grid/agent",
    "manifestUrl": "https://openagent3.xyz/skills/lsp28-grid/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/lsp28-grid/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "LSP28 The Grid Skill",
        "body": "Manage LSP28 The Grid on Universal Profiles. Create grid layouts with mini-apps, iframes, and external links."
      },
      {
        "title": "1. Configure Environment",
        "body": "Set these environment variables or edit the scripts:\n\nexport UP_PRIVATE_KEY=\"your_controller_private_key\"\nexport UP_ADDRESS=\"your_universal_profile_address\"\nexport KEY_MANAGER=\"your_key_manager_address\""
      },
      {
        "title": "2. Update Grid Layout",
        "body": "const { ethers } = require('ethers');\n\n// Grid data structure\nconst gridData = {\n  isEditable: true,\n  items: [\n    {\n      type: 'miniapp',\n      id: 'app1',\n      title: 'My App',\n      backgroundColor: '#1a1a2e',\n      textColor: '#ffffff',\n      text: 'Click me'\n    },\n    {\n      type: 'iframe',\n      src: 'https://example.com/embed',\n      id: 'frame1',\n      title: 'External Content'\n    },\n    {\n      type: 'external',\n      url: 'https://example.com',\n      id: 'link1',\n      title: 'Visit Site'\n    }\n  ]\n};\n\n// Encode as VerifiableURI\nconst jsonString = JSON.stringify(gridData);\nconst base64Data = Buffer.from(jsonString).toString('base64');\nconst verifiableUri = `data:application/json;base64,${base64Data}`;"
      },
      {
        "title": "3. Execute Transaction",
        "body": "// LSP28 Grid data key\nconst LSP28_GRID_KEY = '0x31cf14955c5b0052c1491ec06644438ec7c14454be5eb6cb9ce4e4edef647423';\n\n// Minimal ABIs\nconst LSP0_ABI = ['function setData(bytes32 dataKey, bytes dataValue) external'];\nconst LSP6_ABI = ['function execute(bytes calldata payload) external payable returns (bytes memory)'];\n\n// Setup provider and wallet\nconst provider = new ethers.JsonRpcProvider('https://rpc.mainnet.lukso.network');\nconst wallet = new ethers.Wallet(process.env.UP_PRIVATE_KEY, provider);\n\n// Encode setData call on UP\nconst upInterface = new ethers.Interface(LSP0_ABI);\nconst executeData = upInterface.encodeFunctionData('setData', [\n  LSP28_GRID_KEY,\n  ethers.toUtf8Bytes(verifiableUri)\n]);\n\n// Send via KeyManager\nconst keyManager = new ethers.Contract(process.env.KEY_MANAGER, LSP6_ABI, wallet);\nconst tx = await keyManager.execute(executeData);\nconst receipt = await tx.wait();\nconsole.log('Grid updated in block:', receipt.blockNumber);"
      },
      {
        "title": "Grid Item Types",
        "body": "Mini-App (type: 'miniapp')\n\n{\n  type: 'miniapp',\n  id: 'unique-id',          // Required: unique identifier\n  title: 'App Title',       // Required: display title\n  text: 'Button text',      // Required: button label\n  backgroundColor: '#fe005b',  // Required: hex color\n  textColor: '#ffffff',     // Required: hex color for text\n  size: 'medium'            // Optional: 'small', 'medium', 'large'\n}\n\nIFrame (type: 'iframe')\n\n{\n  type: 'iframe',\n  id: 'unique-id',          // Required: unique identifier\n  title: 'Frame Title',     // Required: display title\n  src: 'https://example.com/embed'  // Required: iframe URL\n}\n\nExternal Link (type: 'external')\n\n{\n  type: 'external',\n  id: 'unique-id',          // Required: unique identifier\n  title: 'Link Title',      // Required: display title\n  url: 'https://example.com'  // Required: external URL\n}"
      },
      {
        "title": "Full Grid Structure",
        "body": "{\n  isEditable: true,  // Boolean: allows editing\n  items: [\n    // Array of grid items (see types above)\n  ]\n}"
      },
      {
        "title": "Important Constants",
        "body": "ConstantValueDescriptionLSP28_GRID_KEY0x31cf14955c5b0052c1491ec06644438ec7c14454be5eb6cb9ce4e4edef647423Data key for grid storageChain ID42LUKSO MainnetRPC URLhttps://rpc.mainnet.lukso.networkPublic RPC endpoint"
      },
      {
        "title": "Color Contrast Requirements",
        "body": "Ensure text is readable on background colors:\n\nBackgroundText ColorResult#1a1a2e (dark)#ffffff (white)Good contrast#ffffff (white)#000000 (black)Good contrast#fe005b (pink)#ffffff (white)Good contrast#000000 (black)#fe005b (pink)Good contrast"
      },
      {
        "title": "Common Mistakes",
        "body": "❌ Wrong property names:\n\n// WRONG:\n{ color: '#fe005b', content: 'Click me' }\n\n// CORRECT:\n{ backgroundColor: '#fe005b', text: 'Click me' }\n\n❌ Missing required fields:\n\nAll items need: type, id, title\nMini-apps additionally need: text, backgroundColor, textColor\n\n❌ Wrong encoding:\n\n// WRONG - toUtf8String instead of toUtf8Bytes:\nsetData(key, ethers.toUtf8String(uri))\n\n// CORRECT:\nsetData(key, ethers.toUtf8Bytes(uri))"
      },
      {
        "title": "Transaction Flow",
        "body": "Controller Key \n    ↓\nKeyManager.execute(payload)\n    ↓\nUP.setData(LSP28_GRID_KEY, verifiableUri)\n    ↓\nGrid updated on-chain"
      },
      {
        "title": "CLI Usage",
        "body": "Use the provided script:\n\n# Use example grid\nnode scripts/update-grid.js --example\n\n# Load from JSON file\nnode scripts/update-grid.js --file my-grid.json"
      },
      {
        "title": "References",
        "body": "references/lsp28-spec.md - Full LSP28 specification\nscripts/update-grid.js - Complete working example\nLSP28 Standard: https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-28-TheGrid.md"
      }
    ],
    "body": "LSP28 The Grid Skill\n\nManage LSP28 The Grid on Universal Profiles. Create grid layouts with mini-apps, iframes, and external links.\n\nQuick Start\n1. Configure Environment\n\nSet these environment variables or edit the scripts:\n\nexport UP_PRIVATE_KEY=\"your_controller_private_key\"\nexport UP_ADDRESS=\"your_universal_profile_address\"\nexport KEY_MANAGER=\"your_key_manager_address\"\n\n2. Update Grid Layout\nconst { ethers } = require('ethers');\n\n// Grid data structure\nconst gridData = {\n  isEditable: true,\n  items: [\n    {\n      type: 'miniapp',\n      id: 'app1',\n      title: 'My App',\n      backgroundColor: '#1a1a2e',\n      textColor: '#ffffff',\n      text: 'Click me'\n    },\n    {\n      type: 'iframe',\n      src: 'https://example.com/embed',\n      id: 'frame1',\n      title: 'External Content'\n    },\n    {\n      type: 'external',\n      url: 'https://example.com',\n      id: 'link1',\n      title: 'Visit Site'\n    }\n  ]\n};\n\n// Encode as VerifiableURI\nconst jsonString = JSON.stringify(gridData);\nconst base64Data = Buffer.from(jsonString).toString('base64');\nconst verifiableUri = `data:application/json;base64,${base64Data}`;\n\n3. Execute Transaction\n// LSP28 Grid data key\nconst LSP28_GRID_KEY = '0x31cf14955c5b0052c1491ec06644438ec7c14454be5eb6cb9ce4e4edef647423';\n\n// Minimal ABIs\nconst LSP0_ABI = ['function setData(bytes32 dataKey, bytes dataValue) external'];\nconst LSP6_ABI = ['function execute(bytes calldata payload) external payable returns (bytes memory)'];\n\n// Setup provider and wallet\nconst provider = new ethers.JsonRpcProvider('https://rpc.mainnet.lukso.network');\nconst wallet = new ethers.Wallet(process.env.UP_PRIVATE_KEY, provider);\n\n// Encode setData call on UP\nconst upInterface = new ethers.Interface(LSP0_ABI);\nconst executeData = upInterface.encodeFunctionData('setData', [\n  LSP28_GRID_KEY,\n  ethers.toUtf8Bytes(verifiableUri)\n]);\n\n// Send via KeyManager\nconst keyManager = new ethers.Contract(process.env.KEY_MANAGER, LSP6_ABI, wallet);\nconst tx = await keyManager.execute(executeData);\nconst receipt = await tx.wait();\nconsole.log('Grid updated in block:', receipt.blockNumber);\n\nData Structure Reference\nGrid Item Types\n\nMini-App (type: 'miniapp')\n\n{\n  type: 'miniapp',\n  id: 'unique-id',          // Required: unique identifier\n  title: 'App Title',       // Required: display title\n  text: 'Button text',      // Required: button label\n  backgroundColor: '#fe005b',  // Required: hex color\n  textColor: '#ffffff',     // Required: hex color for text\n  size: 'medium'            // Optional: 'small', 'medium', 'large'\n}\n\n\nIFrame (type: 'iframe')\n\n{\n  type: 'iframe',\n  id: 'unique-id',          // Required: unique identifier\n  title: 'Frame Title',     // Required: display title\n  src: 'https://example.com/embed'  // Required: iframe URL\n}\n\n\nExternal Link (type: 'external')\n\n{\n  type: 'external',\n  id: 'unique-id',          // Required: unique identifier\n  title: 'Link Title',      // Required: display title\n  url: 'https://example.com'  // Required: external URL\n}\n\nFull Grid Structure\n{\n  isEditable: true,  // Boolean: allows editing\n  items: [\n    // Array of grid items (see types above)\n  ]\n}\n\nImportant Constants\nConstant\tValue\tDescription\nLSP28_GRID_KEY\t0x31cf14955c5b0052c1491ec06644438ec7c14454be5eb6cb9ce4e4edef647423\tData key for grid storage\nChain ID\t42\tLUKSO Mainnet\nRPC URL\thttps://rpc.mainnet.lukso.network\tPublic RPC endpoint\nColor Contrast Requirements\n\nEnsure text is readable on background colors:\n\nBackground\tText Color\tResult\n#1a1a2e (dark)\t#ffffff (white)\tGood contrast\n#ffffff (white)\t#000000 (black)\tGood contrast\n#fe005b (pink)\t#ffffff (white)\tGood contrast\n#000000 (black)\t#fe005b (pink)\tGood contrast\nCommon Mistakes\n\n❌ Wrong property names:\n\n// WRONG:\n{ color: '#fe005b', content: 'Click me' }\n\n// CORRECT:\n{ backgroundColor: '#fe005b', text: 'Click me' }\n\n\n❌ Missing required fields:\n\nAll items need: type, id, title\nMini-apps additionally need: text, backgroundColor, textColor\n\n❌ Wrong encoding:\n\n// WRONG - toUtf8String instead of toUtf8Bytes:\nsetData(key, ethers.toUtf8String(uri))\n\n// CORRECT:\nsetData(key, ethers.toUtf8Bytes(uri))\n\nTransaction Flow\nController Key \n    ↓\nKeyManager.execute(payload)\n    ↓\nUP.setData(LSP28_GRID_KEY, verifiableUri)\n    ↓\nGrid updated on-chain\n\nCLI Usage\n\nUse the provided script:\n\n# Use example grid\nnode scripts/update-grid.js --example\n\n# Load from JSON file\nnode scripts/update-grid.js --file my-grid.json\n\nReferences\nreferences/lsp28-spec.md - Full LSP28 specification\nscripts/update-grid.js - Complete working example\nLSP28 Standard: https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-28-TheGrid.md"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/LUKSOAgent/lsp28-grid",
    "publisherUrl": "https://clawhub.ai/LUKSOAgent/lsp28-grid",
    "owner": "LUKSOAgent",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/lsp28-grid",
    "downloadUrl": "https://openagent3.xyz/downloads/lsp28-grid",
    "agentUrl": "https://openagent3.xyz/skills/lsp28-grid/agent",
    "manifestUrl": "https://openagent3.xyz/skills/lsp28-grid/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/lsp28-grid/agent.md"
  }
}