{"version":3,"sources":["../src/config.ts","../src/index.ts","../src/mcp/wallet/get_wallet_info_tool.ts","../src/mcp/wallet/get_account_balances_tool.ts","../src/mcp/wallet/send_eth_tool.ts","../src/mcp/wallet/send_token_tool.ts","../src/mcp/wallet/approve_token_tool.ts","../src/mcp/wallet/check_allowance_tool.ts","../src/mcp/wallet/get_token_info_tool.ts","../src/mcp/wallet/get_transaction_history_tool.ts","../src/mcp/wallet/validate_address_tool.ts","../src/mcp/wallet/wrap_ip_tool.ts","../src/mcp/wallet/unwrap_wip_tool.ts","../src/mcp/ip/register_ip_tool.ts","../src/utils/pinata.ts","../src/utils/url-parser.ts","../src/utils/license-terms.ts","../src/mcp/ip/get_ip_info_tool.ts","../src/mcp/license/create_license_terms_tool.ts","../src/mcp/license/attach_license_tool.ts","../src/mcp/license/mint_license_tool.ts","../src/mcp/webapp/generate_showcase_platform_tool.ts","../src/mcp/index.ts","../src/agent/index.ts"],"sourcesContent":["import { aeneid, mainnet, StoryClient, StoryConfig } from '@story-protocol/core-sdk';\nimport { Chain, createPublicClient, createWalletClient, http, WalletClient } from 'viem';\nimport { privateKeyToAccount, Address, Account } from 'viem/accounts';\nimport dotenv from 'dotenv';\n\ndotenv.config();\n\n// Network configuration types\ntype NetworkType = 'aeneid' | 'mainnet';\n\ninterface NetworkConfig {\n    rpcProviderUrl: string;\n    blockExplorer: string;\n    protocolExplorer: string;\n    defaultNFTContractAddress: Address | null;\n    defaultSPGNFTContractAddress: Address | null;\n    chain: Chain;\n}\n\nconst getArgs = () =>\n    process.argv.reduce((args: any, arg: any) => {\n        // long arg\n        if (arg.slice(0, 2) === \"--\") {\n            const longArg = arg.split(\"=\");\n            const longArgFlag = longArg[0].slice(2);\n            const longArgValue = longArg.length > 1 ? longArg[1] : true;\n            args[longArgFlag] = longArgValue;\n        }\n        // flags\n        else if (arg[0] === \"-\") {\n            const flags = arg.slice(1).split(\"\");\n            flags.forEach((flag: any) => {\n                args[flag] = true;\n            });\n        }\n        return args;\n    }, {});\n\n// Network configurations\nconst networkConfigs: Record<NetworkType, NetworkConfig> = {\n    aeneid: {\n        rpcProviderUrl: 'https://aeneid.storyrpc.io',\n        blockExplorer: 'https://aeneid.storyscan.io',\n        protocolExplorer: 'https://aeneid.explorer.story.foundation',\n        defaultNFTContractAddress: '0x937bef10ba6fb941ed84b8d249abc76031429a9a' as Address,\n        defaultSPGNFTContractAddress: '0xc32A8a0FF3beDDDa58393d022aF433e78739FAbc' as Address,\n        chain: aeneid,\n    },\n    mainnet: {\n        rpcProviderUrl: 'https://mainnet.storyrpc.io',\n        blockExplorer: 'https://storyscan.io',\n        protocolExplorer: 'https://explorer.story.foundation',\n        defaultNFTContractAddress: null,\n        defaultSPGNFTContractAddress: '0x98971c660ac20880b60F86Cc3113eBd979eb3aAE' as Address,\n        chain: mainnet,\n    },\n} as const;\n\nconst getNetwork = (): NetworkType => {\n\n    const args = getArgs();\n    const network = ((args?.story_network || process.env.STORY_NETWORK) || 'aeneid') as NetworkType;\n\n    if (network && !(network in networkConfigs)) {\n        throw new Error(`Invalid network: ${network}. Must be one of: ${Object.keys(networkConfigs).join(', ')}`);\n    }\n    return network || 'aeneid';\n};\n\nconst getAccount = (): Account => {\n\n    const args = getArgs();\n    const hasPrivateKey = !!(args?.wallet_private_key || process.env.WALLET_PRIVATE_KEY);\n\n    if (!hasPrivateKey) {\n        throw new Error('WALLET_PRIVATE_KEY environment variable is required');\n    }\n\n    return privateKeyToAccount(`0x${(args?.wallet_private_key || process.env.WALLET_PRIVATE_KEY)}` as Address);\n}\n\n// Initialize client configuration\nexport const network = getNetwork();\n\nexport const networkInfo = {\n    ...networkConfigs[network],\n    rpcProviderUrl: networkConfigs[network].rpcProviderUrl,\n};\n\nexport const account: Account = getAccount()\n\nconst config: StoryConfig = {\n    account,\n    transport: http(networkInfo.rpcProviderUrl),\n    chainId: network,\n};\n\nexport const client = StoryClient.newClient(config);\n\nconst baseConfig = {\n    chain: networkInfo.chain,\n    transport: http(networkInfo.rpcProviderUrl),\n} as const;\n\nexport const publicClient = createPublicClient(baseConfig);\n\nexport const walletClient = createWalletClient({\n    ...baseConfig,\n    account,\n}) as WalletClient;\n\nexport function validateEnvironment(): void {\n    try {\n        getAccount()\n        getNetwork()\n        console.error(`✅ Story Protocol environment configuration valid (${network})`);\n        console.error(`📍 RPC URL: ${networkInfo.rpcProviderUrl}`);\n        console.error(`📍 Account: ${account.address}`);\n    } catch (error) {\n        console.error('❌ Invalid environment configuration:', error);\n        throw error;\n    }\n}\n","#!/usr/bin/env node\n\nimport { validateEnvironment } from './config';\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { StoryMcpTools, getImplementationStatus } from \"./mcp\";\nimport { StoryAgent } from './agent';\n\n/**\n * Creates an MCP server for IP registration and licensing on Story Protocol\n */\nfunction createMcpServer(agent: StoryAgent) {\n    // Create MCP server instance\n    const server = new McpServer({\n        name: \"story-build\",\n        version: \"0.1.0\"\n    });\n\n    // Register all Story Protocol tools\n    for (const [_key, tool] of Object.entries(StoryMcpTools)) {\n        server.tool(tool.name, tool.description, tool.schema, async (params: any): Promise<any> => {\n            try {\n                // Execute the handler with the params directly\n                const result = await tool.handler(agent, params);\n\n                // Format the result as MCP tool response\n                return {\n                    content: [\n                        {\n                            type: \"text\",\n                            text: JSON.stringify(result, null, 2),\n                        },\n                    ],\n                };\n            } catch (error) {\n                console.error(\"Tool execution error:\", error);\n                // Handle errors in MCP format\n                return {\n                    isError: true,\n                    content: [\n                        {\n                            type: \"text\",\n                            text: error instanceof Error\n                                ? error.message\n                                : \"Unknown error occurred\",\n                        },\n                    ],\n                };\n            }\n        });\n    }\n\n    return server;\n}\n\nasync function main() {\n    try {\n        console.error(\"🎨 Starting Story.build MCP Server...\");\n\n        // Validate environment before proceeding\n        validateEnvironment();\n\n        // Create Story agent\n        const storyAgent = new StoryAgent();\n\n        // Get implementation status\n        const status = getImplementationStatus();\n        console.error(`📊 Implementation Status: ${status.implemented}/${status.total_defined} tools (${status.completion_percentage}%)`);\n\n        // Create and start MCP server\n        const server = createMcpServer(storyAgent);\n        const transport = new StdioServerTransport();\n        await server.connect(transport);\n\n        console.error(\"✅ Story.build MCP Server is running!\");\n        console.error(\"🎯 IP registration and licensing tools ready!\");\n        \n        \n    } catch (error) {\n        console.error('❌ Error starting Story.build MCP server:', error);\n        process.exit(1);\n    }\n}\n\nmain();","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\n\nexport const GetWalletInfoTool: McpTool = {\n    name: \"story_get_wallet_info\",\n    description: \"Get wallet address and basic account information\",\n    schema: {},\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            // const walletInfo = await agent.getWalletInfo();\n            const balance = await agent.publicClient.getBalance({\n                address: agent.account.address\n            });\n            \n            const balanceInETH = Number(balance) / 1e18;\n\n            return {\n                status: \"success\",\n                message: \"✅ Wallet information retrieved successfully\",\n                wallet_details: {\n                    address: agent.account.address,\n                    network: agent.network,\n                    balance: `${balanceInETH.toFixed(6)} IP`,\n                    balance_in_wei: balance.toString(),\n                    chain_id: await agent.publicClient.getChainId(),\n                    block_explorer: agent.networkInfo.blockExplorer,\n                    protocol_explorer: agent.networkInfo.protocolExplorer\n                },\n                account_status: {\n                    activated: true,\n                    minimum_balance_required: \"0.01 IP\",\n                    can_register_ip: balanceInETH >= 0.01,\n                    ready_for_operations: balanceInETH >= 0.001\n                },\n                recommendations: balanceInETH < 0.01 \n                    ? [\n                        \"⚠️ Low IP balance detected\",\n                        \"Fund wallet with at least 0.01 IP for IP registration\",\n                        \"Gas fees required for all Story Protocol operations\",\n                        `Current balance: ${balanceInETH.toFixed(6)} IP`\n                    ]\n                    : [\n                        \"✅ Wallet has sufficient balance for operations\",\n                        \"Ready to register IP assets\",\n                        \"Ready to create license terms and mint tokens\"\n                    ]\n            };\n        } catch (error: any) {\n            throw new Error(`Failed to get wallet info: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { formatEther, Address } from \"viem\";\nimport { WIP_TOKEN_ADDRESS } from \"@story-protocol/core-sdk\";\n\nexport const GetAccountBalancesTool: McpTool = {\n    name: \"story_get_account_balances\",\n    description: \"Get all token balances including IP, WIP tokens, and license tokens\",\n    schema: {\n        account_address: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .optional()\n            .describe(\"Ethereum address to check (optional, defaults to wallet address)\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const targetAddress = (input.account_address || agent.account.address) as Address;\n\n            // Get ETH balance\n            const ethBalance = await agent.publicClient.getBalance({\n                address: targetAddress\n            });\n\n            // Get WIP token balance (Story Protocol's wrapped token)\n            let wipBalance = BigInt(0);\n            try {\n                wipBalance = await agent.publicClient.readContract({\n                    address: WIP_TOKEN_ADDRESS,\n                    abi: [\n                        {\n                            name: 'balanceOf',\n                            type: 'function',\n                            stateMutability: 'view',\n                            inputs: [{ name: 'account', type: 'address' }],\n                            outputs: [{ name: '', type: 'uint256' }],\n                        }\n                    ],\n                    functionName: 'balanceOf',\n                    args: [targetAddress]\n                });\n            } catch (error) {\n                console.error('Error fetching WIP balance:', error);\n            } \n\n            return {\n                status: \"success\",\n                message: `✅ Account balances retrieved for ${targetAddress}`,\n                account_info: {\n                    address: targetAddress,\n                    network: agent.network,\n                    is_own_wallet: targetAddress.toLowerCase() === agent.account.address.toLowerCase()\n                },\n                native_balance: {\n                    symbol: \"IP\",\n                    balance: formatEther(ethBalance),\n                    balance_wei: ethBalance.toString(),\n                    usd_value: \"N/A\" // Could integrate price feeds later\n                },\n                story_protocol_tokens: {\n                    wip: {\n                        symbol: \"WIP\",\n                        name: \"Wrapped IP Token\",\n                        balance: formatEther(wipBalance),\n                        balance_wei: wipBalance.toString(),\n                        contract_address: WIP_TOKEN_ADDRESS,\n                        purpose: \"Used for licensing fees and royalty payments\"\n                    }\n                },\n                portfolio_summary: {\n                    total_ip_balance: formatEther(ethBalance),\n                    total_wip_balance: formatEther(wipBalance),\n                    can_pay_gas: Number(formatEther(ethBalance)) > 0.001,\n                    can_pay_licensing_fees: wipBalance > 0,\n                    ready_for_ip_operations: Number(formatEther(ethBalance)) > 0.001\n                },\n                next_steps: Number(formatEther(ethBalance)) < 0.001\n                    ? [\n                        \"🔋 Fund wallet with ETH for gas fees\",\n                        \"💎 Acquire WIP tokens for licensing operations\",\n                        \"🎨 Ready to register IP assets once funded\"\n                    ]\n                    : [\n                        \"✅ Sufficient ETH for gas fees\",\n                        \"🎨 Ready to register IP assets\",\n                        \"🎫 Ready to mint and purchase licenses\",\n                        wipBalance === BigInt(0) ? \"💡 Consider acquiring WIP tokens for licensing\" : \"💎 WIP tokens available for licensing\"\n                    ]\n            };\n        } catch (error: any) {\n            throw new Error(`Failed to get account balances: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { parseEther, Address } from \"viem\";\n\nexport const SendETHTool: McpTool = {\n    name: \"story_send_native_ip\",\n    description: \"Send native IP token to another address for gas fees or payments\",\n    schema: {\n        destination: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"Recipient's Ethereum address\"),\n        amount: z.number()\n            .positive()\n            .describe(\"Amount of IP to send\"),\n        memo: z.string()\n            .optional()\n            .describe(\"Optional memo for the transaction\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const destination = input.destination as Address;\n            const amount = parseEther(input.amount.toString());\n            \n            // Check sender balance\n            const balance = await agent.publicClient.getBalance({\n                address: agent.account.address\n            });\n\n            if (balance < amount) {\n                throw new Error(`Insufficient balance. Available: ${Number(balance) / 1e18} IP, Required: ${input.amount} IP`);\n            }\n\n            // Simulate transaction first to get accurate gas estimate and catch errors\n            let gasEstimate: bigint;\n            try {\n                // For ETH transfers, we use estimateGas directly since it's not a contract call\n                gasEstimate = await agent.publicClient.estimateGas({\n                    account: agent.account.address,\n                    to: destination,\n                    value: amount\n                });\n            } catch (error: any) {\n                throw new Error(`Transaction simulation failed: ${error.message}. Check recipient address and amount.`);\n            }\n\n            // Get gas price for cost calculation\n            const gasPrice = await agent.publicClient.getGasPrice();\n            const gasCost = gasEstimate * gasPrice;\n\n            if (balance < amount + gasCost) {\n                throw new Error(`Insufficient balance for transaction + gas. Total needed: ${Number(amount + gasCost) / 1e18} IP`);\n            }\n\n            console.error(`✅ Native IP transfer simulation successful. Gas estimate: ${gasEstimate.toString()}`);\n\n            // Send transaction\n            const txHash = await agent.walletClient.sendTransaction({\n                account: agent.account,\n                to: destination,\n                value: amount,\n                gas: gasEstimate\n            } as any);\n\n            // Wait for confirmation\n            const receipt = await agent.publicClient.waitForTransactionReceipt({\n                hash: txHash,\n                confirmations: 1\n            });\n\n            return {\n                status: \"success\",\n                message: `✅ Successfully sent ${input.amount} IP to ${destination}`,\n                transaction_details: {\n                    transaction_hash: txHash,\n                    from: agent.account.address,\n                    to: destination,\n                    amount: `${input.amount} IP`,\n                    amount_wei: amount.toString(),\n                    gas_used: receipt.gasUsed.toString(),\n                    gas_price: gasPrice.toString(),\n                    total_cost: `${Number(amount + (receipt.gasUsed * gasPrice)) / 1e18} IP`,\n                    block_number: receipt.blockNumber.toString(),\n                    confirmations: 1,\n                    memo: input.memo || \"N/A\"\n                },\n                network_info: {\n                    network: agent.network,\n                    explorer_url: `${agent.networkInfo.blockExplorer}/tx/${txHash}`\n                },\n                next_steps: [\n                    \"✅ Transaction confirmed on blockchain\",\n                    \"🔍 View transaction details on block explorer\",\n                    \"💰 Recipient can now use IP for Story Protocol operations\"\n                ]\n            };\n        } catch (error: any) {\n            throw new Error(`Failed to send IP: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { parseEther, Address, formatEther } from \"viem\";\nimport { WIP_TOKEN_ADDRESS } from \"@story-protocol/core-sdk\";\n\nexport const SendTokenTool: McpTool = {\n    name: \"story_send_token\",\n    description: \"Send Story Protocol tokens (WIP, or custom tokens) to another address\",\n    schema: {\n        token_address: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"Token contract address (use 'WIP' for WIP token shortcut)\"),\n        destination: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"Recipient's Ethereum address\"),\n        amount: z.number()\n            .positive()\n            .describe(\"Amount of tokens to send\"),\n        memo: z.string()\n            .optional()\n            .describe(\"Optional memo for the transaction\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const destination = input.destination as Address;\n            let tokenAddress = input.token_address as Address;\n            \n            // Handle shortcuts\n            if (input.token_address === \"WIP\") {\n                tokenAddress = WIP_TOKEN_ADDRESS;\n            } \n\n            const amount = parseEther(input.amount.toString());\n\n            // ERC20 ABI for token operations\n            const erc20Abi = [\n                {\n                    name: 'transfer',\n                    type: 'function',\n                    stateMutability: 'nonpayable',\n                    inputs: [\n                        { name: 'to', type: 'address' },\n                        { name: 'amount', type: 'uint256' }\n                    ],\n                    outputs: [{ name: '', type: 'bool' }],\n                },\n                {\n                    name: 'balanceOf',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [{ name: 'account', type: 'address' }],\n                    outputs: [{ name: '', type: 'uint256' }],\n                },\n                {\n                    name: 'symbol',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [],\n                    outputs: [{ name: '', type: 'string' }],\n                },\n                {\n                    name: 'decimals',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [],\n                    outputs: [{ name: '', type: 'uint8' }],\n                }\n            ];\n\n            // Get token info\n            const [balance, symbol, decimals] = await Promise.all([\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'balanceOf',\n                    args: [agent.account.address]\n                }) as Promise<bigint>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'symbol'\n                }) as Promise<string>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'decimals'\n                }) as Promise<number>\n            ]);\n\n            if (balance < amount) {\n                throw new Error(`Insufficient ${symbol} balance. Available: ${formatEther(balance)}, Required: ${input.amount}`);\n            }\n\n            // Simulate token transfer first to catch errors and get accurate gas estimate\n            const { request, result } = await agent.publicClient.simulateContract({\n                address: tokenAddress,\n                abi: erc20Abi,\n                functionName: 'transfer',\n                args: [destination, amount],\n                account: agent.account.address\n            });\n\n            console.error(`✅ Transfer simulation successful. Proceeding with transaction...`);\n\n            // Send token transfer transaction using the simulated request\n            const txHash = await agent.walletClient.writeContract(request);\n\n            // Wait for confirmation\n            const receipt = await agent.publicClient.waitForTransactionReceipt({\n                hash: txHash,\n                confirmations: 1\n            });\n\n            return {\n                status: \"success\",\n                message: `✅ Successfully sent ${input.amount} ${symbol} to ${destination}`,\n                transaction_details: {\n                    transaction_hash: txHash,\n                    from: agent.account.address,\n                    to: destination,\n                    token_address: tokenAddress,\n                    token_symbol: symbol,\n                    amount: `${input.amount} ${symbol}`,\n                    amount_wei: amount.toString(),\n                    decimals: decimals,\n                    gas_used: receipt.gasUsed.toString(),\n                    block_number: receipt.blockNumber.toString(),\n                    confirmations: 1,\n                    memo: input.memo || \"N/A\"\n                },\n                token_info: {\n                    contract_address: tokenAddress,\n                    symbol: symbol,\n                    decimals: decimals,\n                    is_story_protocol_token: tokenAddress === WIP_TOKEN_ADDRESS\n                },\n                network_info: {\n                    network: agent.network,\n                    explorer_url: `${agent.networkInfo.blockExplorer}/tx/${txHash}`\n                },\n                next_steps: [\n                    \"✅ Token transfer confirmed on blockchain\",\n                    \"🔍 View transaction details on block explorer\",\n                    `💎 Recipient can now use ${symbol} tokens for Story Protocol operations`\n                ]\n            };\n        } catch (error: any) {\n            throw new Error(`Failed to send tokens: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { parseEther, Address, formatEther, maxUint256 } from \"viem\";\nimport { WIP_TOKEN_ADDRESS } from \"@story-protocol/core-sdk\";\n\nexport const ApproveTokenTool: McpTool = {\n    name: \"story_approve_token\",\n    description: \"Approve Story Protocol contracts to spend your tokens (required for licensing operations)\",\n    schema: {\n        token_address: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"Token contract address (use 'WIP' for WIP token shortcut)\"),\n        spender: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"Contract address to approve (Story Protocol contracts)\"),\n        amount: z.number()\n            .positive()\n            .optional()\n            .describe(\"Amount to approve (optional, defaults to unlimited)\"),\n        unlimited: z.boolean()\n            .default(true)\n            .describe(\"Set unlimited approval (recommended for convenience)\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            let tokenAddress = input.token_address as Address;\n            const spender = input.spender as Address;\n            \n            // Handle shortcuts\n            if (input.token_address === \"WIP\") {\n                tokenAddress = WIP_TOKEN_ADDRESS;\n            }\n\n            const amount = input.unlimited || !input.amount \n                ? maxUint256 \n                : parseEther(input.amount.toString());\n\n            // ERC20 ABI for approval operations\n            const erc20Abi = [\n                {\n                    name: 'approve',\n                    type: 'function',\n                    stateMutability: 'nonpayable',\n                    inputs: [\n                        { name: 'spender', type: 'address' },\n                        { name: 'amount', type: 'uint256' }\n                    ],\n                    outputs: [{ name: '', type: 'bool' }],\n                },\n                {\n                    name: 'allowance',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [\n                        { name: 'owner', type: 'address' },\n                        { name: 'spender', type: 'address' }\n                    ],\n                    outputs: [{ name: '', type: 'uint256' }],\n                },\n                {\n                    name: 'symbol',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [],\n                    outputs: [{ name: '', type: 'string' }],\n                },\n                {\n                    name: 'balanceOf',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [{ name: 'account', type: 'address' }],\n                    outputs: [{ name: '', type: 'uint256' }],\n                }\n            ];\n\n            // Get current allowance and token info\n            const [currentAllowance, symbol, balance] = await Promise.all([\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'allowance',\n                    args: [agent.account.address, spender]\n                }) as Promise<bigint>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'symbol'\n                }) as Promise<string>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'balanceOf',\n                    args: [agent.account.address]\n                }) as Promise<bigint>\n            ]);\n\n            // Check if approval is needed\n            if (currentAllowance >= amount && amount !== maxUint256) {\n                return {\n                    status: \"success\",\n                    message: `✅ Sufficient approval already exists for ${symbol}`,\n                    approval_details: {\n                        token_address: tokenAddress,\n                        token_symbol: symbol,\n                        spender: spender,\n                        current_allowance: input.unlimited ? \"Unlimited\" : formatEther(currentAllowance),\n                        requested_amount: input.unlimited ? \"Unlimited\" : input.amount?.toString(),\n                        approval_needed: false\n                    },\n                    wallet_info: {\n                        balance: formatEther(balance),\n                        address: agent.account.address\n                    },\n                    next_steps: [\n                        \"✅ Approval already sufficient\",\n                        \"🎨 Ready to proceed with Story Protocol operations\",\n                        \"💡 No additional transaction needed\"\n                    ]\n                };\n            }\n\n            // Simulate approval first to catch errors and get accurate gas estimate\n            const { request, result } = await agent.publicClient.simulateContract({\n                address: tokenAddress,\n                abi: erc20Abi,\n                functionName: 'approve',\n                args: [spender, amount],\n                account: agent.account.address\n            });\n\n            console.error(`✅ Approval simulation successful. Proceeding with transaction...`);\n\n            // Send approval transaction using the simulated request\n            const txHash = await agent.walletClient.writeContract(request);\n\n            // Wait for confirmation\n            const receipt = await agent.publicClient.waitForTransactionReceipt({\n                hash: txHash,\n                confirmations: 1\n            });\n\n            // Get new allowance\n            const newAllowance = await agent.publicClient.readContract({\n                address: tokenAddress,\n                abi: erc20Abi,\n                functionName: 'allowance',\n                args: [agent.account.address, spender]\n            }) as bigint;\n\n            return {\n                status: \"success\",\n                message: `✅ Successfully approved ${symbol} spending for Story Protocol contract`,\n                transaction_details: {\n                    transaction_hash: txHash,\n                    from: agent.account.address,\n                    token_address: tokenAddress,\n                    token_symbol: symbol,\n                    spender: spender,\n                    approved_amount: input.unlimited ? \"Unlimited\" : input.amount?.toString(),\n                    gas_used: receipt.gasUsed.toString(),\n                    block_number: receipt.blockNumber.toString(),\n                    confirmations: 1\n                },\n                approval_details: {\n                    previous_allowance: formatEther(currentAllowance),\n                    new_allowance: amount === maxUint256 ? \"Unlimited\" : formatEther(newAllowance),\n                    is_unlimited: amount === maxUint256,\n                    spender_contract: spender\n                },\n                wallet_info: {\n                    balance: formatEther(balance),\n                    address: agent.account.address\n                },\n                network_info: {\n                    network: agent.network,\n                    explorer_url: `${agent.networkInfo.blockExplorer}/tx/${txHash}`\n                },\n                next_steps: [\n                    \"✅ Token approval confirmed on blockchain\",\n                    \"🎨 Ready to register IP assets and mint licenses\",\n                    \"💎 Story Protocol contracts can now spend your tokens\",\n                    \"🔍 View transaction details on block explorer\"\n                ]\n            };\n        } catch (error: any) {\n            throw new Error(`Failed to approve tokens: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { Address, formatEther } from \"viem\";\nimport { WIP_TOKEN_ADDRESS } from \"@story-protocol/core-sdk\";\n\nexport const CheckAllowanceTool: McpTool = {\n    name: \"story_check_allowance\",\n    description: \"Check token allowance for Story Protocol contracts and other spenders\",\n    schema: {\n        token_address: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"Token contract address (use 'WIP' for WIP token shortcut)\"),\n        owner: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .optional()\n            .describe(\"Token owner address (optional, defaults to wallet address)\"),\n        spender: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"Spender contract address to check allowance for\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            let tokenAddress = input.token_address as Address;\n            const owner = (input.owner || agent.account.address) as Address;\n            const spender = input.spender as Address;\n            \n            // Handle shortcuts\n            if (input.token_address === \"WIP\") {\n                tokenAddress = WIP_TOKEN_ADDRESS;\n            }\n\n            // ERC20 ABI for allowance operations\n            const erc20Abi = [\n                {\n                    name: 'allowance',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [\n                        { name: 'owner', type: 'address' },\n                        { name: 'spender', type: 'address' }\n                    ],\n                    outputs: [{ name: '', type: 'uint256' }],\n                },\n                {\n                    name: 'balanceOf',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [{ name: 'account', type: 'address' }],\n                    outputs: [{ name: '', type: 'uint256' }],\n                },\n                {\n                    name: 'symbol',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [],\n                    outputs: [{ name: '', type: 'string' }],\n                },\n                {\n                    name: 'decimals',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [],\n                    outputs: [{ name: '', type: 'uint8' }],\n                },\n                {\n                    name: 'name',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [],\n                    outputs: [{ name: '', type: 'string' }],\n                }\n            ];\n\n            // Get token info and allowance\n            const [allowance, balance, symbol, decimals, name] = await Promise.all([\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'allowance',\n                    args: [owner, spender]\n                }) as Promise<bigint>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'balanceOf',\n                    args: [owner]\n                }) as Promise<bigint>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'symbol'\n                }) as Promise<string>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'decimals'\n                }) as Promise<number>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'name'\n                }) as Promise<string>\n            ]);\n\n            // Check if allowance is unlimited (max uint256)\n            const maxUint256 = BigInt(\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\");\n            const isUnlimited = allowance >= maxUint256 / BigInt(2); // Close to max value\n\n            // Calculate allowance status\n            const allowanceFormatted = isUnlimited ? \"Unlimited\" : formatEther(allowance);\n            const balanceFormatted = formatEther(balance);\n            const canSpendBalance = allowance >= balance;\n            const needsApproval = allowance === BigInt(0);\n\n            // Determine approval recommendations\n            const getRecommendations = () => {\n                if (needsApproval) {\n                    return [\n                        \"⚠️ No allowance set - approval required\",\n                        `Use story_approve_token to approve ${symbol} spending`,\n                        \"Recommend setting unlimited approval for convenience\"\n                    ];\n                } else if (!canSpendBalance && !isUnlimited) {\n                    return [\n                        \"⚠️ Allowance is less than current balance\",\n                        `Current allowance: ${allowanceFormatted} ${symbol}`,\n                        `Current balance: ${balanceFormatted} ${symbol}`,\n                        \"Consider increasing allowance for full balance access\"\n                    ];\n                } else if (isUnlimited) {\n                    return [\n                        \"✅ Unlimited allowance set\",\n                        \"No further approvals needed for this token\",\n                        \"Ready for all Story Protocol operations\"\n                    ];\n                } else {\n                    return [\n                        \"✅ Sufficient allowance for current balance\",\n                        `Can spend up to ${allowanceFormatted} ${symbol}`,\n                        \"Ready for Story Protocol operations\"\n                    ];\n                }\n            };\n\n            return {\n                status: \"success\",\n                message: `✅ Allowance checked for ${symbol} token`,\n                allowance_details: {\n                    token_address: tokenAddress,\n                    token_name: name,\n                    token_symbol: symbol,\n                    token_decimals: decimals,\n                    owner: owner,\n                    spender: spender,\n                    allowance: allowanceFormatted,\n                    allowance_wei: allowance.toString(),\n                    is_unlimited: isUnlimited,\n                    is_zero: allowance === BigInt(0)\n                },\n                balance_comparison: {\n                    owner_balance: balanceFormatted,\n                    owner_balance_wei: balance.toString(),\n                    can_spend_full_balance: canSpendBalance,\n                    allowance_vs_balance: allowance >= balance ? \"sufficient\" : \"insufficient\"\n                },\n                contract_info: {\n                    is_story_protocol_token: tokenAddress === WIP_TOKEN_ADDRESS,\n                    spender_contract: spender,\n                    is_own_wallet: owner.toLowerCase() === agent.account.address.toLowerCase()\n                },\n                operational_status: {\n                    needs_approval: needsApproval,\n                    ready_for_operations: !needsApproval,\n                    can_spend_tokens: allowance > 0,\n                    approval_sufficient: canSpendBalance || isUnlimited\n                },\n                network_info: {\n                    network: agent.network,\n                    block_explorer: agent.networkInfo.blockExplorer,\n                    token_explorer_url: `${agent.networkInfo.blockExplorer}/token/${tokenAddress}`,\n                    approval_explorer_url: `${agent.networkInfo.blockExplorer}/token/${tokenAddress}?a=${owner}`\n                },\n                recommendations: getRecommendations(),\n                next_steps: needsApproval \n                    ? [\n                        `🔧 Run: story_approve_token with token_address=${symbol === 'WIP' ? 'WIP' : tokenAddress}`,\n                        `📄 Specify spender=${spender}`,\n                        \"💡 Consider unlimited approval for convenience\",\n                        \"🎨 Then proceed with Story Protocol operations\"\n                    ]\n                    : [\n                        \"✅ Allowance is properly configured\",\n                        \"🎨 Ready to proceed with Story Protocol operations\",\n                        `💎 Can spend ${canSpendBalance ? 'full balance' : 'partial balance'} of ${symbol}`,\n                        \"🔍 View token details on block explorer\"\n                    ]\n            };\n        } catch (error: any) {\n            throw new Error(`Failed to check allowance: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { Address, formatEther } from \"viem\";\nimport { WIP_TOKEN_ADDRESS } from \"@story-protocol/core-sdk\";\n\nexport const GetTokenInfoTool: McpTool = {\n    name: \"story_get_token_info\",\n    description: \"Get comprehensive information about ERC20 tokens including metadata and user balances\",\n    schema: {\n        token_address: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"Token contract address (use 'WIP' for WIP token shortcut)\"),\n        account_address: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .optional()\n            .describe(\"Address to check balance for (optional, defaults to wallet address)\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            let tokenAddress = input.token_address as Address;\n            const accountAddress = (input.account_address || agent.account.address) as Address;\n            \n            // Handle shortcuts\n            if (input.token_address === \"WIP\") {\n                tokenAddress = WIP_TOKEN_ADDRESS;\n            }\n\n            // Extended ERC20 ABI for comprehensive token info\n            const erc20Abi = [\n                {\n                    name: 'name',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [],\n                    outputs: [{ name: '', type: 'string' }],\n                },\n                {\n                    name: 'symbol',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [],\n                    outputs: [{ name: '', type: 'string' }],\n                },\n                {\n                    name: 'decimals',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [],\n                    outputs: [{ name: '', type: 'uint8' }],\n                },\n                {\n                    name: 'totalSupply',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [],\n                    outputs: [{ name: '', type: 'uint256' }],\n                },\n                {\n                    name: 'balanceOf',\n                    type: 'function',\n                    stateMutability: 'view',\n                    inputs: [{ name: 'account', type: 'address' }],\n                    outputs: [{ name: '', type: 'uint256' }],\n                }\n            ];\n\n            // Get basic token information\n            const [name, symbol, decimals, totalSupply, balance] = await Promise.all([\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'name'\n                }) as Promise<string>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'symbol'\n                }) as Promise<string>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'decimals'\n                }) as Promise<number>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'totalSupply'\n                }) as Promise<bigint>,\n                agent.publicClient.readContract({\n                    address: tokenAddress,\n                    abi: erc20Abi,\n                    functionName: 'balanceOf',\n                    args: [accountAddress]\n                }) as Promise<bigint>\n            ]);\n\n            // Get contract bytecode to verify it's a contract\n            const bytecode = await agent.publicClient.getBytecode({\n                address: tokenAddress\n            });\n\n            const isContract = !!(bytecode && bytecode !== '0x');\n\n            // Calculate formatted values\n            const totalSupplyFormatted = formatEther(totalSupply);\n            const balanceFormatted = formatEther(balance);\n            const balancePercentage = totalSupply > 0 ? (Number(balance) / Number(totalSupply)) * 100 : 0;\n\n            // Determine token type and purpose\n            const getTokenInfo = () => {\n                if (tokenAddress === WIP_TOKEN_ADDRESS) {\n                    return {\n                        type: \"story_protocol_token\",\n                        category: \"wrapped_token\",\n                        purpose: \"Used for licensing fees and royalty payments on Story Protocol\",\n                        official: true\n                    };\n                } else {\n                    return {\n                        type: \"erc20_token\",\n                        category: \"custom\",\n                        purpose: \"Custom ERC20 token - verify legitimacy before use\",\n                        official: false\n                    };\n                }\n            };\n\n            const tokenInfo = getTokenInfo();\n\n            return {\n                status: \"success\",\n                message: `✅ Token information retrieved for ${symbol}`,\n                token_metadata: {\n                    contract_address: tokenAddress,\n                    name: name,\n                    symbol: symbol,\n                    decimals: decimals,\n                    total_supply: totalSupplyFormatted,\n                    total_supply_wei: totalSupply.toString(),\n                    is_contract: isContract,\n                    ...tokenInfo\n                },\n                account_balance: {\n                    address: accountAddress,\n                    balance: balanceFormatted,\n                    balance_wei: balance.toString(),\n                    percentage_of_supply: balancePercentage.toFixed(6) + \"%\",\n                    is_holder: balance > 0,\n                    is_own_wallet: accountAddress.toLowerCase() === agent.account.address.toLowerCase()\n                },\n                supply_analysis: {\n                    total_supply_formatted: totalSupplyFormatted,\n                    user_balance_formatted: balanceFormatted,\n                    supply_concentration: balancePercentage > 1 ? \"significant_holder\" : \n                                        balancePercentage > 0.1 ? \"moderate_holder\" : \n                                        balancePercentage > 0 ? \"small_holder\" : \"non_holder\"\n                },\n                story_protocol_integration: {\n                    is_story_token: tokenInfo.official,\n                    can_use_for_licensing: tokenAddress === WIP_TOKEN_ADDRESS,\n                    can_use_for_governance: false,\n                    purpose: tokenInfo.purpose,\n                    recommended_for_ip_operations: tokenInfo.official\n                },\n                network_info: {\n                    network: agent.network,\n                    block_explorer: agent.networkInfo.blockExplorer,\n                    token_explorer_url: `${agent.networkInfo.blockExplorer}/token/${tokenAddress}`,\n                    account_explorer_url: `${agent.networkInfo.blockExplorer}/token/${tokenAddress}?a=${accountAddress}`\n                },\n                operational_status: {\n                    has_balance: balance > 0,\n                    can_transfer: balance > 0,\n                    ready_for_story_operations: tokenInfo.official && balance > 0,\n                    needs_acquisition: balance === BigInt(0) && tokenInfo.official\n                },\n                next_steps: balance === BigInt(0) \n                    ? [\n                        `💰 Acquire ${symbol} tokens to use for Story Protocol`,\n                        tokenInfo.official ? `🎯 ${symbol} is required for licensing operations` : \"⚠️ Verify token legitimacy before acquiring\",\n                        `🔍 View token details on ${agent.networkInfo.blockExplorer}`,\n                        \"💡 Use story_send_token to receive tokens from others\"\n                    ]\n                    : [\n                        `✅ You have ${balanceFormatted} ${symbol} tokens`,\n                        tokenInfo.official ? \"🎨 Ready for Story Protocol operations\" : \"⚠️ Verify token legitimacy before using\",\n                        \"💎 Use story_approve_token to enable contract spending\",\n                        \"🔄 Use story_send_token to transfer to others\"\n                    ]\n            };\n        } catch (error: any) {\n            throw new Error(`Failed to get token info: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { Address, formatEther } from \"viem\";\n\nexport const GetTransactionHistoryTool: McpTool = {\n    name: \"story_get_transaction_history\",\n    description: \"Get recent transaction history for the wallet or specified address\",\n    schema: {\n        account_address: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .optional()\n            .describe(\"Address to check (optional, defaults to wallet address)\"),\n        limit: z.number()\n            .min(1)\n            .max(100)\n            .default(20)\n            .describe(\"Number of transactions to retrieve (max 100)\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const targetAddress = (input.account_address || agent.account.address) as Address;\n            const limit = input.limit || 20;\n\n            // Get current block number\n            const currentBlock = await agent.publicClient.getBlockNumber();\n            const fromBlock = currentBlock - BigInt(10000); // Look back ~10k blocks\n\n            // Get recent blocks to find transactions\n            const recentTransactions = [];\n            const blocksToCheck = Math.min(Number(limit * 5), 1000); // Check enough blocks to find transactions\n\n            for (let i = 0; i < blocksToCheck && recentTransactions.length < limit; i++) {\n                try {\n                    const blockNumber = currentBlock - BigInt(i);\n                    const block = await agent.publicClient.getBlock({\n                        blockNumber,\n                        includeTransactions: true\n                    });\n\n                    // Find transactions involving our address\n                    for (const tx of block.transactions) {\n                        if (typeof tx === 'object') {\n                            if ((tx.from?.toLowerCase() === targetAddress.toLowerCase() ||\n                                tx.to?.toLowerCase() === targetAddress.toLowerCase()) &&\n                                recentTransactions.length < limit) {\n\n                                // Get transaction receipt for more details\n                                try {\n                                    const receipt = await agent.publicClient.getTransactionReceipt({\n                                        hash: tx.hash\n                                    });\n\n                                    recentTransactions.push({\n                                        hash: tx.hash,\n                                        block_number: block.number?.toString(),\n                                        timestamp: new Date(Number(block.timestamp) * 1000).toISOString(),\n                                        from: tx.from,\n                                        to: tx.to,\n                                        value: tx.value ? formatEther(tx.value) : '0',\n                                        gas_used: receipt.gasUsed.toString(),\n                                        gas_price: tx.gasPrice?.toString(),\n                                        status: receipt.status === 'success' ? 'success' : 'failed',\n                                        type: tx.from?.toLowerCase() === targetAddress.toLowerCase() ? 'sent' : 'received',\n                                        is_contract_interaction: tx.to && tx.input !== '0x'\n                                    });\n                                } catch (receiptError) {\n                                    // If we can't get receipt, add basic info\n                                    recentTransactions.push({\n                                        hash: tx.hash,\n                                        block_number: block.number?.toString(),\n                                        timestamp: new Date(Number(block.timestamp) * 1000).toISOString(),\n                                        from: tx.from,\n                                        to: tx.to,\n                                        value: tx.value ? formatEther(tx.value) : '0',\n                                        gas_used: 'N/A',\n                                        gas_price: tx.gasPrice?.toString(),\n                                        status: 'unknown',\n                                        type: tx.from?.toLowerCase() === targetAddress.toLowerCase() ? 'sent' : 'received',\n                                        is_contract_interaction: tx.to && tx.input !== '0x'\n                                    });\n                                }\n                            }\n                        }\n                    }\n                } catch (blockError) {\n                    console.error(`Error fetching block ${currentBlock - BigInt(i)}:`, blockError);\n                    continue;\n                }\n            }\n\n            // Sort by block number (most recent first)\n            recentTransactions.sort((a, b) => {\n                const blockA = parseInt(a.block_number || '0');\n                const blockB = parseInt(b.block_number || '0');\n                return blockB - blockA;\n            });\n\n            // Calculate summary statistics\n            const sentTransactions = recentTransactions.filter(tx => tx.type === 'sent');\n            const receivedTransactions = recentTransactions.filter(tx => tx.type === 'received');\n            const contractInteractions = recentTransactions.filter(tx => tx.is_contract_interaction);\n\n            const totalSent = sentTransactions.reduce((sum, tx) => sum + parseFloat(tx.value), 0);\n            const totalReceived = receivedTransactions.reduce((sum, tx) => sum + parseFloat(tx.value), 0);\n\n            return {\n                status: \"success\",\n                message: `✅ Retrieved ${recentTransactions.length} recent transactions for ${targetAddress}`,\n                account_info: {\n                    address: targetAddress,\n                    network: agent.network,\n                    is_own_wallet: targetAddress.toLowerCase() === agent.account.address.toLowerCase(),\n                    blocks_searched: blocksToCheck,\n                    from_block: fromBlock.toString(),\n                    to_block: currentBlock.toString()\n                },\n                transaction_summary: {\n                    total_transactions: recentTransactions.length,\n                    sent_transactions: sentTransactions.length,\n                    received_transactions: receivedTransactions.length,\n                    contract_interactions: contractInteractions.length,\n                    total_eth_sent: `${totalSent.toFixed(6)} ETH`,\n                    total_eth_received: `${totalReceived.toFixed(6)} ETH`,\n                    net_eth_flow: `${(totalReceived - totalSent).toFixed(6)} ETH`\n                },\n                transactions: recentTransactions.map(tx => ({\n                    ...tx,\n                    explorer_url: `${agent.networkInfo.blockExplorer}/tx/${tx.hash}`,\n                    age: tx.timestamp ? getTimeAgo(new Date(tx.timestamp)) : 'Unknown'\n                })),\n                network_info: {\n                    network: agent.network,\n                    block_explorer: agent.networkInfo.blockExplorer,\n                    current_block: currentBlock.toString()\n                },\n                story_protocol_activity: {\n                    ip_registrations: contractInteractions.filter(tx =>\n                        tx.to?.toLowerCase().includes('story') ||\n                        tx.to?.toLowerCase().includes('ip')\n                    ).length,\n                    licensing_transactions: contractInteractions.filter(tx =>\n                        tx.to?.toLowerCase().includes('license')\n                    ).length,\n                    total_protocol_interactions: contractInteractions.length\n                },\n                next_steps: recentTransactions.length === 0\n                    ? [\n                        \"🔍 No recent transactions found\",\n                        \"💡 Start by funding your wallet with ETH\",\n                        \"🎨 Begin registering IP assets on Story Protocol\"\n                    ]\n                    : [\n                        \"✅ Transaction history retrieved successfully\",\n                        \"🔍 Click explorer URLs to view detailed transaction info\",\n                        `📊 Found ${contractInteractions.length} smart contract interactions`,\n                        \"💎 Ready to analyze Story Protocol activity\"\n                    ]\n            };\n        } catch (error: any) {\n            throw new Error(`Failed to get transaction history: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};\n\n\nconst getTimeAgo = (date: Date): string => {\n    const now = new Date();\n    const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);\n\n    if (diffInSeconds < 60) return `${diffInSeconds} seconds ago`;\n    if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)} minutes ago`;\n    if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)} hours ago`;\n    return `${Math.floor(diffInSeconds / 86400)} days ago`;\n}","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { Address, isAddress } from \"viem\";\n\nexport const ValidateAddressTool: McpTool = {\n    name: \"story_validate_address\",\n    description: \"Validate Ethereum address format and check if account exists on Story Protocol network\",\n    schema: {\n        address: z.string()\n            .describe(\"Ethereum address to validate\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const address = input.address;\n\n            // Basic format validation\n            const isValidFormat = isAddress(address);\n            \n            if (!isValidFormat) {\n                return {\n                    status: \"invalid\",\n                    message: `❌ Invalid Ethereum address format: ${address}`,\n                    validation_details: {\n                        address: address,\n                        is_valid_format: false,\n                        is_checksum_valid: false,\n                        exists_on_network: false,\n                        error: \"Invalid address format - must be 42 characters starting with 0x\"\n                    },\n                    recommendations: [\n                        \"🔍 Check that address starts with '0x'\",\n                        \"📏 Ensure address is exactly 42 characters long\",\n                        \"🔤 Verify hexadecimal characters (0-9, a-f, A-F)\",\n                        \"📋 Copy address directly from source to avoid typos\"\n                    ]\n                };\n            }\n\n            const validAddress = address as Address;\n\n              \n            // Check checksum validation (EIP-55)\n            const checksumAddress = address; // viem handles this automatically\n            const isChecksumValid = isAddress(address);\n\n \n            return {\n                status: \"valid\",\n                message: `✅ Valid Ethereum address: ${validAddress}`,\n                validation_details: {\n                    address: validAddress,\n                    is_valid_format: isValidFormat,\n                    is_checksum_valid: isChecksumValid,\n                    network: agent.network\n                },\n                network_info: {\n                    network: agent.network,\n                    chain_id: await agent.publicClient.getChainId(),\n                    block_explorer: agent.networkInfo.blockExplorer,\n                    explorer_url: `${agent.networkInfo.blockExplorer}/address/${validAddress}`\n                }\n            };\n        } catch (error: any) {\n            throw new Error(`Failed to validate address: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { parseEther, formatEther } from 'viem';\nimport { WIP_TOKEN_ADDRESS } from \"@story-protocol/core-sdk\";\n\n\nexport const WrapIPTool: McpTool = {\n    name: \"story_wrap_ip\",\n    description: \"Wrap IP tokens to WIP tokens for use in licensing and trading\",\n    schema: {\n        amount: z.number()\n            .positive()\n            .describe(\"Amount of IP tokens to wrap into WIP tokens\"),\n        check_balance: z.boolean()\n            .default(true)\n            .describe(\"Check IP balance before wrapping\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const amount = input.amount;\n            const amountWei = parseEther(amount.toString());\n\n            console.error(`🔄 Wrapping ${amount} IP tokens to WIP...`);\n\n            // Check IP balance if requested\n            if (input.check_balance) {\n                console.error(`💰 Checking IP token balance...`);\n                try {\n                    const ipBalance = await agent.publicClient.getBalance({\n                        address: agent.account.address\n                    });\n\n                    const ipBalanceFormatted = Number(formatEther(ipBalance));\n                    \n                    if (ipBalanceFormatted < amount) {\n                        throw new Error(`Insufficient IP balance. Required: ${amount} IP, Available: ${ipBalanceFormatted} IP`);\n                    }\n                    \n                    console.error(`✅ Sufficient IP balance: ${ipBalanceFormatted} IP`);\n                } catch (error) {\n                    console.error(`⚠️ Could not verify IP balance: ${error}`);\n                }\n            }\n\n            // Wrap IP to WIP using Story Protocol client\n            console.error(`🔄 Executing wrap transaction...`);\n            const response = await agent.client.wipClient.deposit({\n                amount: amountWei\n            });\n\n            // Get updated balances\n            console.error(`📊 Fetching updated balances...`); \n            let newWIPBalance = \"0\";\n\n            try { \n\n                // Get new WIP balance\n                const wipBalance = await agent.publicClient.readContract({\n                    address: WIP_TOKEN_ADDRESS, // WIP token address\n                    abi: [\n                        {\n                            name: 'balanceOf',\n                            type: 'function',\n                            stateMutability: 'view',\n                            inputs: [{ name: 'account', type: 'address' }],\n                            outputs: [{ name: '', type: 'uint256' }],\n                        }\n                    ],\n                    functionName: 'balanceOf',\n                    args: [agent.account.address]\n                });\n                newWIPBalance = formatEther(wipBalance);\n            } catch (error) {\n                console.error(`⚠️ Could not fetch updated balances: ${error}`);\n            }\n\n            console.error(`✅ Successfully wrapped ${amount} IP to WIP!`);\n\n            return {\n                status: \"success\",\n                message: `✅ Successfully wrapped ${amount} IP tokens to WIP`,\n                wrap_details: {\n                    amount_wrapped: `${amount} IP`,\n                    received: `${amount} WIP`,\n                    exchange_rate: \"1:1 (IP to WIP)\",\n                    wrapped_at: new Date().toISOString()\n                },\n                transaction_info: {\n                    tx_hash: response.txHash,\n                    block_explorer: `${agent.networkInfo.blockExplorer}/tx/${response.txHash}`,\n                    gas_used: \"Varies by network congestion\"\n                },\n                balance_changes: { \n                    wip_balance: {\n                        before: `${Number(newWIPBalance) - amount} WIP (estimated)`,\n                        after: `${newWIPBalance} WIP`,\n                        change: `+${amount} WIP`\n                    }\n                },\n                token_info: { \n                    wip_token: {\n                        name: \"Wrapped IP Token\",\n                        symbol: \"WIP\",\n                        address: WIP_TOKEN_ADDRESS,\n                        type: \"ERC20 wrapper for IP token\"\n                    }\n                },\n                use_cases: {\n                    wip_advantages: [\n                        \"🎫 Required for license token minting fees\",\n                        \"💰 Used for royalty payments\",\n                        \"🔄 ERC20 compatibility for DeFi integrations\",\n                        \"🎨 Derivative work licensing payments\",\n                        \"💱 Trading on DEXs and markets\"\n                    ],\n                    when_to_wrap: [\n                        \"Before minting license tokens with fees\",\n                        \"To pay for derivative licensing\",\n                        \"For revenue sharing payments\",\n                        \"To interact with Story Protocol contracts\",\n                        \"For trading on secondary markets\"\n                    ]\n                },\n                next_steps: [\n                    \"✅ WIP tokens ready for Story Protocol operations\",\n                    \"🎫 Use WIP for license token minting fees\",\n                    \"💰 Pay royalties and licensing fees\",\n                    \"🔄 Unwrap back to IP using story_unwrap_wip if needed\",\n                    `💎 Current WIP balance: ${newWIPBalance} WIP`\n                ]\n            };\n\n        } catch (error: any) {\n            console.error('❌ Failed to wrap IP tokens:', error);\n            throw new Error(`Failed to wrap IP tokens: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { parseEther, formatEther } from 'viem';\nimport { WIP_TOKEN_ADDRESS } from \"@story-protocol/core-sdk\";\n\n\nexport const UnwrapWIPTool: McpTool = {\n    name: \"story_unwrap_wip\",\n    description: \"Unwrap WIP tokens back to IP tokens (reverse of wrapping)\",\n    schema: {\n        amount: z.number()\n            .positive()\n            .describe(\"Amount of WIP tokens to unwrap back to IP tokens\"),\n        check_balance: z.boolean()\n            .default(true)\n            .describe(\"Check WIP balance before unwrapping\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const amount = input.amount;\n            const amountWei = parseEther(amount.toString());\n\n            console.error(`🔄 Unwrapping ${amount} WIP tokens to IP...`);\n\n            // Check WIP balance if requested\n            if (input.check_balance) {\n                console.error(`💰 Checking WIP token balance...`);\n                try {\n                    const wipBalance = await agent.publicClient.readContract({\n                        address: WIP_TOKEN_ADDRESS, // WIP token address\n                        abi: [\n                            {\n                                name: 'balanceOf',\n                                type: 'function',\n                                stateMutability: 'view',\n                                inputs: [{ name: 'account', type: 'address' }],\n                                outputs: [{ name: '', type: 'uint256' }],\n                            }\n                        ],\n                        functionName: 'balanceOf',\n                        args: [agent.account.address]\n                    });\n\n                    const wipBalanceFormatted = Number(formatEther(wipBalance));\n\n                    if (wipBalanceFormatted < amount) {\n                        throw new Error(`Insufficient WIP balance. Required: ${amount} WIP, Available: ${wipBalanceFormatted} WIP`);\n                    }\n\n                    console.error(`✅ Sufficient WIP balance: ${wipBalanceFormatted} WIP`);\n                } catch (error) {\n                    console.error(`⚠️ Could not verify WIP balance: ${error}`);\n                }\n            }\n\n            // Unwrap WIP to IP using Story Protocol client\n            console.error(`🔄 Executing unwrap transaction...`);\n            const response = await agent.client.wipClient.withdraw({\n                amount: amountWei\n            });\n\n            // Get updated balances\n            console.error(`📊 Fetching updated balances...`);\n            let newIPBalance = \"0\";\n\n            try {\n                // Get new IP balance\n                const ipBalance = await agent.publicClient.getBalance({\n                    address: agent.account.address\n                });\n                newIPBalance = formatEther(ipBalance);\n            } catch (error) {\n                console.error(`⚠️ Could not fetch updated balances: ${error}`);\n            }\n\n            console.error(`✅ Successfully unwrapped ${amount} WIP to IP!`);\n\n            return {\n                status: \"success\",\n                message: `✅ Successfully unwrapped ${amount} WIP tokens to IP`,\n                unwrap_details: {\n                    amount_unwrapped: `${amount} WIP`,\n                    received: `${amount} IP`,\n                    exchange_rate: \"1:1 (WIP to IP)\",\n                    unwrapped_at: new Date().toISOString()\n                },\n                transaction_info: {\n                    tx_hash: response.txHash,\n                    block_explorer: `${agent.networkInfo.blockExplorer}/tx/${response.txHash}`,\n                    gas_used: \"Varies by network congestion\"\n                },\n                balance_changes: { \n                    ip_balance: {\n                        before: `${Number(newIPBalance) - amount} IP (estimated)`,\n                        after: `${newIPBalance} IP`,\n                        change: `+${amount} IP`\n                    }\n                },\n                token_info: {\n                    wip_token: {\n                        name: \"Wrapped IP Token\",\n                        symbol: \"WIP\",\n                        address: WIP_TOKEN_ADDRESS,\n                        type: \"ERC20 wrapper for IP token\"\n                    }\n                },\n                use_cases: {\n                    ip_advantages: [\n                        \"🏛️ Native Story Protocol governance token\",\n                        \"🎯 Direct protocol participation\",\n                        \"💎 Long-term holding and staking\",\n                        \"🗳️ Voting on protocol proposals\",\n                        \"🔄 Can be wrapped back to WIP anytime\"\n                    ],\n                    when_to_unwrap: [\n                        \"After completing licensing operations\",\n                        \"To participate in governance voting\",\n                        \"For long-term storage as native token\",\n                        \"When no longer needing ERC20 compatibility\",\n                        \"To reduce smart contract interaction complexity\"\n                    ]\n                },\n                conversion_info: {\n                    total_wrapped_supply: \"Dynamic (based on user deposits)\",\n                    backing: \"1:1 WIP backed by IP tokens\",\n                    reversibility: \"Always reversible at 1:1 ratio\",\n                    fees: \"Only gas fees, no protocol fees\"\n                },\n                next_steps: [\n                    \"✅ IP tokens received and ready for use\",\n                    \"🏛️ Participate in Story Protocol governance\",\n                    \"💎 Hold native IP tokens long-term\",\n                    \"🔄 Wrap back to WIP using story_wrap_ip if needed\",\n                    `💰 Current IP balance: ${newIPBalance} IP`\n                ]\n            };\n\n        } catch (error: any) {\n            console.error('❌ Failed to unwrap WIP tokens:', error);\n            throw new Error(`Failed to unwrap WIP tokens: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { parseContentUrl, generateIPMetadataFromContent, validateUrl } from \"../../utils\";\nimport { createHash } from 'crypto';\nimport { Address, toHex } from 'viem';\nimport { createCommercialRemixTerms } from \"../../utils/license-terms\"\n\n\nexport const RegisterIPTool: McpTool = {\n    name: \"story_register_ip\",\n    description: \"Register IP from URLs or metadata with automatic content parsing and IPFS upload\",\n    schema: {\n        content_url: z.string()\n            .optional()\n            .describe(\"URL to content (Instagram, Twitter, ArtStation, Behance, YouTube, or direct image URL)\"),\n        title: z.string()\n            .optional()\n            .describe(\"Title of the IP asset (auto-extracted from URL if not provided)\"),\n        description: z.string()\n            .optional()\n            .describe(\"Description of the IP asset (auto-extracted from URL if not provided)\"),\n        image_url: z.string()\n            .optional()\n            .describe(\"Direct image URL if not using content_url\"),\n        media_url: z.string()\n            .optional()\n            .describe(\"Direct media URL (video, audio) if not using content_url\"),\n        creator_name: z.string()\n            .optional()\n            .describe(\"Name of the creator (defaults to wallet address)\"),\n        attributes: z.array(z.object({\n            trait_type: z.string(),\n            value: z.string()\n        }))\n            .optional()\n            .describe(\"Additional attributes for the IP asset\"),\n        commercial_use: z.boolean()\n            .default(true)\n            .describe(\"Allow commercial use of this IP\"),\n        derivatives_allowed: z.boolean()\n            .default(true)\n            .describe(\"Allow derivative works\"),\n        commercial_rev_share: z.number()\n            .min(0)\n            .max(100)\n            .default(5)\n            .describe(\"Commercial revenue share percentage for derivatives (0-100)\"),\n        minting_fee: z.number()\n            .min(0)\n            .default(1)\n            .describe(\"License minting fee in WIP tokens\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            let contentData;\n            let finalTitle = input.title;\n            let finalDescription = input.description;\n            let finalImageUrl = input.image_url;\n            let finalMediaUrl = input.media_url;\n            let finalAttributes = input.attributes || [];\n\n            // Parse content URL if provided\n            if (input.content_url) {\n                if (!validateUrl(input.content_url)) {\n                    throw new Error('Invalid URL format');\n                }\n\n                console.error(`🔍 Parsing content from URL: ${input.content_url}`);\n                contentData = await parseContentUrl(input.content_url);\n\n                // Use parsed data as defaults if not explicitly provided\n                finalTitle = finalTitle || contentData.title;\n                finalDescription = finalDescription || contentData.description;\n                finalImageUrl = finalImageUrl || contentData.imageUrl;\n                finalMediaUrl = finalMediaUrl || contentData.mediaUrl;\n\n                // Merge attributes\n                if (contentData.attributes) {\n                    finalAttributes = [...finalAttributes, ...contentData.attributes];\n                }\n            }\n\n            // Validate required fields\n            if (!finalTitle) {\n                throw new Error('Title is required (provide title or content_url)');\n            }\n            if (!finalDescription) {\n                throw new Error('Description is required (provide description or content_url)');\n            }\n\n            // Generate metadata and upload to IPFS\n            console.error(`📝 Generating metadata for IP: ${finalTitle}`);\n\n            const { ipMetadata, nftMetadata, ipfsHashes } = await generateIPMetadataFromContent(\n                {\n                    title: finalTitle,\n                    description: finalDescription,\n                    imageUrl: finalImageUrl,\n                    mediaUrl: finalMediaUrl,\n                    mediaType: contentData?.mediaType,\n                    creator: input.creator_name,\n                    platform: contentData?.platform || 'Direct Upload',\n                    originalUrl: input.content_url || '',\n                    attributes: finalAttributes\n                },\n                agent.account.address\n            );\n\n            // Generate content hashes\n            const ipHash = createHash('sha256').update(JSON.stringify(ipMetadata)).digest('hex');\n            const nftHash = createHash('sha256').update(JSON.stringify(nftMetadata)).digest('hex');\n\n            console.error(\"nft metadata :\", nftMetadata)\n\n            console.error(`📤 Uploading metadata to IPFS...`);\n            console.error(`📁 IP Metadata IPFS: ${ipfsHashes.ipMetadataHash}`);\n            console.error(`📁 NFT Metadata IPFS: ${ipfsHashes.nftMetadataHash}`);\n\n            // Prepare license terms if requested\n            console.error(`📜 Creating license terms...`);\n            const licenseTermsData = {\n                terms: createCommercialRemixTerms({\n                    defaultMintingFee: input.minting_fee,\n                    commercialRevShare: input.commercial_rev_share\n                })\n            };\n\n            // Register IP with Story Protocol\n            console.error(`🎨 Registering IP with Story Protocol...`);\n\n            const spgNftContract = agent.networkInfo.defaultSPGNFTContractAddress;\n            if (!spgNftContract) {\n                throw new Error('SPG NFT contract not configured for this network');\n            }\n\n            const response = await agent.client.ipAsset.mintAndRegisterIpAssetWithPilTerms({\n                spgNftContract: spgNftContract,\n                licenseTermsData: [\n                    licenseTermsData\n                ],\n                ipMetadata: {\n                    ipMetadataURI: `https://ipfs.io/ipfs/${ipfsHashes.ipMetadataHash}`,\n                    ipMetadataHash: `0x${ipHash}`,\n                    nftMetadataURI: `https://ipfs.io/ipfs/${ipfsHashes.nftMetadataHash}`,\n                    nftMetadataHash: `0x${nftHash}`,\n                }\n            })\n\n            console.error(`✅ IP registered successfully: ${response.ipId}`);\n\n            return {\n                status: \"success\",\n                message: `✅ Successfully registered IP: ${finalTitle}`,\n                ip_details: {\n                    ip_id: response.ipId,\n                    token_id: `${response.tokenId}`,\n                    title: finalTitle,\n                    description: finalDescription,\n                    creator: input.creator_name || 'IP Creator',\n                    creator_address: agent.account.address\n                },\n                transaction_info: {\n                    tx_hash: response.txHash,\n                    explorer_url: `${agent.networkInfo.protocolExplorer}/ipa/${response.ipId}`,\n                    block_explorer: `${agent.networkInfo.blockExplorer}/tx/${response.txHash}`\n                },\n                metadata: {\n                    ip_metadata_uri: `https://ipfs.io/ipfs/${ipfsHashes.ipMetadataHash}`,\n                    nft_metadata_uri: `https://ipfs.io/ipfs/${ipfsHashes.nftMetadataHash}`,\n                    // image_ipfs: ipfsHashes.imageHash ? `https://ipfs.io/ipfs/${ipfsHashes.imageHash}` : null,\n                    // media_ipfs: ipfsHashes.mediaHash ? `https://ipfs.io/ipfs/${ipfsHashes.mediaHash}` : null\n                },\n                license_info: {\n                    attached: true,\n                    license_terms_ids: response.licenseTermsIds?.map(id => `${id}`),\n                    commercial_use: input.commercial_use,\n                    derivatives_allowed: input.derivatives_allowed,\n                    commercial_rev_share: `${input.commercial_rev_share}%`,\n                    minting_fee: `${input.minting_fee} WIP`\n                },\n                content_source: {\n                    original_url: input.content_url,\n                    platform: contentData?.platform || 'Direct Upload',\n                    parsed_automatically: !!input.content_url\n                },\n                next_steps: [\n                    \"✅ IP asset registered and ready for licensing\",\n                    \"🎫 License terms attached - ready to mint license tokens\",\n                    \"🔗 Share your IP with the explorer URL above\",\n                    \"💰 Start earning from derivatives and licensing\"\n                ]\n            };\n\n        } catch (error: any) {\n            console.error('❌ Failed to register IP:', error);\n            throw new Error(`Failed to register IP: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { PinataSDK } from \"pinata\";\nimport { createHash } from 'crypto';\n\n/**\n * Pinata IPFS utilities for Story Protocol\n * Handles metadata and media uploads for IP registration\n */\n\n// Hardcoded Pinata configuration for development\nconst PINATA_JWT = atob(\"ZXlKaGJHY2lPaUpJVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SjFjMlZ5U1c1bWIzSnRZWFJwYjI0aU9uc2lhV1FpT2lKak0yVmhabUZrTXkwMU0yWXpMVFJrWkdNdFlURTJZaTFqWTJKbFkyRTRaV1ZpWkRJaUxDSmxiV0ZwYkNJNkluQnBjM1YwYUM1a1lXVkFaMjFoYVd3dVkyOXRJaXdpWlcxaGFXeGZkbVZ5YVdacFpXUWlPblJ5ZFdVc0luQnBibDl3YjJ4cFkza2lPbnNpY21WbmFXOXVjeUk2VzNzaVpHVnphWEpsWkZKbGNHeHBZMkYwYVc5dVEyOTFiblFpT2pFc0ltbGtJam9pUmxKQk1TSjlMSHNpWkdWemFYSmxaRkpsY0d4cFkyRjBhVzl1UTI5MWJuUWlPakVzSW1sa0lqb2lUbGxETVNKOVhTd2lkbVZ5YzJsdmJpSTZNWDBzSW0xbVlWOWxibUZpYkdWa0lqcG1ZV3h6WlN3aWMzUmhkSFZ6SWpvaVFVTlVTVlpGSW4wc0ltRjFkR2hsYm5ScFkyRjBhVzl1Vkhsd1pTSTZJbk5qYjNCbFpFdGxlU0lzSW5OamIzQmxaRXRsZVV0bGVTSTZJalpqTUdKbFpXTTNORGMzTURBME56a3lNR0U0SWl3aWMyTnZjR1ZrUzJWNVUyVmpjbVYwSWpvaU9EQXpaRGsyTWpJeFpqUTJNVGN4WlRJeU5UVXhORFkwWTJSbFlqbG1aR1F5WkdWbE16RmpNREkzTURGa09ERTRaV013WkdNellUa3pPRFJrTXpneVlpSXNJbVY0Y0NJNk1UYzRNVEkxTlRJd05YMC44ME1OZ1ZKM2lvcHJtSHBtV1B4TExMa281bWR2RnI4VTd6ZE12bmo5UGRz\")\nconst PINATA_GATEWAY = \"gold-changing-antelope-65.mypinata.cloud\";\n\n// Initialize Pinata SDK\nexport const pinata = new PinataSDK({\n    pinataJwt: PINATA_JWT,\n    pinataGateway: PINATA_GATEWAY,\n});\n\n/**\n * Upload image file to Pinata IPFS\n */\nexport const uploadImageToPinata = async (file: File): Promise<string> => {\n    try {\n        const { cid: imageHash } = await pinata.upload.public.file(file);\n        console.error(`✅ Successfully uploaded image to Pinata with hash: ${imageHash}`);\n        return imageHash;\n    } catch (error: any) {\n        console.error('❌ Failed to upload image to Pinata:', error);\n        throw new Error(`Failed to upload image to IPFS: ${error.message}`);\n    }\n};\n\n/**\n * Upload JSON metadata to Pinata IPFS\n */\nexport const uploadJsonToPinata = async (\n    name: string,\n    description: string,\n    imageHash: string,\n    properties: any = {}\n): Promise<string> => {\n    try {\n        const jsonName = `${name\n            .slice(0, 20)\n            .replace(/\\s/g, \"_\")}_${Date.now()}.json`;\n\n        const metadata = {\n            name: name,\n            description: description,\n            image: `ipfs://${imageHash}`,\n            properties,\n            // Additional Story Protocol specific fields\n            created_at: new Date().toISOString(),\n            protocol: \"Story Protocol\",\n            version: \"1.0\"\n        };\n\n        const { cid: jsonHash } = await pinata.upload.public.json(metadata, {\n            metadata: {\n                name: jsonName,\n            },\n        });\n\n        console.error(`✅ Successfully uploaded JSON ${jsonName} to Pinata with hash: ${jsonHash}`);\n        return jsonHash;\n    } catch (error: any) {\n        console.error('❌ Failed to upload JSON to Pinata:', error);\n        throw new Error(`Failed to upload JSON to IPFS: ${error.message}`);\n    }\n};\n\n/**\n * Upload Story Protocol IP metadata (follows IpMetadata standard)\n */\nexport const uploadIPMetadata = async (ipMetadata: {\n    title: string;\n    description: string;\n    creators: Array<{\n        name: string;\n        address: string;\n        contributionPercent: number;\n    }>;\n    image?: string;\n    imageHash?: string;\n    mediaUrl?: string;\n    mediaHash?: string;\n    mediaType?: string;\n    attributes?: Array<{\n        trait_type: string;\n        value: string;\n    }>;\n}): Promise<{ ipfsHash: string; contentHash: string }> => {\n    try {\n        const metadata = {\n            title: ipMetadata.title,\n            description: ipMetadata.description,\n            createdAt: Math.floor(Date.now() / 1000).toString(),\n            creators: ipMetadata.creators,\n            image: ipMetadata.image,\n            imageHash: ipMetadata.imageHash,\n            mediaUrl: ipMetadata.mediaUrl,\n            mediaHash: ipMetadata.mediaHash,\n            mediaType: ipMetadata.mediaType,\n            attributes: ipMetadata.attributes || [],\n            // Story Protocol specific fields\n            protocol: \"Story Protocol\",\n            version: \"1.0\",\n            standard: \"IpMetadata\"\n        };\n\n        const fileName = `ip_metadata_${ipMetadata.title\n            .slice(0, 20)\n            .replace(/\\s/g, \"_\")}_${Date.now()}.json`;\n\n        const { cid: ipfsHash } = await pinata.upload.public.json(metadata, {\n            metadata: {\n                name: fileName,\n                keyvalues: {\n                    type: \"ip_metadata\",\n                    protocol: \"story\",\n                    title: ipMetadata.title\n                }\n            },\n        });\n\n        // Generate content hash for Story Protocol\n        const contentHash = createHash('sha256')\n            .update(JSON.stringify(metadata))\n            .digest('hex');\n\n        console.error(`✅ Successfully uploaded IP metadata to Pinata with hash: ${ipfsHash}`);\n        console.error(`📝 Content hash: 0x${contentHash}`);\n\n        return {\n            ipfsHash,\n            contentHash: `0x${contentHash}`\n        };\n    } catch (error: any) {\n        console.error('❌ Failed to upload IP metadata to Pinata:', error);\n        throw new Error(`Failed to upload IP metadata to IPFS: ${error.message}`);\n    }\n};\n\n/**\n * Upload NFT metadata (follows OpenSea standard)\n */\nexport const uploadNFTMetadata = async (nftMetadata: {\n    name: string;\n    description: string;\n    image?: string;\n    animation_url?: string;\n    attributes?: Array<{\n        trait_type?: string;\n        key?: string;\n        value: string;\n    }>;\n    external_url?: string;\n}): Promise<{ ipfsHash: string; contentHash: string }> => {\n    try {\n        const metadata = {\n            name: nftMetadata.name,\n            description: nftMetadata.description,\n            image: nftMetadata.image,\n            animation_url: nftMetadata.animation_url,\n            external_url: nftMetadata.external_url,\n            attributes: nftMetadata.attributes || [],\n            // Additional metadata\n            created_at: new Date().toISOString(),\n            protocol: \"Story Protocol\"\n        };\n\n        const fileName = `nft_metadata_${nftMetadata.name\n            .slice(0, 20)\n            .replace(/\\s/g, \"_\")}_${Date.now()}.json`;\n\n        const { cid: ipfsHash } = await pinata.upload.public.json(metadata, {\n            metadata: {\n                name: fileName,\n                keyvalues: {\n                    type: \"nft_metadata\",\n                    protocol: \"story\",\n                    name: nftMetadata.name\n                }\n            },\n        });\n\n        // Generate content hash\n        const contentHash = createHash('sha256')\n            .update(JSON.stringify(metadata))\n            .digest('hex');\n\n        console.error(`✅ Successfully uploaded NFT metadata to Pinata with hash: ${ipfsHash}`);\n        console.error(`📝 Content hash: 0x${contentHash}`);\n\n        return {\n            ipfsHash,\n            contentHash: `0x${contentHash}`\n        };\n    } catch (error: any) {\n        console.error('❌ Failed to upload NFT metadata to Pinata:', error);\n        throw new Error(`Failed to upload NFT metadata to IPFS: ${error.message}`);\n    }\n};\n\n/**\n * Upload raw file to Pinata IPFS\n */\nexport const uploadFileToPinata = async (\n    fileBuffer: Buffer,\n    fileName: string,\n    mimeType?: string\n): Promise<string> => {\n    try {\n        const file = new File([fileBuffer], fileName, {\n            type: mimeType || 'application/octet-stream'\n        });\n\n        const { cid: fileHash } = await pinata.upload.public.file(file);\n        console.error(`✅ Successfully uploaded file ${fileName} to Pinata with hash: ${fileHash}`);\n        return fileHash;\n    } catch (error: any) {\n        console.error('❌ Failed to upload file to Pinata:', error);\n        throw new Error(`Failed to upload file to IPFS: ${error.message}`);\n    }\n};\n\n/**\n * Upload URL content to Pinata (downloads and uploads)\n */\nexport const uploadFromUrl = async (\n    url: string,\n    fileName?: string\n): Promise<string> => {\n    try {\n        console.error(`📥 Downloading content from: ${url}`);\n\n        const response = await fetch(url);\n        if (!response.ok) {\n            throw new Error(`Failed to fetch URL: ${response.statusText}`);\n        }\n\n        const contentType = response.headers.get('content-type') || 'application/octet-stream';\n        const buffer = Buffer.from(await response.arrayBuffer());\n\n        const finalFileName = fileName || `content_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n\n        const fileHash = await uploadFileToPinata(buffer, finalFileName, contentType);\n        console.error(`✅ Successfully uploaded URL content to IPFS: ${fileHash}`);\n\n        return fileHash;\n    } catch (error: any) {\n        console.error('❌ Failed to upload from URL:', error);\n        throw new Error(`Failed to upload from URL: ${error.message}`);\n    }\n};\n\n/**\n * Get IPFS URL from hash\n */\nexport const getIPFSUrl = (hash: string): string => {\n    return `https://ipfs.io/ipfs/${hash}`;\n};\n\n/**\n * Get Pinata gateway URL from hash\n */\nexport const getPinataUrl = (hash: string): string => {\n    return `https://${PINATA_GATEWAY}/ipfs/${hash}`;\n};\n\n/**\n * Verify IPFS content exists\n */\nexport const verifyIPFSContent = async (hash: string): Promise<boolean> => {\n    try {\n        const response = await fetch(getIPFSUrl(hash), { method: 'HEAD' });\n        return response.ok;\n    } catch (error) {\n        console.error(`❌ Failed to verify IPFS content: ${hash}`, error);\n        return false;\n    }\n};\n\n/**\n * Generate metadata hash for Story Protocol\n */\nexport const generateMetadataHash = (metadata: any): string => {\n    const hash = createHash('sha256')\n        .update(JSON.stringify(metadata))\n        .digest('hex');\n    return `0x${hash}`;\n};\n\n/**\n * Test Pinata connection\n */\nexport const testPinataConnection = async (): Promise<boolean> => {\n    try {\n        console.error('🔍 Testing Pinata connection...');\n\n        // Upload a small test JSON\n        const testData = {\n            test: true,\n            timestamp: Date.now(),\n            message: \"Story Protocol Pinata connection test\"\n        };\n\n        const { cid } = await pinata.upload.public.json(testData, {\n            metadata: {\n                name: `story_test_${Date.now()}.json`,\n            },\n        });\n\n        console.error(`✅ Pinata connection successful! Test file uploaded: ${cid}`);\n        return true;\n    } catch (error: any) {\n        console.error('❌ Pinata connection failed:', error);\n        return false;\n    }\n};","import axios from 'axios';\nimport { uploadFromUrl, uploadIPMetadata, uploadNFTMetadata } from './pinata';\n\n/**\n * URL parsing utilities for social media and content platforms\n * Extracts metadata and media from various platforms for IP registration\n */\n\ninterface ParsedContent {\n    title: string;\n    description: string;\n    imageUrl?: string;\n    mediaUrl?: string;\n    mediaType?: string;\n    creator?: string;\n    platform: string;\n    originalUrl: string;\n    attributes?: Array<{\n        trait_type: string;\n        value: string;\n    }>;\n}\n\n/**\n * Parse Instagram post URL\n */\nexport const parseInstagramUrl = async (url: string): Promise<ParsedContent> => {\n    try {\n        console.error(`📸 Parsing Instagram URL: ${url}`);\n\n        // Extract post ID from URL\n        const match = url.match(/\\/p\\/([A-Za-z0-9_-]+)/);\n        if (!match) {\n            throw new Error('Invalid Instagram URL format');\n        }\n\n        const postId = match[1];\n\n        // For now, return a structured format that can be enhanced with actual API calls\n        return {\n            title: `Instagram Post ${postId}`,\n            description: `Content from Instagram post ${postId}`,\n            platform: 'Instagram',\n            originalUrl: url,\n            attributes: [\n                { trait_type: 'Platform', value: 'Instagram' },\n                { trait_type: 'Post ID', value: postId },\n                { trait_type: 'Content Type', value: 'Social Media Post' }\n            ]\n        };\n    } catch (error: any) {\n        throw new Error(`Failed to parse Instagram URL: ${error.message}`);\n    }\n};\n\n/**\n * Parse Twitter/X post URL\n */\nexport const parseTwitterUrl = async (url: string): Promise<ParsedContent> => {\n    try {\n        console.error(`🐦 Parsing Twitter URL: ${url}`);\n\n        // Extract username and tweet ID\n        const match = url.match(/\\/([^\\/]+)\\/status\\/(\\d+)/);\n        if (!match) {\n            throw new Error('Invalid Twitter URL format');\n        }\n\n        const [, username, tweetId] = match;\n\n        return {\n            title: `Tweet by @${username}`,\n            description: `Content from Twitter post ${tweetId}`,\n            creator: `@${username}`,\n            platform: 'Twitter',\n            originalUrl: url,\n            attributes: [\n                { trait_type: 'Platform', value: 'Twitter' },\n                { trait_type: 'Username', value: `@${username}` },\n                { trait_type: 'Tweet ID', value: tweetId },\n                { trait_type: 'Content Type', value: 'Social Media Post' }\n            ]\n        };\n    } catch (error: any) {\n        throw new Error(`Failed to parse Twitter URL: ${error.message}`);\n    }\n};\n\n/**\n * Parse ArtStation artwork URL\n */\nexport const parseArtStationUrl = async (url: string): Promise<ParsedContent> => {\n    try {\n        console.error(`🎨 Parsing ArtStation URL: ${url}`);\n\n        // Extract artwork info from URL\n        const match = url.match(/artstation\\.com\\/artwork\\/([A-Za-z0-9]+)/);\n        if (!match) {\n            throw new Error('Invalid ArtStation URL format');\n        }\n\n        const artworkId = match[1];\n\n        return {\n            title: `ArtStation Artwork ${artworkId}`,\n            description: `Digital artwork from ArtStation`,\n            platform: 'ArtStation',\n            originalUrl: url,\n            mediaType: 'image',\n            attributes: [\n                { trait_type: 'Platform', value: 'ArtStation' },\n                { trait_type: 'Artwork ID', value: artworkId },\n                { trait_type: 'Content Type', value: 'Digital Art' },\n                { trait_type: 'Medium', value: 'Digital' }\n            ]\n        };\n    } catch (error: any) {\n        throw new Error(`Failed to parse ArtStation URL: ${error.message}`);\n    }\n};\n\n/**\n * Parse Behance project URL\n */\nexport const parseBehanceUrl = async (url: string): Promise<ParsedContent> => {\n    try {\n        console.error(`💼 Parsing Behance URL: ${url}`);\n\n        // Extract project info from URL\n        const match = url.match(/behance\\.net\\/gallery\\/([0-9]+)\\/([^?]+)/);\n        if (!match) {\n            throw new Error('Invalid Behance URL format');\n        }\n\n        const [, projectId, projectSlug] = match;\n        const projectName = projectSlug.replace(/-/g, ' ');\n\n        return {\n            title: `Behance Project: ${projectName}`,\n            description: `Creative project from Behance`,\n            platform: 'Behance',\n            originalUrl: url,\n            attributes: [\n                { trait_type: 'Platform', value: 'Behance' },\n                { trait_type: 'Project ID', value: projectId },\n                { trait_type: 'Content Type', value: 'Creative Project' }\n            ]\n        };\n    } catch (error: any) {\n        throw new Error(`Failed to parse Behance URL: ${error.message}`);\n    }\n};\n\n/**\n * Parse YouTube video URL\n */\nexport const parseYouTubeUrl = async (url: string): Promise<ParsedContent> => {\n    try {\n        console.error(`📺 Parsing YouTube URL: ${url}`);\n\n        // Extract video ID from various YouTube URL formats\n        let videoId = '';\n\n        if (url.includes('youtube.com/watch')) {\n            const match = url.match(/[?&]v=([^&]+)/);\n            if (match) videoId = match[1];\n        } else if (url.includes('youtu.be/')) {\n            const match = url.match(/youtu\\.be\\/([^?]+)/);\n            if (match) videoId = match[1];\n        }\n\n        if (!videoId) {\n            throw new Error('Invalid YouTube URL format');\n        }\n\n        return {\n            title: `YouTube Video ${videoId}`,\n            description: `Video content from YouTube`,\n            platform: 'YouTube',\n            originalUrl: url,\n            mediaType: 'video',\n            mediaUrl: url,\n            imageUrl: `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`,\n            attributes: [\n                { trait_type: 'Platform', value: 'YouTube' },\n                { trait_type: 'Video ID', value: videoId },\n                { trait_type: 'Content Type', value: 'Video' },\n                { trait_type: 'Medium', value: 'Video' }\n            ]\n        };\n    } catch (error: any) {\n        throw new Error(`Failed to parse YouTube URL: ${error.message}`);\n    }\n};\n\n/**\n * Parse generic image URL\n */\nexport const parseImageUrl = async (url: string): Promise<ParsedContent> => {\n    try {\n        console.error(`🖼️ Parsing image URL: ${url}`);\n\n        // Check if it's actually an image\n        const response = await axios.head(url);\n        const contentType = response.headers['content-type'];\n\n        if (!contentType?.startsWith('image/')) {\n            throw new Error('URL does not point to an image');\n        }\n\n        const fileName = url.split('/').pop() || 'image';\n        const extension = fileName.split('.').pop()?.toLowerCase();\n\n        return {\n            title: `Image: ${fileName}`,\n            description: `Image file from URL`,\n            platform: 'Direct URL',\n            originalUrl: url,\n            imageUrl: url,\n            mediaType: 'image',\n            attributes: [\n                { trait_type: 'Content Type', value: 'Image' },\n                { trait_type: 'File Format', value: extension?.toUpperCase() || 'Unknown' },\n                { trait_type: 'Source', value: 'Direct URL' }\n            ]\n        };\n    } catch (error: any) {\n        throw new Error(`Failed to parse image URL: ${error.message}`);\n    }\n};\n\n/**\n * Auto-detect and parse URL based on domain\n */\nexport const parseContentUrl = async (url: string): Promise<ParsedContent> => {\n    try {\n        console.error(`🔍 Auto-detecting URL type: ${url}`);\n\n        if (url.includes('instagram.com')) {\n            return await parseInstagramUrl(url);\n        } else if (url.includes('twitter.com') || url.includes('x.com')) {\n            return await parseTwitterUrl(url);\n        } else if (url.includes('artstation.com')) {\n            return await parseArtStationUrl(url);\n        } else if (url.includes('behance.net')) {\n            return await parseBehanceUrl(url);\n        } else if (url.includes('youtube.com') || url.includes('youtu.be')) {\n            return await parseYouTubeUrl(url);\n        } else {\n            // Try as image URL\n            return await parseImageUrl(url);\n        }\n    } catch (error: any) {\n        throw new Error(`Failed to parse URL: ${error.message}`);\n    }\n};\n\n/**\n * Generate IP metadata from parsed content\n */\nexport const generateIPMetadataFromContent = async (\n    content: ParsedContent,\n    creatorAddress: string,\n    additionalCreators: Array<{\n        name: string;\n        address: string;\n        contributionPercent: number;\n    }> = []\n): Promise<{\n    ipMetadata: any;\n    nftMetadata: any;\n    ipfsHashes: {\n        // imageHash?: string;\n        // mediaHash?: string;\n        ipMetadataHash: string;\n        nftMetadataHash: string;\n    };\n}> => {\n    try {\n        console.error(`📝 Generating metadata for: ${content.title}`);\n\n        // Upload media to IPFS\n        // let imageHash: string | undefined;\n        // let mediaHash: string | undefined;\n\n        // if (content.imageUrl) {\n        //     try {\n        //         imageHash = await uploadFromUrl(content.imageUrl, `image_${Date.now()}`);\n        //     } catch (error) {\n        //         console.error(`⚠️ Failed to upload image: ${error}`);\n        //     }\n        // }\n\n        // if (content.mediaUrl && content.mediaUrl !== content.imageUrl) {\n        //     try {\n        //         mediaHash = await uploadFromUrl(content.mediaUrl, `media_${Date.now()}`);\n        //     } catch (error) {\n        //         console.error(`⚠️ Failed to upload media: ${error}`);\n        //     }\n        // }\n\n        // Prepare creators array\n        const creators = [\n            {\n                name: content.creator || 'Content Creator',\n                address: creatorAddress,\n                contributionPercent: additionalCreators.length > 0 ? 80 : 100\n            },\n            ...additionalCreators\n        ];\n\n        // Generate IP metadata\n        const ipMetadata = {\n            title: content.title,\n            description: content.description,\n            creators: creators,\n            image: content.imageUrl,\n            // imageHash: imageHash,\n            mediaUrl: content.mediaUrl,\n            // mediaHash: mediaHash,\n            mediaType: content.mediaType,\n            attributes: content.attributes\n        };\n\n        // Generate NFT metadata\n        const nftMetadata = {\n            name: content.title,\n            description: content.description,\n            image: content?.imageUrl,\n            animation_url: content?.mediaUrl,\n            external_url: content.originalUrl,\n            attributes: content.attributes?.map(attr => ({\n                trait_type: attr.trait_type,\n                value: attr.value\n            }))\n        };\n\n        // Upload metadata to IPFS\n        const { ipfsHash: ipMetadataHash } = await uploadIPMetadata(ipMetadata);\n        const { ipfsHash: nftMetadataHash } = await uploadNFTMetadata(nftMetadata);\n\n        return {\n            ipMetadata,\n            nftMetadata,\n            ipfsHashes: { \n                ipMetadataHash,\n                nftMetadataHash\n            }\n        };\n    } catch (error: any) {\n        throw new Error(`Failed to generate metadata: ${error.message}`);\n    }\n};\n\n/**\n * Validate URL format\n */\nexport const validateUrl = (url: string): boolean => {\n    try {\n        new URL(url);\n        return true;\n    } catch {\n        return false;\n    }\n};\n\n/**\n * Get supported platforms\n */\nexport const getSupportedPlatforms = (): string[] => {\n    return [\n        'Instagram',\n        'Twitter/X',\n        'ArtStation',\n        'Behance',\n        'YouTube',\n        'Direct Image URLs'\n    ];\n};","import { LicenseTerms, WIP_TOKEN_ADDRESS } from '@story-protocol/core-sdk';\nimport { parseEther, zeroAddress } from 'viem';\n\n// Royalty policy addresses for Story Protocol\nexport const RoyaltyPolicyLAP = '0xBe54FB168b3c982b7AaE60dB6CF75Bd8447b390E';\nexport const RoyaltyPolicyLRP = '0x9156e603C949481883B1d3355c6f1132D191fC41';\n\n/**\n * Create commercial remix license terms\n */\nexport function createCommercialRemixTerms(terms: { \n    commercialRevShare: number; \n    defaultMintingFee: number \n}): LicenseTerms {\n    return {\n        transferable: true,\n        royaltyPolicy: RoyaltyPolicyLAP,\n        defaultMintingFee: parseEther(terms.defaultMintingFee.toString()),\n        expiration: BigInt(0),\n        commercialUse: true,\n        commercialAttribution: true,\n        commercializerChecker: zeroAddress,\n        commercializerCheckerData: '0x',\n        commercialRevShare: terms.commercialRevShare,\n        commercialRevCeiling: BigInt(0),\n        derivativesAllowed: true,\n        derivativesAttribution: true,\n        derivativesApproval: false,\n        derivativesReciprocal: true,\n        derivativeRevCeiling: BigInt(0),\n        currency: WIP_TOKEN_ADDRESS,\n        uri: 'https://github.com/piplabs/pil-document/blob/ad67bb632a310d2557f8abcccd428e4c9c798db1/off-chain-terms/CommercialRemix.json',\n    };\n}\n\n/**\n * Create non-commercial social remixing terms\n */\nexport function createNonCommercialTerms(): LicenseTerms {\n    return {\n        transferable: true,\n        royaltyPolicy: zeroAddress,\n        defaultMintingFee: 0n,\n        expiration: 0n,\n        commercialUse: false,\n        commercialAttribution: false,\n        commercializerChecker: zeroAddress,\n        commercializerCheckerData: '0x',\n        commercialRevShare: 0,\n        commercialRevCeiling: 0n,\n        derivativesAllowed: true,\n        derivativesAttribution: true,\n        derivativesApproval: false,\n        derivativesReciprocal: true,\n        derivativeRevCeiling: 0n,\n        currency: zeroAddress,\n        uri: 'https://github.com/piplabs/pil-document/blob/998c13e6ee1d04eb817aefd1fe16dfe8be3cd7a2/off-chain-terms/NCSR.json',\n    };\n}","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { Address } from 'viem';\nimport axios from 'axios';\n\n// Story Protocol API configuration\nconst STORY_API_BASE_URL = 'https://api.storyapis.com/api/v3';\nconst STORY_API_KEY = 'MhBsxkU1z9fG6TofE59KqiiWV-YlYE8Q4awlLQehF3U';\n\n// API response interfaces\ninterface StoryAPIResponse {\n    data: {\n        ancestorCount: number;\n        blockNumber: string;\n        blockTimestamp: string;\n        childrenCount: number;\n        descendantCount: number;\n        id: string;\n        ipId: string;\n        isGroup: boolean;\n        latestArbitrationPolicy: string;\n        nftMetadata: {\n            chainId: string;\n            imageUrl: string;\n            name: string;\n            tokenContract: string;\n            tokenId: string;\n            tokenUri: string;\n        };\n        parentCount: number;\n        rootCount: number;\n        rootIpIds: string[];\n        transactionHash: string;\n    };\n}\n\nexport const GetIPInfoTool: McpTool = {\n    name: \"story_get_ip_info\",\n    description: \"Get comprehensive information about an IP asset including metadata, license terms, and derivatives\",\n    schema: {\n        ip_id: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"IP asset ID (Ethereum address format)\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const ipId = input.ip_id as Address;\n            console.error(`🔍 Getting IP asset information for: ${ipId}`);\n\n            // Determine the chain based on network\n            const chain = agent.network === 'mainnet' ? 'story' : 'story-aeneid';\n            \n            console.error(`🌐 Using Story API with chain: ${chain}`);\n\n            // Fetch IP asset data from Story Protocol API\n            console.error(`📡 Fetching IP asset from Story Protocol API...`);\n            \n            const apiHeaders = {\n                'X-Api-Key': STORY_API_KEY,\n                'X-Chain': chain,\n                'Content-Type': 'application/json'\n            };\n\n            let apiResponse: StoryAPIResponse | null = null;\n            let apiError: string | null = null;\n\n            try {\n                const response = await axios.get(\n                    `${STORY_API_BASE_URL}/assets/${ipId}`,\n                    { headers: apiHeaders }\n                );\n                apiResponse = response.data;\n                console.error(`✅ Successfully fetched data from Story Protocol API`);\n            } catch (error: any) {\n                apiError = `API Error: ${error.response?.data?.message || error.message}`;\n                console.error(`⚠️ Story Protocol API error: ${apiError}`);\n            }\n\n            // Fetch additional metadata from tokenURI if available\n            let nftMetadata = null;\n            let ipMetadata = null;\n\n            if (apiResponse?.data?.nftMetadata?.tokenUri) {\n                try {\n                    console.error(`📝 Fetching NFT metadata from: ${apiResponse.data.nftMetadata.tokenUri}`);\n                    const metadataResponse = await axios.get(apiResponse.data.nftMetadata.tokenUri, {\n                        timeout: 10000\n                    });\n                    nftMetadata = metadataResponse.data;\n                    console.error(`✅ Successfully fetched NFT metadata`);\n                } catch (error: any) {\n                    console.error(`⚠️ Failed to fetch NFT metadata: ${error.message}`);\n                }\n            }\n \n        \n            // Build comprehensive response\n            const ipAssetInfo = apiResponse?.data ? {\n                // Basic IP information\n                ip_id: apiResponse.data.ipId,\n                id: apiResponse.data.id,\n                is_group: apiResponse.data.isGroup,\n                \n                // Transaction information\n                block_number: apiResponse.data.blockNumber,\n                block_timestamp: apiResponse.data.blockTimestamp,\n                transaction_hash: apiResponse.data.transactionHash,\n                \n                // NFT information\n                nft_metadata: {\n                    chain_id: apiResponse.data.nftMetadata.chainId,\n                    token_contract: apiResponse.data.nftMetadata.tokenContract,\n                    token_id: apiResponse.data.nftMetadata.tokenId,\n                    token_uri: apiResponse.data.nftMetadata.tokenUri,\n                    name: apiResponse.data.nftMetadata.name,\n                    image_url: apiResponse.data.nftMetadata.imageUrl\n                },\n                \n                // Family tree information\n                family_tree: {\n                    ancestor_count: apiResponse.data.ancestorCount,\n                    children_count: apiResponse.data.childrenCount,\n                    descendant_count: apiResponse.data.descendantCount,\n                    parent_count: apiResponse.data.parentCount,\n                    root_count: apiResponse.data.rootCount,\n                    root_ip_ids: apiResponse.data.rootIpIds\n                },\n                \n                // Policy information\n                latest_arbitration_policy: apiResponse.data.latestArbitrationPolicy\n            } : null;\n\n            console.error(`✅ Successfully retrieved IP asset information`);\n\n            return {\n                status: \"success\",\n                message: `✅ Successfully retrieved information for IP: ${ipId}`,\n                ip_asset: ipAssetInfo,\n                metadata: {\n                    nft_metadata: nftMetadata,\n                    ip_metadata: ipMetadata\n                },\n                network_info: {\n                    network: agent.network,\n                    chain: chain,\n                    explorer_url: `${agent.networkInfo.protocolExplorer}/ipa/${ipId}`\n                },\n                api_status: {\n                    story_api_success: !!apiResponse,\n                    story_api_error: apiError,\n                    metadata_fetched: !!nftMetadata\n                },\n                derivatives_info: apiResponse?.data ? {\n                    has_children: apiResponse.data.childrenCount > 0,\n                    has_descendants: apiResponse.data.descendantCount > 0,\n                    is_derivative: apiResponse.data.parentCount > 0,\n                    is_root: apiResponse.data.rootCount === 1,\n                    family_size: apiResponse.data.ancestorCount + apiResponse.data.descendantCount + 1\n                } : null,\n                licensing_info: {\n                    ready_for_licensing: !!apiResponse?.data,\n                    licensing_url: `${agent.networkInfo.protocolExplorer}/ipa/${ipId}/licenses`,\n                    can_create_derivatives: !!apiResponse?.data\n                },\n                recommendations: [\n                    apiResponse?.data ? \"✅ IP asset found and accessible\" : \"⚠️ IP asset not found in Story Protocol API\",\n                    nftMetadata ? \"✅ NFT metadata successfully loaded\" : \"⚠️ NFT metadata not available\",\n                    (apiResponse?.data?.childrenCount || 0) > 0 ? `📈 This IP has ${apiResponse?.data?.childrenCount || 0} derivative(s)` : \"📋 No derivatives found\",\n                    (apiResponse?.data?.parentCount || 0) > 0 ? `🔗 This IP is a derivative of ${apiResponse?.data?.parentCount || 0} parent(s)` : \"🌱 This is an original IP asset\",\n                    \"💡 Use story_attach_license to enable licensing\",\n                    \"🎫 Use story_mint_license to create license tokens\"\n                ]\n            };\n\n        } catch (error: any) {\n            console.error('❌ Failed to get IP info:', error);\n            throw new Error(`Failed to get IP info: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { createCommercialRemixTerms, createNonCommercialTerms } from \"../../utils\";\nimport { parseEther, zeroAddress } from 'viem';\nimport { WIP_TOKEN_ADDRESS } from '@story-protocol/core-sdk';\n\nexport const CreateLicenseTermsTool: McpTool = {\n    name: \"story_create_license_terms\",\n    description: \"Create custom PIL (Programmable IP License) terms that can be reused across multiple IP assets\",\n    schema: {\n        license_type: z.enum(['custom', 'commercial_remix', 'non_commercial', 'commercial_use'])\n            .default('custom')\n            .describe(\"Type of license to create\"),\n        \n        // Basic licensing permissions\n        commercial_use: z.boolean()\n            .default(true)\n            .describe(\"Allow commercial use of the IP\"),\n        derivatives_allowed: z.boolean()\n            .default(true)\n            .describe(\"Allow creation of derivative works\"),\n        \n        // Commercial terms\n        minting_fee: z.number()\n            .min(0)\n            .default(1)\n            .describe(\"Fee to mint license tokens (in WIP tokens)\"),\n        commercial_rev_share: z.number()\n            .min(0)\n            .max(100)\n            .default(0)\n            .describe(\"Revenue share percentage for commercial use (0-100)\"),\n        commercial_rev_ceiling: z.number()\n            .min(0)\n            .default(5)\n            .describe(\"Maximum revenue amount subject to sharing (0 = unlimited)\"),\n        \n        // Attribution requirements\n        commercial_attribution: z.boolean()\n            .default(true)\n            .describe(\"Require attribution for commercial use\"),\n        derivatives_attribution: z.boolean()\n            .default(true)\n            .describe(\"Require attribution for derivatives\"),\n        \n        // Approval requirements\n        derivatives_approval: z.boolean()\n            .default(false)\n            .describe(\"Require approval before creating derivatives\"),\n        derivatives_reciprocal: z.boolean()\n            .default(true)\n            .describe(\"Derivatives must use same license terms\"),\n        \n        // Advanced settings\n        transferable: z.boolean()\n            .default(true)\n            .describe(\"License tokens can be transferred\"),\n        expiration: z.number()\n            .min(0)\n            .default(0)\n            .describe(\"License expiration timestamp (0 = never expires)\"),\n        \n        // Custom URI for license terms\n        terms_uri: z.string()\n            .url()\n            .optional()\n            .describe(\"URI pointing to human-readable license terms\"),\n        \n        // AI-powered natural language input\n        description: z.string()\n            .optional()\n            .describe(\"Natural language description of license terms (AI will parse this)\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            let licenseTerms: any;\n            let licenseType = input.license_type;\n            let description = \"Custom license terms\";\n\n            // Handle predefined license types\n            if (licenseType === 'commercial_remix') {\n                console.error(`📜 Creating Commercial Remix license terms...`);\n                licenseTerms = createCommercialRemixTerms({\n                    defaultMintingFee: input.minting_fee || 1,\n                    commercialRevShare: input.commercial_rev_share || 5\n                });\n                description = `Commercial Remix (${input.minting_fee || 1} WIP fee, ${input.commercial_rev_share || 5}% revenue share)`;\n                \n            } else if (licenseType === 'non_commercial') {\n                console.error(`📜 Creating Non-Commercial Social Remixing license terms...`);\n                licenseTerms = createNonCommercialTerms();\n                description = \"Non-Commercial Social Remixing\";\n                \n            } else if (licenseType === 'commercial_use') {\n                console.error(`📜 Creating Commercial Use (No Derivatives) license terms...`);\n                licenseTerms = {\n                    transferable: input.transferable,\n                    royaltyPolicy: input.commercial_rev_share > 0 ? \"0xBe54FB168b3c982b7AaE60dB6CF75Bd8447b390E\" : zeroAddress,\n                    defaultMintingFee: parseEther(input.minting_fee.toString()),\n                    expiration: BigInt(input.expiration),\n                    commercialUse: true,\n                    commercialAttribution: input.commercial_attribution,\n                    commercializerChecker: zeroAddress,\n                    commercializerCheckerData: '0x',\n                    commercialRevShare: input.commercial_rev_share,\n                    commercialRevCeiling: BigInt(input.commercial_rev_ceiling),\n                    derivativesAllowed: false, // No derivatives for this type\n                    derivativesAttribution: false,\n                    derivativesApproval: false,\n                    derivativesReciprocal: false,\n                    derivativeRevCeiling: BigInt(0),\n                    currency: WIP_TOKEN_ADDRESS,\n                    uri: input.terms_uri || '',\n                };\n                description = `Commercial Use Only (${input.minting_fee} WIP fee, ${input.commercial_rev_share}% revenue share)`;\n                \n            } else {\n                // Custom license terms\n                console.error(`📜 Creating custom license terms...`);\n                \n                // Parse natural language description if provided\n                if (input.description) {\n                    console.error(`🤖 Parsing natural language: \"${input.description}\"`);\n                    // Simple AI parsing - could be enhanced with actual NLP\n                    const desc = input.description.toLowerCase();\n                    \n                    // Override settings based on natural language\n                    if (desc.includes('no commercial') || desc.includes('non-commercial')) {\n                        input.commercial_use = false;\n                    }\n                    if (desc.includes('no derivatives') || desc.includes('no remixes')) {\n                        input.derivatives_allowed = false;\n                    }\n                    if (desc.includes('free') || desc.includes('no fee')) {\n                        input.minting_fee = 0;\n                    }\n                    \n                    // Extract percentage if mentioned\n                    const percentMatch = desc.match(/(\\d+)%/);\n                    if (percentMatch) {\n                        input.commercial_rev_share = parseInt(percentMatch[1]);\n                    }\n                    \n                    // Extract fee amount\n                    const feeMatch = desc.match(/\\$?(\\d+(?:\\.\\d+)?)\\s*(?:wip|dollars?|usd)/);\n                    if (feeMatch) {\n                        input.minting_fee = parseFloat(feeMatch[1]);\n                    }\n                }\n\n                licenseTerms = {\n                    transferable: input.transferable,\n                    royaltyPolicy: (input.commercial_use && input.commercial_rev_share > 0) \n                        ? \"0xBe54FB168b3c982b7AaE60dB6CF75Bd8447b390E\" \n                        : zeroAddress,\n                    defaultMintingFee: parseEther(input.minting_fee.toString()),\n                    expiration: BigInt(input.expiration),\n                    commercialUse: input.commercial_use,\n                    commercialAttribution: input.commercial_attribution,\n                    commercializerChecker: zeroAddress,\n                    commercializerCheckerData: '0x',\n                    commercialRevShare: input.commercial_rev_share,\n                    commercialRevCeiling: BigInt(input.commercial_rev_ceiling),\n                    derivativesAllowed: input.derivatives_allowed,\n                    derivativesAttribution: input.derivatives_attribution,\n                    derivativesApproval: input.derivatives_approval,\n                    derivativesReciprocal: input.derivatives_reciprocal,\n                    derivativeRevCeiling: BigInt(0),\n                    currency: WIP_TOKEN_ADDRESS,\n                    uri: input.terms_uri || '',\n                };\n                \n                description = input.description || `Custom License (Commercial: ${input.commercial_use}, Derivatives: ${input.derivatives_allowed})`;\n            }\n\n            // Register the license terms on Story Protocol\n            console.error(`🔗 Registering license terms on Story Protocol...`);\n            \n            const response = await agent.client.license.registerPILTerms(licenseTerms);\n\n            console.error(`✅ License terms created with ID: ${response.licenseTermsId}`);\n\n            return {\n                status: \"success\",\n                message: `✅ Successfully created license terms: ${description}`,\n                license_terms: {\n                    license_terms_id: `${response.licenseTermsId}`,\n                    description: description,\n                    type: licenseType,\n                    created_by: agent.account.address\n                },\n                transaction_info: {\n                    tx_hash: response.txHash,\n                    block_explorer: `${agent.networkInfo.blockExplorer}/tx/${response.txHash}`\n                },\n                terms_details: {\n                    commercial_use: licenseTerms.commercialUse,\n                    derivatives_allowed: licenseTerms.derivativesAllowed,\n                    minting_fee: `${input.minting_fee} WIP`,\n                    commercial_rev_share: `${licenseTerms.commercialRevShare}%`,\n                    commercial_attribution: licenseTerms.commercialAttribution,\n                    derivatives_attribution: licenseTerms.derivativesAttribution,\n                    derivatives_approval: licenseTerms.derivativesApproval,\n                    derivatives_reciprocal: licenseTerms.derivativesReciprocal,\n                    transferable: licenseTerms.transferable,\n                    expires: input.expiration > 0 ? new Date(input.expiration * 1000).toISOString() : \"Never\",\n                    currency: \"WIP Token\"\n                },\n                usage_examples: [\n                    `🔗 Attach to IP: story_attach_license with license_terms_id: ${response.licenseTermsId}`,\n                    `🎫 Mint tokens: story_mint_license after attaching to IP`,\n                    `📋 Reuse: Use license_terms_id ${response.licenseTermsId} for multiple IP assets`\n                ],\n                pil_flavors_info: {\n                    available_flavors: [\n                        \"Non-Commercial Social Remixing (ID: 1) - Built-in\",\n                        \"Commercial Use (ID: 2) - Built-in\", \n                        \"Commercial Remix (ID: 3) - Built-in\",\n                        `Custom License (ID: ${response.licenseTermsId}) - Your creation`\n                    ],\n                    note: \"You can use built-in PIL flavor IDs (1, 2, 3) or your custom ID for attaching to IP assets\"\n                },\n                next_steps: [\n                    \"✅ License terms created and ready to use\",\n                    \"🔗 Attach these terms to IP assets using story_attach_license\",\n                    \"📋 Save the license_terms_id for reuse across multiple IP assets\",\n                    \"🎫 Mint license tokens after attaching to IP assets\"\n                ]\n            };\n\n        } catch (error: any) {\n            console.error('❌ Failed to create license terms:', error);\n            throw new Error(`Failed to create license terms: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { Address } from 'viem';\n\nexport const AttachLicenseTool: McpTool = {\n    name: \"story_attach_license\",\n    description: \"Attach existing license terms to an IP asset to enable licensing and monetization\",\n    schema: {\n        ip_id: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"IP asset ID to attach license terms to\"),\n        license_terms_id: z.string()\n            .describe(\"License terms ID to attach (from story_create_license_terms or built-in PIL flavors: 1, 2, 3)\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const ipId = input.ip_id as Address;\n            const licenseTermsId = input.license_terms_id;\n\n            console.error(`🔗 Attaching license terms ${licenseTermsId} to IP ${ipId}...`);\n\n            // Verify IP exists\n            // console.error(`🔍 Verifying IP asset exists...`);\n            // const ipAsset = await agent.client.ipAsset.getIpAsset({ ipId });\n            // if (!ipAsset) {\n            //     throw new Error(`IP asset not found: ${ipId}`);\n            // }\n\n            // // Check if IP is owned by current wallet\n            // if (ipAsset.owner.toLowerCase() !== agent.account.address.toLowerCase()) {\n            //     throw new Error(`You don't own this IP asset. Owner: ${ipAsset.owner}, Your address: ${agent.account.address}`);\n            // }\n\n            // Get license terms info to validate\n            let licenseTermsInfo: any;\n            try {\n                console.error(`📜 Fetching license terms ${licenseTermsId}...`);\n                licenseTermsInfo = await agent.client.license.getLicenseTerms(licenseTermsId);\n            } catch (error) {\n                throw new Error(`Invalid license terms ID: ${licenseTermsId}. Make sure it exists.`);\n            }\n\n\n            // Attach license terms\n            console.error(`🔗 Attaching license terms to IP asset...`);\n            const response = await agent.client.license.attachLicenseTerms({\n                ipId,\n                licenseTermsId\n            });\n\n            // Get attached license terms to show current state\n            // console.error(`📋 Fetching updated license terms...`);\n            // const attachedTerms = await agent.client.license.getLicensingConfig({\n            //     ipId,\n            //     licenseTermsId\n            // });\n\n            // console.error(`✅ License terms attached successfully!`);\n\n            // Determine license type description\n            let licenseDescription = \"Custom License Terms\";\n            if (licenseTermsId === \"1\") {\n                licenseDescription = \"Non-Commercial Social Remixing (PIL Flavor #1)\";\n            } else if (licenseTermsId === \"2\") {\n                licenseDescription = \"Commercial Use (PIL Flavor #2)\";\n            } else if (licenseTermsId === \"3\") {\n                licenseDescription = \"Commercial Remix (PIL Flavor #3)\";\n            }\n\n            return {\n                status: \"success\",\n                message: `✅ Successfully attached license terms to IP asset`,\n                attachment_info: {\n                    ip_id: ipId,\n                    license_terms_id: licenseTermsId,\n                    license_description: licenseDescription,\n                    attached_at: new Date().toISOString(),\n                    attached_by: agent.account.address\n                },\n                transaction_info: {\n                    tx_hash: response.txHash,\n                    block_explorer: `${agent.networkInfo.blockExplorer}/tx/${response.txHash}`,\n                    explorer_url: `${agent.networkInfo.protocolExplorer}/ipa/${ipId}`\n                },\n                license_terms_details: {\n                    commercial_use: licenseTermsInfo.commercialUse,\n                    derivatives_allowed: licenseTermsInfo.derivativesAllowed,\n                    commercial_attribution: licenseTermsInfo.commercialAttribution,\n                    derivatives_attribution: licenseTermsInfo.derivativesAttribution,\n                    derivatives_approval: licenseTermsInfo.derivativesApproval,\n                    derivatives_reciprocal: licenseTermsInfo.derivativesReciprocal,\n                    transferable: licenseTermsInfo.transferable,\n                    minting_fee: `${Number(licenseTermsInfo.mintingFee) / 1e18} WIP`,\n                    commercial_rev_share: `${licenseTermsInfo.commercialRevShare}%`,\n                    currency: licenseTermsInfo.currency || \"WIP Token\",\n                    expires: licenseTermsInfo.expiration > 0 ? new Date(Number(licenseTermsInfo.expiration) * 1000).toISOString() : \"Never\"\n                },\n                monetization_info: {\n                    revenue_model: licenseTermsInfo.commercialUse ?\n                        (licenseTermsInfo.commercialRevShare > 0 ? \"Fee + Revenue Share\" : \"Fee Only\") :\n                        \"Non-Commercial\",\n                    earnings_potential: licenseTermsInfo.commercialUse ?\n                        `${Number(licenseTermsInfo.mintingFee) / 1e18} WIP per license + ${licenseTermsInfo.commercialRevShare}% of derivative revenue` :\n                        \"Non-commercial use only\",\n                    license_token_price: `${Number(licenseTermsInfo.mintingFee) / 1e18} WIP`\n                },\n                pil_flavors_reference: {\n                    \"1\": \"Non-Commercial Social Remixing - Free derivatives, no commercial use\",\n                    \"2\": \"Commercial Use - Commercial allowed, no derivatives\",\n                    \"3\": \"Commercial Remix - Commercial + derivatives with revenue sharing\",\n                    [licenseTermsId]: licenseTermsId === \"1\" || licenseTermsId === \"2\" || licenseTermsId === \"3\" ?\n                        \"Built-in PIL Flavor\" : \"Your Custom License Terms\"\n                },\n                next_steps: [\n                    \"✅ License terms attached - IP is now licensable\",\n                    \"🎫 Mint license tokens using story_mint_license\",\n                    \"💰 Start earning from license sales and derivative revenue\",\n                    \"🔗 Share your licensable IP with the explorer URL\",\n                    licenseTermsInfo.derivativesAllowed ? \"🎨 Others can now create derivatives\" : \"⚠️ Derivatives not allowed with these terms\",\n                    licenseTermsInfo.commercialRevShare > 0 ? \"📈 You'll earn revenue share from all derivatives\" : \"\"\n                ].filter(Boolean),\n                usage_examples: [\n                    `🎫 Mint licenses: story_mint_license with ip_id: ${ipId}`,\n                    `📊 Check IP status: story_get_ip_info with ip_id: ${ipId}`,\n                    `🔍 View on explorer: ${agent.networkInfo.protocolExplorer}/ipa/${ipId}`\n                ]\n            };\n\n        } catch (error: any) {\n            console.error('❌ Failed to attach license terms:', error);\n            throw new Error(`Failed to attach license terms: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\nimport { Address, parseEther } from 'viem';\nimport { WIP_TOKEN_ADDRESS } from \"@story-protocol/core-sdk\";\n\nexport const MintLicenseTool: McpTool = {\n    name: \"story_mint_license\",\n    description: \"Mint license tokens from an IP asset with attached license terms\",\n    schema: {\n        licensor_ip_id: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .describe(\"IP asset ID that will issue the license tokens\"),\n        license_terms_id: z.string()\n            .describe(\"License terms ID to mint tokens from (must be attached to the IP)\"),\n        amount: z.number()\n            .int()\n            .min(1)\n            .default(1)\n            .describe(\"Number of license tokens to mint\"),\n        receiver: z.string()\n            .regex(/^0x[0-9a-fA-F]{40}$/)\n            .optional()\n            .describe(\"Address to receive the license tokens (defaults to your wallet)\"),\n        max_minting_fee: z.number()\n            .min(0)\n            .optional()\n            .describe(\"Maximum minting fee willing to pay in WIP tokens (for slippage protection)\"),\n        max_revenue_share: z.number()\n            .min(0)\n            .max(100)\n            .default(100)\n            .describe(\"Maximum revenue share percentage willing to accept (0-100)\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const licensorIpId = input.licensor_ip_id as Address;\n            const licenseTermsId = input.license_terms_id;\n            const amount = input.amount;\n            const receiver = (input.receiver || agent.account.address) as Address;\n\n            console.error(`🎫 Minting ${amount} license token(s) from IP ${licensorIpId}...`);\n\n            // Verify IP exists and has license terms attached\n            // console.log(`🔍 Verifying IP asset and license terms...`);\n            // const ipAsset = await agent.client.ipAsset.getIpAsset({ ipId: licensorIpId });\n            // if (!ipAsset) {\n            //     throw new Error(`IP asset not found: ${licensorIpId}`);\n            // }\n\n            // Get attached license terms\n            // const attachedTerms = await agent.client.license.getAttachedLicenseTerms({ ipId: licensorIpId });\n            // const targetTerms = attachedTerms.find((terms: any) => terms.licenseTermsId === licenseTermsId);\n\n            // if (!targetTerms) {\n            //     throw new Error(`License terms ${licenseTermsId} not attached to IP ${licensorIpId}. Available terms: ${attachedTerms.map((t: any) => t.licenseTermsId).join(', ')}`);\n            // }\n\n            // Get detailed license terms info\n            console.error(`📜 Fetching license terms details...`);\n            const licenseConfig = await agent.client.license.getLicensingConfig({\n                ipId: licensorIpId,\n                licenseTermsId\n            });\n            const { terms } = await agent.client.license.getLicenseTerms(licenseTermsId)\n            const licenseTermsInfo = terms\n\n            // Calculate minting fee\n            const mintingFeePerToken = licenseConfig.mintingFee;\n            const totalMintingFee = mintingFeePerToken * BigInt(amount);\n            const mintingFeeInWIP = Number(totalMintingFee) / 1e18;\n\n            // Check if user has sufficient WIP balance for minting fees\n            if (mintingFeePerToken > 0) {\n                console.error(`💰 Checking WIP balance for minting fee...`);\n                try {\n                    const wipBalance = await agent.publicClient.readContract({\n                        address: WIP_TOKEN_ADDRESS, // WIP token\n                        abi: [\n                            {\n                                name: 'balanceOf',\n                                type: 'function',\n                                stateMutability: 'view',\n                                inputs: [{ name: 'account', type: 'address' }],\n                                outputs: [{ name: '', type: 'uint256' }],\n                            }\n                        ],\n                        functionName: 'balanceOf',\n                        args: [agent.account.address]\n                    });\n\n                    const wipBalanceInTokens = Number(wipBalance) / 1e18;\n\n                    if (wipBalanceInTokens < mintingFeeInWIP) {\n                        throw new Error(`Insufficient WIP balance. Required: ${mintingFeeInWIP} WIP, Available: ${wipBalanceInTokens} WIP`);\n                    }\n\n                    console.error(`✅ Sufficient WIP balance: ${wipBalanceInTokens} WIP (need ${mintingFeeInWIP} WIP)`);\n                } catch (error) {\n                    console.error(`⚠️ Could not verify WIP balance: ${error}`);\n                }\n            }\n\n            // Set max minting fee if not provided\n            const maxMintingFee = input.max_minting_fee !== undefined\n                ? parseEther(input.max_minting_fee.toString())\n                : totalMintingFee + (totalMintingFee / BigInt(10)); // 10% slippage protection\n\n            // Mint license tokens\n            console.error(`🔨 Minting license tokens...`);\n            console.error(`   Amount: ${amount} tokens`);\n            console.error(`   Receiver: ${receiver}`);\n            console.error(`   Minting fee: ${mintingFeeInWIP} WIP`);\n\n            const response = await agent.client.license.mintLicenseTokens({\n                licenseTermsId,\n                licensorIpId,\n                amount,\n                receiver,\n                maxMintingFee,\n                maxRevenueShare: input.max_revenue_share\n            });\n\n            console.error(`✅ License tokens minted successfully!`);\n\n            // Determine license type description\n            let licenseDescription = \"Custom License\";\n            if (licenseTermsId === \"1\") {\n                licenseDescription = \"Non-Commercial Social Remixing\";\n            } else if (licenseTermsId === \"2\") {\n                licenseDescription = \"Commercial Use\";\n            } else if (licenseTermsId === \"3\") {\n                licenseDescription = \"Commercial Remix\";\n            }\n\n            return {\n                status: \"success\",\n                message: `✅ Successfully minted ${amount} license token(s)`,\n                minting_info: {\n                    license_token_ids: response.licenseTokenIds?.map(id => `${id}`),\n                    amount_minted: amount,\n                    receiver: receiver,\n                    licensor_ip_id: licensorIpId,\n                    license_terms_id: licenseTermsId,\n                    license_description: licenseDescription\n                },\n                transaction_info: {\n                    tx_hash: response.txHash,\n                    block_explorer: `${agent.networkInfo.blockExplorer}/tx/${response.txHash}`,\n                    ip_explorer: `${agent.networkInfo.protocolExplorer}/ipa/${licensorIpId}`\n                },\n                cost_breakdown: {\n                    minting_fee_per_token: `${Number(mintingFeePerToken) / 1e18} WIP`,\n                    total_minting_fee: `${mintingFeeInWIP} WIP`,\n                    gas_fee: \"Paid in IP (see transaction)\",\n                    total_cost: mintingFeeInWIP > 0 ? `${mintingFeeInWIP} WIP + gas` : \"Only gas fees\"\n                },\n                license_terms_summary: {\n                    commercial_use: licenseTermsInfo.commercialUse,\n                    derivatives_allowed: licenseTermsInfo.derivativesAllowed,\n                    commercial_attribution: licenseTermsInfo.commercialAttribution,\n                    derivatives_attribution: licenseTermsInfo.derivativesAttribution,\n                    transferable: licenseTermsInfo.transferable,\n                    revenue_share: `${licenseTermsInfo.commercialRevShare}%`,\n                    expires: licenseTermsInfo.expiration > 0 ?\n                        new Date(Number(licenseTermsInfo.expiration) * 1000).toISOString() : \"Never\"\n                },\n                license_token_details: response.licenseTokenIds?.map((tokenId: any, index: number) => ({\n                    token_id: `${tokenId}`,\n                    token_number: index + 1,\n                    owner: receiver,\n                    licensor_ip: licensorIpId,\n                    license_terms: licenseTermsId,\n                    can_transfer: licenseTermsInfo.transferable\n                })),\n                usage_rights: {\n                    what_you_can_do: [\n                        ...(licenseTermsInfo.commercialUse ? [\"✅ Use for commercial purposes\"] : [\"❌ No commercial use allowed\"]),\n                        ...(licenseTermsInfo.derivativesAllowed ? [\"✅ Create derivative works\"] : [\"❌ No derivatives allowed\"]),\n                        ...(licenseTermsInfo.transferable ? [\"✅ Transfer license tokens\"] : [\"❌ Cannot transfer tokens\"]),\n                        \"✅ Use according to license terms\"\n                    ],\n                    obligations: [\n                        ...(licenseTermsInfo.commercialAttribution ? [\"📝 Provide attribution for commercial use\"] : []),\n                        ...(licenseTermsInfo.derivativesAttribution ? [\"📝 Provide attribution for derivatives\"] : []),\n                        ...(licenseTermsInfo.commercialRevShare > 0 ? [`💰 Pay ${licenseTermsInfo.commercialRevShare}% revenue share`] : []),\n                        \"📋 Follow all license terms\"\n                    ]\n                },\n                derivative_workflow: licenseTermsInfo.derivativesAllowed ? {\n                    enabled: true,\n                    next_steps: [\n                        \"🎨 Create your derivative work\",\n                        \"📝 Register derivative using story_register_derivative\",\n                        `💰 Pay ${licenseTermsInfo.commercialRevShare}% revenue share to original creator`,\n                        \"🚀 Start earning from your derivative\"\n                    ]\n                } : {\n                    enabled: false,\n                    message: \"Derivatives not allowed with this license\"\n                },\n                revenue_model: licenseTermsInfo.commercialUse ? {\n                    type: licenseTermsInfo.commercialRevShare > 0 ? \"Revenue Sharing\" : \"One-time Fee\",\n                    original_creator_earns: [\n                        `💰 ${mintingFeeInWIP} WIP from this license purchase`,\n                        ...(licenseTermsInfo.commercialRevShare > 0 ? [`📈 ${licenseTermsInfo.commercialRevShare}% of your commercial revenue`] : [])\n                    ],\n                    your_obligations: licenseTermsInfo.commercialRevShare > 0 ? [\n                        `💸 Pay ${licenseTermsInfo.commercialRevShare}% of commercial revenue to original creator`,\n                        \"📊 Track and report commercial usage\"\n                    ] : [\n                        \"✅ No ongoing revenue sharing required\"\n                    ]\n                } : {\n                    type: \"Non-Commercial\",\n                    message: \"No commercial revenue allowed\"\n                },\n                next_steps: [\n                    \"✅ License tokens minted and ready to use\",\n                    ...(receiver !== agent.account.address ? [`📤 Tokens sent to ${receiver}`] : [\"💎 Tokens received in your wallet\"]),\n                    ...(licenseTermsInfo.derivativesAllowed ? [\"🎨 Create derivative works using these licenses\"] : []),\n                    ...(licenseTermsInfo.commercialUse ? [\"💼 Use for commercial purposes\"] : [\"🎭 Use for non-commercial purposes only\"]),\n                    ...(licenseTermsInfo.transferable ? [\"🔄 Transfer tokens to others if needed\"] : [])\n                ],\n                pil_reference: {\n                    license_id: licenseTermsId,\n                    type: licenseDescription,\n                    standard: \"PIL (Programmable IP License)\",\n                    chain: agent.network\n                }\n            };\n\n        } catch (error: any) {\n            console.error('❌ Failed to mint license tokens:', error);\n            throw new Error(`Failed to mint license tokens: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};","import { z } from \"zod\";\nimport { StoryAgent } from \"../../agent\";\nimport { type McpTool } from \"../../types\";\n\nexport const GenerateShowcasePlatformTool: McpTool = {\n    name: \"story_generate_showcase_platform\",\n    description: \"Generate a complete IP showcase platform with license purchasing functionality\",\n    schema: {\n        project_name: z.string()\n            .min(3)\n            .max(50)\n            .regex(/^[a-zA-Z0-9-_]+$/)\n            .describe(\"Name of the showcase platform project (e.g., 'my-art-showcase')\"),\n        ip_asset: z.object({\n            id: z.string().describe(\"Primary IP asset ID to showcase (0x...)\"),\n            title: z.string().describe(\"IP asset title\"),\n            creator: z.string().describe(\"Creator/artist name\"),\n            type: z.enum(['image', 'video', 'audio', 'text']).describe(\"Media type\")\n        }).describe(\"Primary IP asset information\"),\n        additional_assets: z.array(z.string())\n            .optional()\n            .describe(\"Additional IP asset IDs to include in portfolio\"),\n        platform_config: z.object({\n            title: z.string().describe(\"Platform title (e.g., 'My Art Collection')\"),\n            description: z.string().describe(\"Platform description for SEO\"),\n            theme: z.enum(['dark', 'light', 'creative', 'professional']).default('dark').describe(\"Visual theme\"),\n            domain: z.string().optional().describe(\"Custom domain for deployment\")\n        }).describe(\"Platform configuration\"),\n        features: z.array(z.enum([\n            'portfolio_gallery',\n            'license_purchasing',\n            'revenue_analytics',\n            'wallet_integration',\n            'social_sharing',\n            'mobile_responsive'\n        ]))\n            .default(['portfolio_gallery', 'license_purchasing', 'wallet_integration'])\n            .describe(\"Features to include in the platform\"),\n        monetization: z.object({\n            enable_licensing: z.boolean().default(true).describe(\"Enable license token sales\"),\n            license_tiers: z.array(z.object({\n                name: z.string(),\n                price: z.number(),\n                description: z.string()\n            })).optional().describe(\"Custom license tiers\")\n        }).describe(\"Monetization settings\")\n    },\n    handler: async (agent: StoryAgent, input: Record<string, any>) => {\n        try {\n            await agent.connect();\n\n            const projectName = input.project_name;\n            const ipAsset = input.ip_asset;\n            const platformConfig = input.platform_config;\n\n            // Validate IP asset exists\n            // console.error(`🔍 Validating IP asset: ${ipAsset.id}...`);\n            // const assetData = await agent.getIPAsset(ipAsset.id);\n            // if (!assetData) {\n            //     throw new Error(`IP asset not found: ${ipAsset.id}`);\n            // }\n\n            // Generate project structure\n            const projectStructure = generateProjectStructure(projectName, input);\n\n            // Generate configuration files\n            const configFiles = generateConfigFiles(projectName, ipAsset, platformConfig, input);\n\n            // Generate React components\n            const components = generateComponents(ipAsset, input.features, platformConfig.theme);\n\n            // Generate API routes\n            const apiRoutes = generateAPIRoutes(input.features);\n\n            // Generate deployment configuration\n            const deploymentConfig = generateDeploymentConfig(projectName, platformConfig);\n\n            // Generate documentation\n            const documentation = generateDocumentation(projectName, ipAsset, platformConfig, input);\n\n            console.error(`✅ Generated complete showcase platform: ${projectName}`);\n\n            return {\n                status: \"success\",\n                message: `✅ IP Showcase Platform \"${platformConfig.title}\" generated successfully!`,\n                project_details: {\n                    name: projectName,\n                    platform_title: platformConfig.title,\n                    creator_name: ipAsset.creator,\n                    primary_ip_id: ipAsset.id,\n                    theme: platformConfig.theme,\n                    features_count: input.features.length\n                },\n                generated_structure: projectStructure,\n                configuration_files: configFiles,\n                react_components: components,\n                api_routes: apiRoutes,\n                deployment_config: deploymentConfig,\n                documentation: documentation,\n                setup_instructions: {\n                    development: {\n                        commands: [\n                            `cd ${projectName}`,\n                            \"npm install\",\n                            \"cp .env.example .env.local\",\n                            \"# Configure your Story Protocol settings in .env.local\",\n                            \"npm run dev\"\n                        ],\n                        local_url: \"http://localhost:3000\",\n                        admin_url: \"http://localhost:3000/dashboard\"\n                    },\n                    production: {\n                        build_command: \"npm run build\",\n                        deploy_platforms: [\"Vercel\", \"Netlify\", \"Railway\"],\n                        domain_setup: platformConfig.domain ? `Custom domain: ${platformConfig.domain}` : \"Use platform subdomain\"\n                    }\n                },\n                platform_features: {\n                    ip_showcase: \"Professional IP asset display with metadata\",\n                    licensing_system: input.monetization.enable_licensing ? \"WIP token-based license purchasing\" : \"Display only\",\n                    wallet_support: input.features.includes('wallet_integration') ? \"MetaMask + WalletConnect\" : \"View only\",\n                    analytics: input.features.includes('revenue_analytics') ? \"Creator revenue dashboard\" : \"Basic stats\",\n                    mobile_ready: input.features.includes('mobile_responsive') ? \"Fully responsive design\" : \"Desktop optimized\"\n                },\n                integration_checklist: [\n                    \"✅ Project files generated\",\n                    \"🔄 Configure environment variables (.env.local)\",\n                    \"🔄 Test wallet connections\",\n                    \"🔄 Verify IP asset loading\",\n                    \"🔄 Deploy to hosting platform\",\n                    \"🔄 Configure custom domain (if provided)\",\n                    \"📚 Share platform with potential licensees\"\n                ],\n                live_urls: {\n                    platform: platformConfig.domain ? `https://${platformConfig.domain}` : `https://${projectName}.vercel.app`,\n                    creator_dashboard: `/dashboard`,\n                    license_purchase: `/license/${ipAsset.id}`,\n                    portfolio: input.features.includes('portfolio_gallery') ? `/portfolio` : null\n                },\n                monetization_setup: input.monetization.enable_licensing ? {\n                    license_tokens: \"Ready for WIP token purchases\",\n                    revenue_tracking: \"Automatic royalty collection\",\n                    pricing_model: input.monetization.license_tiers ? \"Custom tiers configured\" : \"Standard pricing\",\n                    payment_method: \"WIP tokens via Story Protocol\"\n                } : {\n                    display_only: \"Showcase mode - no monetization\",\n                    upgrade_path: \"Enable licensing anytime via platform settings\"\n                },\n                success_metrics: {\n                    deployment_time: \"< 5 minutes\",\n                    buyer_conversion: \"One-click license purchasing\",\n                    mobile_experience: \"Touch-optimized interface\",\n                    seo_optimized: \"Meta tags and social sharing ready\",\n                    load_speed: \"Optimized images and lazy loading\"\n                }\n            };\n\n        } catch (error: any) {\n            console.error('❌ Failed to generate showcase platform:', error);\n            throw new Error(`Failed to generate showcase platform: ${error.message}`);\n        } finally {\n            await agent.disconnect();\n        }\n    }\n};\n\n// Generate project structure\nfunction generateProjectStructure(projectName: string, input: any): any {\n    return {\n        [`${projectName}/`]: {\n            type: \"directory\",\n            description: \"Next.js 14 showcase platform with Story Protocol integration\",\n            children: {\n                \"src/\": {\n                    type: \"directory\",\n                    children: {\n                        \"app/\": {\n                            type: \"directory\",\n                            description: \"Next.js App Router pages\",\n                            children: {\n                                \"layout.tsx\": { type: \"file\", description: \"Root layout with providers\" },\n                                \"page.tsx\": { type: \"file\", description: \"Main showcase page\" },\n                                \"globals.css\": { type: \"file\", description: \"Global styles with theme\" },\n                                ...(input.features.includes('portfolio_gallery') && {\n                                    \"portfolio/\": {\n                                        type: \"directory\",\n                                        children: {\n                                            \"page.tsx\": { type: \"file\", description: \"Portfolio gallery\" }\n                                        }\n                                    }\n                                }),\n                                ...(input.monetization.enable_licensing && {\n                                    \"license/[ipId]/\": {\n                                        type: \"directory\",\n                                        children: {\n                                            \"page.tsx\": { type: \"file\", description: \"License purchase page\" }\n                                        }\n                                    }\n                                }),\n                                ...(input.features.includes('revenue_analytics') && {\n                                    \"dashboard/\": {\n                                        type: \"directory\",\n                                        children: {\n                                            \"page.tsx\": { type: \"file\", description: \"Creator analytics dashboard\" }\n                                        }\n                                    }\n                                }),\n                                \"api/\": {\n                                    type: \"directory\",\n                                    children: {\n                                        \"ip/[id]/\": {\n                                            type: \"directory\",\n                                            children: {\n                                                \"route.ts\": { type: \"file\", description: \"IP asset API endpoint\" }\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        },\n                        \"components/\": {\n                            type: \"directory\",\n                            description: \"React components\",\n                            children: {\n                                \"IPShowcase.tsx\": { type: \"file\", description: \"Main IP asset display\" },\n                                \"WalletConnect.tsx\": { type: \"file\", description: \"Wallet connection component\" },\n                                ...(input.monetization.enable_licensing && {\n                                    \"LicensePurchase.tsx\": { type: \"file\", description: \"License purchasing interface\" }\n                                }),\n                                ...(input.features.includes('portfolio_gallery') && {\n                                    \"PortfolioGrid.tsx\": { type: \"file\", description: \"IP assets grid\" }\n                                }),\n                                ...(input.features.includes('revenue_analytics') && {\n                                    \"RevenueChart.tsx\": { type: \"file\", description: \"Analytics dashboard\" }\n                                })\n                            }\n                        },\n                        \"lib/\": {\n                            type: \"directory\",\n                            description: \"Utility libraries\",\n                            children: {\n                                \"story-client.ts\": { type: \"file\", description: \"Story Protocol integration\" },\n                                \"utils.ts\": { type: \"file\", description: \"Helper functions\" }\n                            }\n                        },\n                        \"types/\": {\n                            type: \"directory\",\n                            children: {\n                                \"index.ts\": { type: \"file\", description: \"TypeScript definitions\" }\n                            }\n                        }\n                    }\n                },\n                \"public/\": {\n                    type: \"directory\",\n                    children: {\n                        \"favicon.ico\": { type: \"file\", description: \"Site favicon\" },\n                        \"images/\": { type: \"directory\", description: \"Static images\" }\n                    }\n                },\n                \"package.json\": { type: \"file\", description: \"Dependencies and scripts\" },\n                \"next.config.js\": { type: \"file\", description: \"Next.js configuration\" },\n                \"tailwind.config.js\": { type: \"file\", description: \"Tailwind CSS config\" },\n                \".env.example\": { type: \"file\", description: \"Environment variables template\" },\n                \"README.md\": { type: \"file\", description: \"Setup and usage guide\" }\n            }\n        }\n    };\n}\n\n// Generate configuration files\nfunction generateConfigFiles(projectName: string, ipAsset: any, platformConfig: any, input: any): any {\n    return {\n        \"package.json\": {\n            name: projectName,\n            version: \"1.0.0\",\n            description: platformConfig.description,\n            private: true,\n            scripts: {\n                dev: \"next dev\",\n                build: \"next build\",\n                start: \"next start\",\n                lint: \"next lint\"\n            },\n            dependencies: {\n                \"next\": \"^14.0.0\",\n                \"react\": \"^18.0.0\",\n                \"react-dom\": \"^18.0.0\",\n                \"typescript\": \"^5.0.0\",\n                \"@types/node\": \"^20.0.0\",\n                \"@types/react\": \"^18.0.0\",\n                \"tailwindcss\": \"^3.3.0\",\n                \"viem\": \"^1.18.0\",\n                \"wagmi\": \"^1.4.0\",\n                \"@story-protocol/core-sdk\": \"^1.0.0\",\n                \"lucide-react\": \"^0.263.0\",\n                \"framer-motion\": \"^10.16.0\"\n            }\n        },\n        \".env.example\": {\n            \"# Story Protocol Configuration\": \"\",\n            \"NEXT_PUBLIC_STORY_NETWORK\": \"aeneid\",\n            \"NEXT_PUBLIC_CREATOR_ADDRESS\": \"your_wallet_address\",\n            \"NEXT_PUBLIC_PRIMARY_IP_ID\": ipAsset.id, \n            \"# Platform Configuration\": \"\",\n            \"NEXT_PUBLIC_PLATFORM_TITLE\": platformConfig.title,\n            \"NEXT_PUBLIC_CREATOR_NAME\": ipAsset.creator, \n            \"# Wallet Integration\": \"\",\n            \"NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID\": \"your_walletconnect_project_id\", \n            \"# Optional Features\": \"\",\n            \"NEXT_PUBLIC_ENABLE_ANALYTICS\": input.features.includes('revenue_analytics').toString(),\n            \"NEXT_PUBLIC_ENABLE_LICENSING\": input.monetization.enable_licensing.toString()\n        },\n        \"next.config.js\": `/** @type {import('next').NextConfig} */\nconst nextConfig = {\n  experimental: {\n    appDir: true,\n  },\n  images: {\n    domains: [\n      'gateway.pinata.cloud',\n      'ipfs.io',\n      'story-protocol.s3.amazonaws.com'\n    ],\n  },\n  env: {\n    STORY_NETWORK: process.env.NEXT_PUBLIC_STORY_NETWORK,\n    PRIMARY_IP_ID: process.env.NEXT_PUBLIC_PRIMARY_IP_ID,\n  }\n};\n\nmodule.exports = nextConfig;`,\n        \"tailwind.config.js\": generateTailwindConfig(platformConfig.theme)\n    };\n}\n\n// Generate React components metadata\nfunction generateComponents(ipAsset: any, features: string[], theme: string): any {\n    const components: any = {\n        \"IPShowcase.tsx\": {\n            description: \"Hero display of IP asset with metadata and licensing info\",\n            props: [\"ipAsset\", \"featured\", \"showLicenseButton\"],\n            features: [\"Responsive design\", \"Media preview\", \"Metadata display\", \"Attribution\"]\n        },\n        \"WalletConnect.tsx\": {\n            description: \"Multi-wallet connection component\",\n            props: [\"onConnect\", \"onDisconnect\"],\n            features: [\"MetaMask support\", \"WalletConnect integration\", \"Connection status\"]\n        }\n    };\n\n    if (features.includes('portfolio_gallery')) {\n        components[\"PortfolioGrid.tsx\"] = {\n            description: \"Grid layout for multiple IP assets\",\n            props: [\"ipAssets\", \"filterBy\", \"sortBy\"],\n            features: [\"Responsive grid\", \"Filtering\", \"Search\", \"Pagination\"]\n        };\n    }\n\n    if (features.includes('license_purchasing')) {\n        components[\"LicensePurchase.tsx\"] = {\n            description: \"License token purchasing interface\",\n            props: [\"ipAsset\", \"licenseTerms\", \"onPurchase\"],\n            features: [\"WIP token integration\", \"Price calculation\", \"Transaction confirmation\"]\n        };\n    }\n\n    if (features.includes('revenue_analytics')) {\n        components[\"RevenueChart.tsx\"] = {\n            description: \"Creator revenue analytics dashboard\",\n            props: [\"revenueData\", \"timeRange\"],\n            features: [\"Interactive charts\", \"Revenue tracking\", \"License sales metrics\"]\n        };\n    }\n\n    return components;\n}\n\n// Generate API routes\nfunction generateAPIRoutes(features: string[]): any {\n    const routes: any = {\n        \"/api/ip/[id]\": {\n            methods: [\"GET\"],\n            description: \"Fetch IP asset information from Story Protocol\",\n            response: \"IP asset metadata and license terms\"\n        }\n    };\n\n    if (features.includes('license_purchasing')) {\n        routes[\"/api/license/purchase\"] = {\n            methods: [\"POST\"],\n            description: \"Process license token purchase\",\n            authentication: \"Wallet signature required\"\n        };\n    }\n\n    if (features.includes('revenue_analytics')) {\n        routes[\"/api/analytics/revenue\"] = {\n            methods: [\"GET\"],\n            description: \"Get creator revenue data\",\n            authentication: \"Creator wallet required\"\n        };\n    }\n\n    return routes;\n}\n\n// Generate deployment configuration\nfunction generateDeploymentConfig(projectName: string, platformConfig: any): any {\n    return {\n        vercel: {\n            project_name: projectName,\n            build_command: \"npm run build\",\n            output_directory: \".next\",\n            environment_variables: [\n                \"NEXT_PUBLIC_STORY_NETWORK\",\n                \"NEXT_PUBLIC_CREATOR_ADDRESS\",\n                \"NEXT_PUBLIC_PRIMARY_IP_ID\",\n                \"NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID\"\n            ]\n        },\n        netlify: {\n            build_command: \"npm run build && npm run export\",\n            publish_directory: \"out\",\n            environment_variables: \"Same as Vercel\"\n        },\n        custom_domain: platformConfig.domain ? {\n            domain: platformConfig.domain,\n            ssl: \"Automatic HTTPS\",\n            dns_setup: \"Point domain to deployment platform\"\n        } : null\n    };\n}\n\n// Generate documentation\nfunction generateDocumentation(projectName: string, ipAsset: any, platformConfig: any, input: any): any {\n    return {\n        \"README.md\": {\n            title: platformConfig.title,\n            sections: [\n                \"Overview\",\n                \"Features\",\n                \"Quick Start\",\n                \"Environment Setup\",\n                \"Development\",\n                \"Deployment\",\n                \"Story Protocol Integration\",\n                \"License\"\n            ],\n            creator_info: {\n                name: ipAsset.creator,\n                primary_asset: ipAsset.title,\n                asset_type: ipAsset.type\n            }\n        },\n        \"API_DOCUMENTATION.md\": {\n            endpoints: Object.keys(generateAPIRoutes(input.features)).length,\n            includes_examples: true,\n            authentication_guide: true\n        },\n        \"DEPLOYMENT_GUIDE.md\": {\n            platforms: [\"Vercel\", \"Netlify\", \"Railway\"],\n            domain_setup: !!platformConfig.domain,\n            environment_configuration: true\n        }\n    };\n}\n\n// Generate Tailwind config based on theme\nfunction generateTailwindConfig(theme: string): string {\n    const themeConfigs = {\n        dark: {\n            primary: '#1a1b23',\n            secondary: '#2d3748',\n            accent: '#805ad5'\n        },\n        light: {\n            primary: '#ffffff',\n            secondary: '#f7fafc',\n            accent: '#3182ce'\n        },\n        creative: {\n            primary: '#1a202c',\n            secondary: '#2d3748',\n            accent: '#ed64a6'\n        },\n        professional: {\n            primary: '#0f172a',\n            secondary: '#1e293b',\n            accent: '#059669'\n        }\n    };\n\n    const config = themeConfigs[theme as keyof typeof themeConfigs] || themeConfigs.dark;\n\n    return `/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  content: [\n    './src/pages/**/*.{js,ts,jsx,tsx,mdx}',\n    './src/components/**/*.{js,ts,jsx,tsx,mdx}',\n    './src/app/**/*.{js,ts,jsx,tsx,mdx}',\n  ],\n  theme: {\n    extend: {\n      colors: {\n        primary: '${config.primary}',\n        secondary: '${config.secondary}',\n        accent: '${config.accent}',\n        story: {\n          purple: '#8B5FBF',\n          blue: '#4F46E5'\n        }\n      },\n      backgroundImage: {\n        'story-gradient': 'linear-gradient(135deg, #8B5FBF 0%, #4F46E5 100%)'\n      }\n    },\n  },\n  plugins: [],\n}`;\n}\n","// Wallet Tools\nimport { GetWalletInfoTool } from \"./wallet/get_wallet_info_tool\";\nimport { GetAccountBalancesTool } from \"./wallet/get_account_balances_tool\";\nimport { SendETHTool } from \"./wallet/send_eth_tool\";\nimport { SendTokenTool } from \"./wallet/send_token_tool\";\nimport { ApproveTokenTool } from \"./wallet/approve_token_tool\";\nimport { CheckAllowanceTool } from \"./wallet/check_allowance_tool\";\nimport { GetTokenInfoTool } from \"./wallet/get_token_info_tool\";\nimport { GetTransactionHistoryTool } from \"./wallet/get_transaction_history_tool\";\nimport { ValidateAddressTool } from \"./wallet/validate_address_tool\";\nimport { WrapIPTool } from \"./wallet/wrap_ip_tool\";\nimport { UnwrapWIPTool } from \"./wallet/unwrap_wip_tool\";\n\n// IP & License Tools  \nimport { RegisterIPTool } from \"./ip/register_ip_tool\";\nimport { GetIPInfoTool } from \"./ip/get_ip_info_tool\";\nimport { CreateLicenseTermsTool } from \"./license/create_license_terms_tool\";\nimport { AttachLicenseTool } from \"./license/attach_license_tool\";\nimport { MintLicenseTool } from \"./license/mint_license_tool\";\n\n// Platform Generation Tools \nimport { GenerateShowcasePlatformTool } from \"./webapp/generate_showcase_platform_tool\";\n\nexport const StoryMcpTools = {\n\n    // Basic wallet information and account management\n    \"GetWalletInfoTool\": GetWalletInfoTool,                    // Get wallet address, balance, network info\n    \"GetAccountBalancesTool\": GetAccountBalancesTool,          // Get ETH, WIP, IP token balances\n    \"ValidateAddressTool\": ValidateAddressTool,                // Validate Ethereum addresses\n    \"GetTransactionHistoryTool\": GetTransactionHistoryTool,    // View recent transaction history\n\n    // Token and ETH operations\n    \"SendETHTool\": SendETHTool,                                // Send ETH for gas fees\n    \"SendTokenTool\": SendTokenTool,                            // Send WIP, IP, or other tokens\n\n    // EVM-specific token operations\n    \"ApproveTokenTool\": ApproveTokenTool,                      // Approve tokens for Story Protocol contracts\n    \"CheckAllowanceTool\": CheckAllowanceTool,                  // Check token allowances for contracts\n    \"GetTokenInfoTool\": GetTokenInfoTool,                      // Get comprehensive ERC20 token information\n\n    // Story Protocol token operations\n    \"WrapIPTool\": WrapIPTool,                                  // Wrap IP tokens to WIP (like WETH)\n    \"UnwrapWIPTool\": UnwrapWIPTool,                            // Unwrap WIP tokens back to IP\n\n    // IP Registration & Management\n    \"RegisterIPTool\": RegisterIPTool,                       // ✅ Register IP from URLs or metadata\n    \"GetIPInfoTool\": GetIPInfoTool,                         // ✅ Get IP asset details and metadata\n    // \"MintAndRegisterIPTool\": MintAndRegisterIPTool,         // Mint NFT + register IP in one tx\n    // \"BatchRegisterTool\": BatchRegisterTool,                 // Register multiple IP assets\n\n    // License Terms & Management  \n    \"CreateLicenseTermsTool\": CreateLicenseTermsTool,       // ✅ AI-powered license term creation\n    \"AttachLicenseTool\": AttachLicenseTool,                 // ✅ Attach license terms to IP\n    // \"GetLicenseTermsTool\": GetLicenseTermsTool,             // View available license terms\n\n    // License Token Operations\n    \"MintLicenseTool\": MintLicenseTool,                     // ✅ Mint license tokens for purchase \n\n    // Platform Generation\n    \"GenerateShowcasePlatformTool\": GenerateShowcasePlatformTool, // ✅ Generate complete IP showcase platform\n};\n\n// Helper function to get available tools by phase\nexport const getToolsByPhase = (phase: 'wallet' | 'core' | 'advanced' | 'platform') => {\n    const toolEntries = Object.entries(StoryMcpTools);\n\n    switch (phase) {\n        case 'wallet':\n            return toolEntries.filter(([name]) =>\n                name.includes('Wallet') ||\n                name.includes('Account') ||\n                name.includes('Send') ||\n                name.includes('Approve') ||\n                name.includes('Transaction') ||\n                name.includes('Validate')\n            );\n        case 'core':\n            return toolEntries.filter(([name]) =>\n                name.includes('IP') ||\n                name.includes('License') ||\n                name.includes('Register')\n            );\n        case 'advanced':\n            return toolEntries.filter(([name]) =>\n                name.includes('Derivative') ||\n                name.includes('Revenue') ||\n                name.includes('Royalty')\n            );\n        case 'platform':\n            return toolEntries.filter(([name]) =>\n                name.includes('Generate') ||\n                name.includes('Marketplace') ||\n                name.includes('Portfolio')\n            );\n        default:\n            return toolEntries;\n    }\n};\n\n// Get count of implemented tools\nexport const getImplementationStatus = () => {\n    const allTools = Object.keys(StoryMcpTools);\n    const implementedTools = allTools.filter(toolName => StoryMcpTools[toolName as keyof typeof StoryMcpTools]);\n\n    return {\n        total_defined: allTools.length,\n        implemented: implementedTools.length,\n        completion_percentage: Math.round((implementedTools.length / allTools.length) * 100),\n        phases: {\n            wallet: getToolsByPhase('wallet').length,\n            core: getToolsByPhase('core').length,\n            advanced: getToolsByPhase('advanced').length,\n            platform: getToolsByPhase('platform').length\n        }\n    };\n};","import { client, publicClient, walletClient, account, network, networkInfo } from '../config';\n// import { Address } from 'viem';\n// import { IpMetadata, WIP_TOKEN_ADDRESS } from '@story-protocol/core-sdk'; \n// import { \n//     IPAssetData, \n//     LicenseTerms, \n//     LicenseToken, \n//     RevenueInfo,\n//     RegisterIPInput,\n//     CreateLicenseInput,\n//     MintLicenseInput,\n//     RegisterDerivativeInput,\n//     PayRoyaltyInput,\n//     ClaimRevenueInput,\n//     StoryResult \n// } from '../types'; \n\nexport class StoryAgent {\n    public client: typeof client;\n    public account: typeof account;\n    public walletClient: typeof walletClient;\n    public publicClient: typeof publicClient;\n    public network: typeof network;\n    public networkInfo: typeof networkInfo;\n\n    constructor() {\n        // Use the configured clients from config\n        this.client = client;\n        this.account = account;\n        this.walletClient = walletClient;\n        this.publicClient = publicClient;\n        this.network = network;\n        this.networkInfo = networkInfo;\n\n        console.error(`🎨 Story Agent initialized on ${this.network}`);\n        console.error(`📍 Wallet address: ${this.account.address}`);\n    }\n\n    async connect(): Promise<void> {\n        try {\n            // Test connection by getting chain ID\n            const chainId = await this.publicClient.getChainId();\n            console.error(`✅ Connected to Story Protocol (Chain ID: ${chainId})`);\n            console.error(`🌐 Network: ${this.network}`);\n            console.error(`🔗 Explorer: ${this.networkInfo.protocolExplorer}`);\n        } catch (error) {\n            console.error('❌ Failed to connect to Story Protocol:', error);\n            throw error;\n        }\n    }\n\n    async disconnect(): Promise<void> {\n        console.error('🔌 Disconnected from Story Protocol');\n    }\n\n    async getWalletInfo(): Promise<any> {\n        try {\n            const balance = await this.publicClient.getBalance({\n                address: this.account.address\n            });\n\n            return {\n                address: this.account.address,\n                balance: balance.toString(),\n                network: this.network,\n                chainId: await this.publicClient.getChainId(),\n                blockExplorer: this.networkInfo.blockExplorer,\n                protocolExplorer: this.networkInfo.protocolExplorer\n            };\n        } catch (error) {\n            console.error('Failed to get wallet info:', error);\n            throw error;\n        }\n    }\n \n}\n"],"mappings":"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","names":["network","z","z","parseEther","formatEther","WIP_TOKEN_ADDRESS","z","parseEther","formatEther","WIP_TOKEN_ADDRESS","z","formatEther","WIP_TOKEN_ADDRESS","maxUint256","z","formatEther","WIP_TOKEN_ADDRESS","z","formatEther","z","z","parseEther","formatEther","WIP_TOKEN_ADDRESS","z","parseEther","formatEther","WIP_TOKEN_ADDRESS","z","WIP_TOKEN_ADDRESS","parseEther","parseEther","WIP_TOKEN_ADDRESS","createHash","z","createHash","z","axios","z","parseEther","zeroAddress","WIP_TOKEN_ADDRESS","z","z","z","parseEther","WIP_TOKEN_ADDRESS","z","config"]}