Skip to main content
Glama

OpenZeppelin Contracts MCP Server

Official
by OpenZeppelin
test.ts3.11 kB
import { promises as fs } from 'fs'; import type { TestFn, ExecutionContext } from 'ava'; import _test from 'ava'; import hre from 'hardhat'; import path from 'path'; import { generateSources, writeGeneratedSources } from './generate/sources'; import type { GenericOptions, KindedOptions } from './build-generic'; import { custom, erc1155, stablecoin, erc20, erc721, governor } from './api'; interface Context { generatedSourcesPath: string; } const test = _test as TestFn<Context>; test.serial('erc20 result compiles', async t => { await testCompile(t, 'ERC20'); }); test.serial('erc721 result compiles', async t => { await testCompile(t, 'ERC721'); }); test.serial('erc1155 result compiles', async t => { await testCompile(t, 'ERC1155'); }); test.serial('stablecoin result compiles', async t => { await testCompile(t, 'Stablecoin'); }); test.serial('account result compiles', async t => { await testCompile(t, 'Account'); }); test.serial('governor result compiles', async t => { await testCompile(t, 'Governor'); }); test.serial('custom result compiles', async t => { await testCompile(t, 'Custom'); }); async function testCompile(t: ExecutionContext<Context>, kind: keyof KindedOptions) { const generatedSourcesPath = path.join(hre.config.paths.sources, `generated`); await fs.rm(generatedSourcesPath, { force: true, recursive: true }); await writeGeneratedSources(generatedSourcesPath, 'all', kind); // We only want to check that contracts compile and we don't care about any // of the outputs. Setting empty outputSelection causes compilation to go a // lot faster and not run out of memory. for (const { settings } of hre.config.solidity.compilers) { settings.outputSelection = {}; } await hre.run('compile'); t.pass(); } function isAccessControlRequired(opts: GenericOptions) { switch (opts.kind) { case 'ERC20': return erc20.isAccessControlRequired(opts); case 'ERC721': return erc721.isAccessControlRequired(opts); case 'ERC1155': return erc1155.isAccessControlRequired(opts); case 'Stablecoin': return stablecoin.isAccessControlRequired(opts); case 'RealWorldAsset': return stablecoin.isAccessControlRequired(opts); case 'Account': throw new Error(`Not applicable for ${opts.kind}`); case 'Governor': return governor.isAccessControlRequired(opts); case 'Custom': return custom.isAccessControlRequired(opts); default: throw new Error('No such kind'); } } test('is access control required', async t => { for (const contract of generateSources('all')) { const regexOwnable = /import.*Ownable(Upgradeable)?.sol.*/gm; switch (contract.options.kind) { case 'Account': break; default: { if (!contract.options.access) { if (isAccessControlRequired(contract.options)) { t.regex(contract.source, regexOwnable, JSON.stringify(contract.options)); } else { t.notRegex(contract.source, regexOwnable, JSON.stringify(contract.options)); } } } } } });

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/OpenZeppelin/contracts-wizard'

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