Skip to main content
Glama

Polygon MCP Server

by Dablclub
handlers.ts6.78 kB
import { encodeFunctionData, erc20Abi, formatUnits, isAddress, parseUnits, type Abi, type AbiFunction, type Account, type PublicActions, type WalletClient, } from "viem"; import type { z } from "zod"; import type { CallContractSchema, DeployPropertyNFTSchema, DeployPropertyTokenSchema, DeployPropertyYieldVaultSchema, Erc20BalanceSchema, Erc20TransferSchema, } from "./schemas.js"; import { constructPolygonScanUrl } from "../utils/index.js"; import { polygon } from "viem/chains"; import { PropertyNFT } from "../contracts/PropertyNFT.js"; import { PropertyToken } from "../contracts/PropertyToken.js"; import { PropertyYieldVault } from "../contracts/PropertyYieldVault.js"; export async function deployPropertyNFTHandler( wallet: WalletClient & PublicActions, args: z.infer<typeof DeployPropertyNFTSchema> ): Promise<string> { if (!wallet.account?.address) { throw new Error("No account address available"); } const hash = await wallet.deployContract({ abi: PropertyNFT.abi, account: wallet.account, chain: wallet.chain, bytecode: PropertyNFT.bytecode as `0x${string}`, }); // Return transaction hash and PolygonScan URL return JSON.stringify({ hash, url: constructPolygonScanUrl(wallet.chain ?? polygon, hash), }); } export async function deployPropertyTokenHandler( wallet: WalletClient & PublicActions, args: z.infer<typeof DeployPropertyTokenSchema> ): Promise<string> { if (!wallet.account?.address) { throw new Error("No account address available"); } // Validate addresses if (!isAddress(args.propertyNFTAddress)) { throw new Error(`Invalid PropertyNFT address: ${args.propertyNFTAddress}`); } const hash = await wallet.deployContract({ abi: PropertyToken.abi, account: wallet.account, chain: wallet.chain, bytecode: PropertyToken.bytecode as `0x${string}`, args: [ args.propertyNFTAddress, BigInt(args.propertyId), args.name, args.symbol, ], }); // Return transaction hash and PolygonScan URL return JSON.stringify({ hash, url: constructPolygonScanUrl(wallet.chain ?? polygon, hash), }); } export async function deployPropertyYieldVaultHandler( wallet: WalletClient & PublicActions, args: z.infer<typeof DeployPropertyYieldVaultSchema> ): Promise<string> { if (!wallet.account?.address) { throw new Error("No account address available"); } // Validate addresses if (!isAddress(args.assetAddress)) { throw new Error(`Invalid asset address: ${args.assetAddress}`); } if (!isAddress(args.propertyNFTAddress)) { throw new Error(`Invalid PropertyNFT address: ${args.propertyNFTAddress}`); } const hash = await wallet.deployContract({ abi: PropertyYieldVault.abi, account: wallet.account, chain: wallet.chain, bytecode: PropertyYieldVault.bytecode as `0x${string}`, args: [ args.assetAddress, args.name, args.symbol, args.propertyNFTAddress, BigInt(args.propertyId), ], }); // Return transaction hash and PolygonScan URL return JSON.stringify({ hash, url: constructPolygonScanUrl(wallet.chain ?? polygon, hash), }); } export async function getAddressHandler( wallet: WalletClient & PublicActions ): Promise<string> { if (!wallet.account?.address) { throw new Error("No account address available"); } return wallet.account.address; } export async function callContractHandler( wallet: WalletClient & PublicActions, args: z.infer<typeof CallContractSchema> ): Promise<string> { let abi: string | Abi = args.abi; try { abi = JSON.parse(abi) as Abi; } catch (error) { throw new Error(`Invalid ABI: ${error}`); } if (!isAddress(args.contractAddress, { strict: false })) { throw new Error(`Invalid contract address: ${args.contractAddress}`); } let functionAbi: AbiFunction | undefined; try { functionAbi = abi.find( (item) => "name" in item && item.name === args.functionName ) as AbiFunction; } catch (error) { throw new Error(`Invalid function name: ${args.functionName}`); } if ( functionAbi.stateMutability === "view" || functionAbi.stateMutability === "pure" ) { const tx = await wallet.readContract({ address: args.contractAddress, abi, functionName: args.functionName, args: args.functionArgs, }); return String(tx); } const tx = await wallet.simulateContract({ account: wallet.account, abi, address: args.contractAddress, functionName: args.functionName, value: BigInt(args.value ?? 0), args: args.functionArgs, }); const txHash = await wallet.writeContract(tx.request); return JSON.stringify({ hash: txHash, url: constructPolygonScanUrl(wallet.chain ?? polygon, txHash), }); } export async function erc20BalanceHandler( wallet: WalletClient & PublicActions, args: z.infer<typeof Erc20BalanceSchema> ): Promise<string> { const { contractAddress } = args; if (!isAddress(contractAddress, { strict: false })) { throw new Error(`Invalid contract address: ${contractAddress}`); } const balance = await wallet.readContract({ address: contractAddress, abi: erc20Abi, functionName: "balanceOf", args: [wallet.account?.address ?? "0x"], }); const decimals = await wallet.readContract({ address: contractAddress, abi: erc20Abi, functionName: "decimals", }); return formatUnits(balance, decimals); } export async function erc20TransferHandler( wallet: WalletClient & PublicActions, args: z.infer<typeof Erc20TransferSchema> ): Promise<string> { const { contractAddress, toAddress, amount } = args; if (!isAddress(contractAddress, { strict: false })) { throw new Error(`Invalid contract address: ${contractAddress}`); } if (!isAddress(toAddress, { strict: false })) { throw new Error(`Invalid to address: ${toAddress}`); } // Get decimals for token const decimals = await wallet.readContract({ address: contractAddress, abi: erc20Abi, functionName: "decimals", }); // Format units const atomicUnits = parseUnits(amount, decimals); const tx = await wallet.simulateContract({ address: contractAddress, abi: erc20Abi, functionName: "transfer", args: [toAddress, atomicUnits], account: wallet.account, chain: wallet.chain, }); const txHash = await wallet.writeContract(tx.request); return JSON.stringify({ hash: txHash, url: constructPolygonScanUrl(wallet.chain ?? polygon, txHash), }); } export async function getGasPriceHandler( wallet: WalletClient & PublicActions ): Promise<string> { const gasPrice = await wallet.getGasPrice(); return formatUnits(gasPrice, 9) + " Gwei"; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Dablclub/polygon-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server