Skip to main content
Glama
subgraph.e2e.test.ts7.14 kB
import { afterAll, afterEach, beforeAll, describe, expect, setDefaultTimeout, test } from "bun:test"; import { copyFile, readFile, rmdir, stat } from "node:fs/promises"; import { join } from "node:path"; import { loadEnv } from "@settlemint/sdk-utils/environment"; import { exists } from "@settlemint/sdk-utils/filesystem"; import type { DotEnv } from "@settlemint/sdk-utils/validation"; import { $ } from "bun"; import { getSubgraphConfig, getSubgraphYamlConfig, updateSubgraphConfig, } from "../sdk/cli/src/utils/subgraph/subgraph-config"; import { PRIVATE_KEY_SMART_CONTRACTS_NAMES } from "./constants/test-resources"; import { retryCommand } from "./utils/retry-command"; import { forceExitAllCommands, runCommand } from "./utils/run-command"; import { findPrivateKeyByName } from "./utils/test-resources"; const PROJECT_NAME = "contracts-subgraphs"; const COMMAND_TEST_SCOPE = __filename; const USE_CASE = "solidity-token-erc721"; const SUBGRAPH_NAME = "token-erc721"; const projectDir = join(__dirname, PROJECT_NAME); setDefaultTimeout(15 * 60_000); async function cleanup() { try { if (await exists(projectDir)) { await rmdir(projectDir, { recursive: true }); } } catch (err) { console.log("Failed to delete project dir", err); } } beforeAll(cleanup); afterAll(cleanup); afterEach(() => { forceExitAllCommands(COMMAND_TEST_SCOPE); }); describe("Build and deploy a subgraph using the SDK", () => { let contractsDeploymentInfo: Record<string, string>; test("Create a smart contract set and install packages", async () => { const { output } = await runCommand( COMMAND_TEST_SCOPE, ["smart-contract-set", "create", "--project-name", PROJECT_NAME, "--use-case", USE_CASE], { cwd: __dirname }, ).result; expect((await stat(projectDir)).isDirectory()).toBeTrue(); expect(output).toInclude("Your smart contract set is ready to go!"); await $`bun install --save-text-lockfile`.cwd(projectDir); if (await exists(join(__dirname, "../.env"))) { await copyFile(join(__dirname, "../.env"), join(projectDir, ".env")); } if (await exists(join(__dirname, "../.env.local"))) { await copyFile(join(__dirname, "../.env.local"), join(projectDir, ".env.local")); } }); test("Deploy smart contract and get address info", async () => { const deploymentId = "diamond-bond"; let retries = 0; const { output: deployOutput } = await retryCommand(async () => { const privateKey = await findPrivateKeyByName(PRIVATE_KEY_SMART_CONTRACTS_NAMES[retries]!); retries++; return runCommand( COMMAND_TEST_SCOPE, [ "scs", "hardhat", "deploy", "remote", "--default-sender", privateKey?.address!, "--deployment-id", deploymentId, "--accept-defaults", ], { cwd: projectDir, env: { HARDHAT_IGNITION_CONFIRM_DEPLOYMENT: "false", }, }, ).result; }); const deploymentInfoData = await readFile( join(projectDir, "ignition", "deployments", deploymentId, "deployed_addresses.json"), ); contractsDeploymentInfo = JSON.parse(deploymentInfoData.toString()); expect(deployOutput).toInclude("successfully deployed 🚀"); }); test("Build subgraph", async () => { const { output } = await runCommand(COMMAND_TEST_SCOPE, ["smart-contract-set", "subgraph", "build"], { cwd: projectDir, }).result; expect(output).toInclude("Build completed"); const subgraphYaml = await getSubgraphYamlConfig(projectDir); expect(subgraphYaml.dataSources).toHaveLength(5); expect(subgraphYaml.dataSources.map((ds) => ds.name)).toEqual([ "erc721", "pausable", "ownable", "erc721ipfs", "erc721freezable", ]); }); test("Codegen subgraph", async () => { const { output } = await runCommand(COMMAND_TEST_SCOPE, ["smart-contract-set", "subgraph", "codegen"], { cwd: projectDir, }).result; expect(output).toInclude("Types generated successfully"); }); test("Deploy subgraphs (invalid subgraph.config.json)", async () => { const command = runCommand(COMMAND_TEST_SCOPE, ["smart-contract-set", "subgraph", "deploy", "--accept-defaults"], { cwd: projectDir, }); const outputs: string[] = []; command.stdout.on("data", (data: Buffer) => { outputs.push(data.toString()); }); expect(() => command.result).toThrow(); expect(outputs.join("\n")).toMatch( /The "subgraph\/subgraph\.config\.json" config has not been set, ensure all the contracts listed have an address added/i, ); }); test("Deploy subgraphs (fix subgraph.config.json and deploy)", async () => { const config = await getSubgraphConfig(projectDir); const datasourceMap = { ExampleERC721: "ExampleERC721Module#ExampleERC721", }; expect(config).toBeDefined(); expect(config).not.toBeNull(); await updateSubgraphConfig( { ...config!, datasources: config!.datasources.map((source) => { const addressKey = datasourceMap[source.name as keyof typeof datasourceMap]; const address = addressKey ? contractsDeploymentInfo[addressKey]! : source.address; return { ...source, address, }; }), }, projectDir, ); const { output } = await retryCommand( () => runCommand( COMMAND_TEST_SCOPE, ["smart-contract-set", "subgraph", "deploy", "--accept-defaults", SUBGRAPH_NAME], { cwd: projectDir, }, ).result, ); expect(output).toInclude("Build completed"); const env: Partial<DotEnv> = await loadEnv(false, false, projectDir); expect(env.SETTLEMINT_THEGRAPH_SUBGRAPHS_ENDPOINTS).toBeArray(); const subgraphDeployed = env.SETTLEMINT_THEGRAPH_SUBGRAPHS_ENDPOINTS?.some((endpoint) => endpoint.endsWith(`/subgraphs/name/${SUBGRAPH_NAME}`), ); if (!subgraphDeployed) { expect(env.SETTLEMINT_THEGRAPH_SUBGRAPHS_ENDPOINTS).toInclude(SUBGRAPH_NAME); } else { expect(subgraphDeployed).toBeTrue(); } }); test("Remove subgraph", async () => { const { output } = await retryCommand( () => runCommand( COMMAND_TEST_SCOPE, ["smart-contract-set", "subgraph", "remove", "--accept-defaults", "--force", SUBGRAPH_NAME], { cwd: projectDir, }, ).result, ); expect(output).toInclude(`Subgraph ${SUBGRAPH_NAME} removed successfully`); const env: Partial<DotEnv> = await loadEnv(false, false, projectDir); expect(env.SETTLEMINT_THEGRAPH_SUBGRAPHS_ENDPOINTS).toBeArray(); const subgraphDeployed = env.SETTLEMINT_THEGRAPH_SUBGRAPHS_ENDPOINTS?.some((endpoint) => endpoint.endsWith(`/subgraphs/name/${SUBGRAPH_NAME}`), ); if (subgraphDeployed) { expect(env.SETTLEMINT_THEGRAPH_SUBGRAPHS_ENDPOINTS?.join(",")).not.toInclude(SUBGRAPH_NAME); } else { expect(subgraphDeployed).toBeFalse(); } }); });

Latest Blog Posts

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/settlemint/sdk'

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