From 248fdd366df6d68139c7f14c3da502b0aa1708aa Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Fri, 27 Mar 2026 15:00:43 -0700 Subject: [PATCH 1/6] chore: require pnpm >=10 in engines pnpm 9 reached end-of-life; align `engines.pnpm` with the pinned packageManager so older pnpm gets rejected on install rather than failing later with cryptic lockfile errors. --- .github/workflows/ci.yml | 4 ---- .github/workflows/pr.yml | 2 -- .github/workflows/release.yml | 1 - package.json | 3 ++- 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f7c21d7e..1d54ccde9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,6 @@ jobs: with: nodeVersion: 20 packageManager: pnpm - packageManagerVersion: 9 - name: Lint run: pnpm lint @@ -46,7 +45,6 @@ jobs: with: nodeVersion: ${{ matrix.node-version }} packageManager: pnpm - packageManagerVersion: 9 - name: Setup git user information run: | @@ -78,7 +76,6 @@ jobs: with: nodeVersion: 20 packageManager: pnpm - packageManagerVersion: 9 - name: Build Packages run: pnpm build @@ -108,7 +105,6 @@ jobs: with: nodeVersion: 20 packageManager: pnpm - packageManagerVersion: 9 - name: Build Packages run: pnpm build # will also check types diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 1f359f9f0..5bcb7489b 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -26,7 +26,6 @@ jobs: buildScript: build nodeVersion: 20 packageManager: pnpm - packageManagerVersion: 9 secrets: githubToken: ${{ secrets.GITHUB_TOKEN }} npmToken: ${{ secrets.NPM_TOKEN }} @@ -39,7 +38,6 @@ jobs: buildScript: build nodeVersion: 20 packageManager: pnpm - packageManagerVersion: 9 restoreDeletedChangesets: true secrets: githubToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 26948f5cc..f55aaaeda 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,6 @@ jobs: with: nodeVersion: 20 packageManager: pnpm - packageManagerVersion: 9 - name: Import bot's GPG key for signing commits id: import-gpg diff --git a/package.json b/package.json index 3ce7350e4..3a6138b03 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,9 @@ "private": true, "engines": { "node": ">=20.0.0", - "pnpm": "9" + "pnpm": ">=10" }, + "packageManager": "pnpm@10.17.1", "scripts": { "build": "pnpm --filter=@graphprotocol/graph-* build", "lint": "pnpm lint:prettier && pnpm lint:eslint", From 9986480d3c07be9c3961d30fba3d6e2062bdd356 Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Wed, 21 Jan 2026 14:20:25 -0800 Subject: [PATCH 2/6] docs: add CLAUDE.md files for AI-assisted development Add documentation files to help Claude (and developers) understand the codebase structure, key patterns, and development workflows. Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 63 +++++++++++++++++ packages/cli/CLAUDE.md | 135 +++++++++++++++++++++++++++++++++++++ packages/ts/CLAUDE.md | 150 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 348 insertions(+) create mode 100644 CLAUDE.md create mode 100644 packages/cli/CLAUDE.md create mode 100644 packages/ts/CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..e5ac66061 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,63 @@ +# The Graph Protocol Tooling Monorepo + +Tools for building and deploying subgraphs on The Graph Network. + +## Packages + +| Package | Description | Docs | +|---------|-------------|------| +| `@graphprotocol/graph-cli` | CLI for init, codegen, build, deploy | [packages/cli/CLAUDE.md](packages/cli/CLAUDE.md) | +| `@graphprotocol/graph-ts` | AssemblyScript library for mappings | [packages/ts/CLAUDE.md](packages/ts/CLAUDE.md) | + +## Development Setup + +```bash +# Requirements: Node.js 20+, pnpm 10 +pnpm install +pnpm build +``` + +## Common Commands + +```bash +# Build all packages +pnpm build + +# Run tests +pnpm test # All packages +pnpm test:cli # CLI only +pnpm test:ts # graph-ts only + +# Code quality +pnpm lint # Check formatting + linting +pnpm lint:fix # Auto-fix issues +pnpm type-check # TypeScript type checking +``` + +## Code Style + +- ESLint with `@theguild/eslint-config` +- Prettier with `@theguild/prettier-config` +- TypeScript strict mode + +## Release Process + +Uses [Changesets](https://github.com/changesets/changesets) for versioning: + +```bash +# Add a changeset for your changes +pnpm changeset + +# Release (builds + publishes) +pnpm release +``` + +## Project Structure + +``` +├── packages/ +│ ├── cli/ # @graphprotocol/graph-cli +│ └── ts/ # @graphprotocol/graph-ts +├── patches/ # pnpm patches for dependencies +└── .changeset/ # Changesets configuration +``` diff --git a/packages/cli/CLAUDE.md b/packages/cli/CLAUDE.md new file mode 100644 index 000000000..68cf9c2c1 --- /dev/null +++ b/packages/cli/CLAUDE.md @@ -0,0 +1,135 @@ +# @graphprotocol/graph-cli + +CLI for building and deploying subgraphs to The Graph Network. + +## Architecture + +Built on [oclif](https://oclif.io/) command framework. Entry point: `bin/run.js` -> `dist/commands/`. + +## Key Directories + +``` +src/ +├── commands/ # 13 CLI commands (init, build, codegen, deploy, test, etc.) +├── protocols/ # Multi-chain support (ethereum, near, cosmos, arweave, substreams) +├── scaffold/ # Code generation for new subgraphs +├── codegen/ # Type generation from ABIs and GraphQL schemas +├── validation/ # Manifest and schema validation +├── command-helpers/ # Shared utilities across commands +├── compiler/ # WASM compilation orchestration +└── migrations/ # Manifest version migrations +``` + +## Commands + +| Command | Description | +|---------|-------------| +| `init` | Scaffold a new subgraph | +| `codegen` | Generate AssemblyScript types from schema/ABIs | +| `build` | Compile subgraph to WASM | +| `deploy` | Deploy to hosted service or decentralized network | +| `test` | Run matchstick tests | +| `create` | Create subgraph name on node | +| `publish` | Publish to The Graph Network | +| `add` | Add data source to manifest | +| `remove` | Remove data source from manifest | +| `auth` | Set deploy key | +| `local` | Manage local Graph Node | +| `node` | Node operations | +| `clean` | Remove build artifacts | + +## Protocol System + +Factory pattern for multi-chain support (`src/protocols/index.ts`): + +```typescript +import Protocol from './protocols/index.js'; + +const protocol = Protocol.fromDataSources(dataSources); +const manifest = protocol.getManifest(); +``` + +Each protocol provides: +- ABI handling and type generation +- Manifest schema and validation +- Scaffolding templates +- Chain-specific codegen + +## Scaffolding + +Templates in `src/scaffold/` generate: +- `subgraph.yaml` manifest +- `schema.graphql` entity definitions +- `src/mapping.ts` event handlers +- Test files + +```typescript +import Scaffold from './scaffold/index.js'; + +const scaffold = new Scaffold({ + protocol, + network, + contractName, + // ... +}); +await scaffold.generate(); +``` + +## Type Generation + +`src/type-generator.ts` creates AssemblyScript classes from: +- GraphQL schema -> Entity classes +- Contract ABIs -> Event/Call types + +## Development + +```bash +pnpm build # Compile TypeScript + generate oclif manifest +pnpm test # Run vitest tests +pnpm type-check # TypeScript type checking +``` + +### Testing + +Uses Vitest with snapshot tests in `tests/`. Key test files: +- `tests/cli/init.test.ts` - Scaffolding tests +- `tests/cli/validation.test.ts` - Manifest validation +- `tests/cli/add.test.ts` - Data source addition + +Run specific tests: +```bash +pnpm test:init +pnpm test:validation +``` + +## Key Patterns + +### Command Structure + +```typescript +import { Command, Flags } from '@oclif/core'; + +export default class MyCommand extends Command { + static flags = { + network: Flags.string({ description: 'Network name' }), + }; + + async run() { + const { flags } = await this.parse(MyCommand); + // ... + } +} +``` + +### Subgraph Manifest Loading + +```typescript +import Subgraph from './subgraph.js'; + +const subgraph = await Subgraph.load('subgraph.yaml'); +const dataSources = subgraph.get('dataSources'); +``` + +## Related + +- [packages/ts/CLAUDE.md](../ts/CLAUDE.md) - AssemblyScript library for mappings diff --git a/packages/ts/CLAUDE.md b/packages/ts/CLAUDE.md new file mode 100644 index 000000000..47133ca50 --- /dev/null +++ b/packages/ts/CLAUDE.md @@ -0,0 +1,150 @@ +# @graphprotocol/graph-ts + +AssemblyScript library for writing subgraph mappings. Imported by generated mapping code. + +## Architecture + +This library provides types and host interfaces that compile to WASM and run in graph-node. Uses AssemblyScript (TypeScript-like syntax targeting WebAssembly). + +## Key Directories + +``` +├── chain/ # Blockchain-specific types +│ ├── ethereum.ts # Ethereum blocks, transactions, events, calls +│ ├── near.ts # NEAR receipts, actions +│ ├── cosmos.ts # Cosmos events, transactions +│ ├── arweave.ts # Arweave blocks, transactions +│ └── starknet.ts # Starknet events, transactions +├── common/ # Core types +│ ├── numbers.ts # BigInt, BigDecimal, Address +│ ├── collections.ts # ByteArray, Bytes, Entity, TypedMap +│ ├── value.ts # Value union type for store operations +│ ├── json.ts # JSON parsing +│ └── datasource.ts # Dynamic data source creation +├── global/ # TypeId enum for WASM runtime +└── index.ts # Re-exports + host namespace declarations +``` + +## Core Types + +```typescript +import { BigInt, BigDecimal, Address, Bytes, Entity } from '@graphprotocol/graph-ts'; + +// Number types +let amount = BigInt.fromI32(100); +let price = BigDecimal.fromString("1.5"); + +// Address (20 bytes) +let addr = Address.fromString("0x..."); + +// Binary data +let data = Bytes.fromHexString("0xabcd"); +``` + +## Host Interfaces + +Declared as namespaces that map to graph-node host functions: + +```typescript +// Entity storage +store.get(entity, id) +store.set(entity, id, data) +store.remove(entity, id) + +// Logging +log.info("Value: {}", [value.toString()]) +log.warning("Issue: {}", [msg]) +log.error("Failed: {}", [err]) + +// IPFS access +ipfs.cat(hash) + +// Cryptography +crypto.keccak256(input) + +// ENS lookups +ens.nameByHash(hash) +``` + +## Entity Pattern + +Entities implement the `Entity` interface for store operations: + +```typescript +class Transfer extends Entity { + constructor(id: string) { + super(); + this.set("id", Value.fromString(id)); + } + + save(): void { + store.set("Transfer", this.get("id")!.toString(), this); + } + + static load(id: string): Transfer | null { + return changetype(store.get("Transfer", id)); + } +} +``` + +## Ethereum Types + +```typescript +import { ethereum } from '@graphprotocol/graph-ts'; + +// In event handler +export function handleTransfer(event: ethereum.Event): void { + let block = event.block; // ethereum.Block + let tx = event.transaction; // ethereum.Transaction + let receipt = event.receipt; // ethereum.TransactionReceipt | null + let logIndex = event.logIndex; // BigInt +} + +// Contract calls +let result = contract.try_balanceOf(address); +if (!result.reverted) { + let balance = result.value; +} +``` + +## Build + +Compiles to WASM via AssemblyScript: + +```bash +pnpm build # Outputs index.wasm +pnpm test # Run tests +``` + +## Relationship to CLI + +The `@graphprotocol/graph-cli` package generates code that imports from this library: +- `graph codegen` generates entity classes extending `Entity` +- `graph build` compiles mappings + this library to WASM + +## Key Patterns + +### Result Type for Contract Calls + +```typescript +// Generated code uses ethereum.CallResult +let result = contract.try_someFunction(); +if (result.reverted) { + log.warning("Call reverted", []); +} else { + let value = result.value; +} +``` + +### Dynamic Data Sources + +```typescript +import { DataSourceTemplate } from '@graphprotocol/graph-ts'; + +// Create new data source at runtime +DataSourceTemplate.create("TokenTemplate", [tokenAddress.toHexString()]); +``` + +## Related + +- [packages/cli/CLAUDE.md](../cli/CLAUDE.md) - CLI for building and deploying subgraphs From 504fa132cefcf32f634b109ded87f39875587147 Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Wed, 13 May 2026 16:58:10 -0700 Subject: [PATCH 3/6] feat(cli): use unified @graphprotocol/gnd package Replace the `graph node install` GitHub-release downloader with a direct dependency on `@graphprotocol/gnd`, the unified npm wrapper now published from the graph-node repo. The wrapper declares the five platform-specific binary packages as its own optional dependencies, so `pnpm install` of graph-cli automatically resolves the correct binary for the host and exposes a `gnd` launcher on `node_modules/.bin`. The `graph node install` command, its `local-node.ts` GitHub downloader, and the `commands/node.ts` oclif command all become dead code and are removed. --- packages/cli/CLAUDE.md | 1 - packages/cli/package.json | 5 +- .../cli/src/command-helpers/local-node.ts | 163 ---------- packages/cli/src/commands/node.ts | 113 ------- pnpm-lock.yaml | 282 +++++------------- 5 files changed, 73 insertions(+), 491 deletions(-) delete mode 100644 packages/cli/src/command-helpers/local-node.ts delete mode 100644 packages/cli/src/commands/node.ts diff --git a/packages/cli/CLAUDE.md b/packages/cli/CLAUDE.md index 68cf9c2c1..378e20342 100644 --- a/packages/cli/CLAUDE.md +++ b/packages/cli/CLAUDE.md @@ -35,7 +35,6 @@ src/ | `remove` | Remove data source from manifest | | `auth` | Set deploy key | | `local` | Manage local Graph Node | -| `node` | Node operations | | `clean` | Remove build artifacts | ## Protocol System diff --git a/packages/cli/package.json b/packages/cli/package.json index c8bd2531d..451a2ef74 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -37,6 +37,7 @@ }, "dependencies": { "@float-capital/float-subgraph-uncrashable": "0.0.0-internal-testing.5", + "@graphprotocol/gnd": "^0.43.0", "@oclif/core": "4.5.5", "@oclif/plugin-autocomplete": "^3.2.11", "@oclif/plugin-not-found": "^3.2.29", @@ -46,7 +47,6 @@ "assemblyscript": "0.19.23", "chokidar": "4.0.3", "debug": "4.4.3", - "decompress": "^4.2.1", "docker-compose": "1.3.0", "fs-extra": "11.3.2", "glob": "11.0.3", @@ -58,7 +58,6 @@ "kubo-rpc-client": "^6.0.0", "open": "10.2.0", "prettier": "3.6.2", - "progress": "^2.0.3", "semver": "7.7.3", "tmp-promise": "3.0.3", "undici": "7.16.0", @@ -67,10 +66,8 @@ }, "devDependencies": { "@types/debug": "^4.1.12", - "@types/decompress": "^4.2.7", "@types/fs-extra": "^11.0.4", "@types/js-yaml": "^4.0.9", - "@types/progress": "^2.0.7", "@types/semver": "^7.5.8", "@types/which": "^3.0.4", "copyfiles": "^2.4.1", diff --git a/packages/cli/src/command-helpers/local-node.ts b/packages/cli/src/command-helpers/local-node.ts deleted file mode 100644 index 49970b77b..000000000 --- a/packages/cli/src/command-helpers/local-node.ts +++ /dev/null @@ -1,163 +0,0 @@ -import * as fs from 'node:fs'; -import { createReadStream, createWriteStream } from 'node:fs'; -import * as os from 'node:os'; -import * as path from 'node:path'; -import { Readable } from 'node:stream'; -import { pipeline } from 'node:stream/promises'; -import { createGunzip } from 'node:zlib'; -import decompress from 'decompress'; -import fetch from '../fetch.js'; - -// Add GitHub repository configuration via environment variables with defaults -const GRAPH_NODE_GITHUB_OWNER = process.env.GRAPH_NODE_GITHUB_OWNER || 'graphprotocol'; -const GRAPH_NODE_GITHUB_REPO = process.env.GRAPH_NODE_GITHUB_REPO || 'graph-node'; - -function getPlatformBinaryName(): string { - const platform = os.platform(); - const arch = os.arch(); - - if (platform === 'linux' && arch === 'x64') return 'gnd-linux-x86_64.gz'; - if (platform === 'linux' && arch === 'arm64') return 'gnd-linux-aarch64.gz'; - if (platform === 'darwin' && arch === 'x64') return 'gnd-macos-x86_64.gz'; - if (platform === 'darwin' && arch === 'arm64') return 'gnd-macos-aarch64.gz'; - if (platform === 'win32' && arch === 'x64') return 'gnd-windows-x86_64.exe.zip'; - - throw new Error(`Unsupported platform: ${platform} ${arch}`); -} - -export async function getGlobalBinDir(): Promise { - const platform = os.platform(); - let binDir: string; - - if (platform === 'win32') { - // Prefer %USERPROFILE%\gnd\bin - binDir = path.join(process.env.USERPROFILE || os.homedir(), 'gnd', 'bin'); - } else { - binDir = path.join(os.homedir(), '.local', 'bin'); - } - - await fs.promises.mkdir(binDir, { recursive: true }); - return binDir; -} - -async function getLatestGithubRelease(owner: string, repo: string) { - const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/releases/latest`); - const data = await res.json(); - return data.tag_name; -} - -export async function getLatestGraphNodeRelease(): Promise { - return getLatestGithubRelease(GRAPH_NODE_GITHUB_OWNER, GRAPH_NODE_GITHUB_REPO); -} - -export async function downloadGraphNodeRelease( - release: string, - outputDir: string, - onProgress?: (downloaded: number, total: number | null) => void, -): Promise { - const fileName = getPlatformBinaryName(); - - try { - return await downloadGithubRelease( - GRAPH_NODE_GITHUB_OWNER, - GRAPH_NODE_GITHUB_REPO, - release, - outputDir, - fileName, - onProgress, - ); - } catch (e) { - if (e === 404) { - throw new Error( - `Graph Node release ${release} does not exist, please check the release page for the correct release tag`, - ); - } - - throw new Error(`Failed to download: ${release}`); - } -} - -async function downloadGithubRelease( - owner: string, - repo: string, - release: string, - outputDir: string, - fileName: string, - onProgress?: (downloaded: number, total: number | null) => void, -): Promise { - const url = `https://github.com/${owner}/${repo}/releases/download/${release}/${fileName}`; - return downloadFile(url, path.join(outputDir, fileName), onProgress); -} - -export async function downloadFile( - url: string, - outputPath: string, - onProgress?: (downloaded: number, total: number | null) => void, -): Promise { - return download(url, outputPath, onProgress); -} - -export async function download( - url: string, - outputPath: string, - onProgress?: (downloaded: number, total: number | null) => void, -): Promise { - const res = await fetch(url); - if (!res.ok || !res.body) { - throw res.status; - } - - const totalLength = Number(res.headers.get('content-length')) || null; - let downloaded = 0; - - const fileStream = fs.createWriteStream(outputPath); - const nodeStream = Readable.from(res.body); - - nodeStream.on('data', chunk => { - downloaded += chunk.length; - onProgress?.(downloaded, totalLength); - }); - - nodeStream.pipe(fileStream); - - await new Promise((resolve, reject) => { - nodeStream.on('error', reject); - fileStream.on('finish', resolve); - fileStream.on('error', reject); - }); - - return outputPath; -} - -export async function extractGz(gzPath: string, outputPath?: string): Promise { - const outPath = outputPath || path.join(path.dirname(gzPath), path.basename(gzPath, '.gz')); - - await pipeline(createReadStream(gzPath), createGunzip(), createWriteStream(outPath)); - - return outPath; -} - -export async function extractZipAndGetExe(zipPath: string, outputDir: string): Promise { - const files = await decompress(zipPath, outputDir); - const exe = files.filter(file => file.path.endsWith('.exe')); - - if (exe.length !== 1) { - throw new Error(`Expected 1 executable file in zip, got ${exe.length}`); - } - - return path.join(outputDir, exe[0].path); -} - -export async function moveFileToBinDir(srcPath: string, binDir?: string): Promise { - const targetDir = binDir || (await getGlobalBinDir()); - const platform = os.platform(); - const binaryName = platform === 'win32' ? 'gnd.exe' : 'gnd'; - const destPath = path.join(targetDir, binaryName); - await fs.promises.rename(srcPath, destPath); - return destPath; -} - -export async function moveFile(srcPath: string, destPath: string): Promise { - await fs.promises.rename(srcPath, destPath); - return destPath; -} diff --git a/packages/cli/src/commands/node.ts b/packages/cli/src/commands/node.ts deleted file mode 100644 index abaab255c..000000000 --- a/packages/cli/src/commands/node.ts +++ /dev/null @@ -1,113 +0,0 @@ -import * as fs from 'node:fs'; -import { chmod } from 'node:fs/promises'; -import * as os from 'node:os'; -import * as path from 'node:path'; -import { print } from 'gluegun'; -import ProgressBar from 'progress'; -import { Args, Command, Flags } from '@oclif/core'; -import { - downloadGraphNodeRelease, - extractGz, - extractZipAndGetExe, - getLatestGraphNodeRelease, - moveFileToBinDir, -} from '../command-helpers/local-node.js'; - -export default class NodeCommand extends Command { - static description = 'Manage Graph node related operations'; - - static override flags = { - help: Flags.help({ - char: 'h', - }), - tag: Flags.string({ - summary: 'Tag of the Graph Node release to install.', - }), - 'bin-dir': Flags.string({ - summary: 'Directory to install the Graph Node binary to.', - }), - }; - - static override args = { - install: Args.boolean({ - description: 'Install the Graph Node', - }), - }; - - static examples = [ - '$ graph node install', - '$ graph node install --tag v1.0.0', - '$ graph node install --bin-dir /usr/local/bin', - ]; - - static strict = false; - - async run() { - const { flags, args } = await this.parse(NodeCommand); - - if (args.install) { - try { - await installGraphNode(flags.tag, flags['bin-dir']); - } catch (e) { - this.error(`Failed to install: ${e.message}`, { exit: 1 }); - } - return; - } - - // If no valid subcommand is provided, show help - await this.config.runCommand('help', ['node']); - } -} - -async function installGraphNode(tag?: string, binDir?: string) { - const latestRelease = tag || (await getLatestGraphNodeRelease()); - const tmpBase = os.tmpdir(); - const tmpDir = await fs.promises.mkdtemp(path.join(tmpBase, 'graph-node-')); - let progressBar: ProgressBar | undefined; - - const downloadPath = await downloadGraphNodeRelease( - latestRelease, - tmpDir, - (downloaded, total) => { - if (!total) return; - - progressBar ||= new ProgressBar(`Downloading ${latestRelease} [:bar] :percent`, { - width: 30, - total, - complete: '=', - incomplete: ' ', - }); - - progressBar.tick(downloaded - (progressBar.curr || 0)); - }, - ); - - let extractedPath: string; - - print.info(`\nExtracting binary...`); - if (downloadPath.endsWith('.gz')) { - extractedPath = await extractGz(downloadPath); - } else if (downloadPath.endsWith('.zip')) { - extractedPath = await extractZipAndGetExe(downloadPath, tmpDir); - } else { - print.error(`Unsupported file type: ${downloadPath}`); - throw new Error(`Unsupported file type: ${downloadPath}`); - } - - const movedPath = await moveFileToBinDir(extractedPath, binDir); - print.info(`✅ Graph Node ${latestRelease} installed successfully`); - print.info(`Binary location: ${movedPath}`); - - if (os.platform() !== 'win32') { - await chmod(movedPath, 0o755); - } - - print.info(''); - print.info(`📋 Next steps:`); - print.info(` Add ${path.dirname(movedPath)} to your PATH (if not already)`); - print.info(` Run 'gnd' to start your local Graph Node development environment`); - print.info(''); - - // Delete the temporary directory - await fs.promises.rm(tmpDir, { recursive: true, force: true }); -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aff0e349c..87ef4e68b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,7 +6,7 @@ settings: patchedDependencies: oclif@4.16.0: - hash: ofxhflhoc4vkbbfnh6gtk4pfua + hash: cf4f9ea2740997b73ebc5e1084352b6adf75960c91a5f924db548e17ce10c6da path: patches/oclif@4.16.0.patch importers: @@ -168,7 +168,7 @@ importers: version: 0.35.1 '@nomicfoundation/hardhat-toolbox': specifier: ^5.0.0 - version: 5.0.0(a47bc6n53ztcryifqiwdx7452m) + version: 5.0.0(9ece31874dfa6c570acf7259c19ebde2) apollo-fetch: specifier: ^0.7.0 version: 0.7.0 @@ -186,7 +186,7 @@ importers: version: 0.35.1 '@nomicfoundation/hardhat-toolbox': specifier: ^5.0.0 - version: 5.0.0(xbt4iz7jxygyqumkflknusgqv4) + version: 5.0.0(b8ab6a67c00eb2d486ed44ed0aeb23f9) hardhat: specifier: ^2.22.17 version: 2.26.3(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.18.11)(typescript@5.7.3))(typescript@5.7.3)(utf-8-validate@5.0.10) @@ -239,6 +239,9 @@ importers: '@float-capital/float-subgraph-uncrashable': specifier: 0.0.0-internal-testing.5 version: 0.0.0-internal-testing.5 + '@graphprotocol/gnd': + specifier: ^0.43.0 + version: 0.43.0 '@oclif/core': specifier: 4.5.5 version: 4.5.5 @@ -266,9 +269,6 @@ importers: debug: specifier: 4.4.3 version: 4.4.3(supports-color@5.5.0) - decompress: - specifier: ^4.2.1 - version: 4.2.1 docker-compose: specifier: 1.3.0 version: 1.3.0 @@ -302,9 +302,6 @@ importers: prettier: specifier: 3.6.2 version: 3.6.2 - progress: - specifier: ^2.0.3 - version: 2.0.3 semver: specifier: 7.7.3 version: 7.7.3 @@ -324,18 +321,12 @@ importers: '@types/debug': specifier: ^4.1.12 version: 4.1.12 - '@types/decompress': - specifier: ^4.2.7 - version: 4.2.7 '@types/fs-extra': specifier: ^11.0.4 version: 11.0.4 '@types/js-yaml': specifier: ^4.0.9 version: 4.0.9 - '@types/progress': - specifier: ^2.0.7 - version: 2.0.7 '@types/semver': specifier: ^7.5.8 version: 7.7.1 @@ -347,7 +338,7 @@ importers: version: 2.4.1 oclif: specifier: 4.16.0 - version: 4.16.0(patch_hash=ofxhflhoc4vkbbfnh6gtk4pfua)(@types/node@22.18.11) + version: 4.16.0(patch_hash=cf4f9ea2740997b73ebc5e1084352b6adf75960c91a5f924db548e17ce10c6da)(@types/node@22.18.11) spawn-command: specifier: 1.0.0 version: 1.0.0 @@ -1759,6 +1750,40 @@ packages: graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 typescript: ^5.0.0 + '@graphprotocol/gnd-darwin-arm64@0.43.0': + resolution: {integrity: sha512-sJyTDXppql71D4a02iZBACyR33H/T4QkfqUOTjWX8OkZBJutEUyYWqkqFBsJ8+nAACx0QJieKj1LpcQFLJFLQA==} + cpu: [arm64] + os: [darwin] + hasBin: true + + '@graphprotocol/gnd-darwin-x64@0.43.0': + resolution: {integrity: sha512-q8LPyoTVNSa3TrYXXbVOl6LVrLuOOe4CFkVEU9mWkQ1b1TunO5zjdmMAi1evFU07+VtOUR3dmzd40Tml9cho4A==} + cpu: [x64] + os: [darwin] + hasBin: true + + '@graphprotocol/gnd-linux-arm64@0.43.0': + resolution: {integrity: sha512-L/YljzSomydIGe82seWn7VTP+jNc+bDxBreH7E6rAeNxWXP5NLFQd7tSaqOtiL/28xwoy0FQ2JTGQHNuSyMy9w==} + cpu: [arm64] + os: [linux] + hasBin: true + + '@graphprotocol/gnd-linux-x64@0.43.0': + resolution: {integrity: sha512-N/QxT93ZvF+vOYCrrUOu0/mPR81VEEtFKUNyx9W/hfCt96mEh6R7KO08VCWwGB3VdS623atxBWaO08ILqSps4w==} + cpu: [x64] + os: [linux] + hasBin: true + + '@graphprotocol/gnd-win32-x64@0.43.0': + resolution: {integrity: sha512-o3GqOnDaRy7yQKtWJxjkKG6GebAjNgOWFAPjtlqcTkYGhTetjK2+Bbs1zLDyr6gk5UiLrkdQIRljAOWkJJjLSg==} + cpu: [x64] + os: [win32] + hasBin: true + + '@graphprotocol/gnd@0.43.0': + resolution: {integrity: sha512-VdOR32HiY1SfG6w/Kasc1+GZm58xvLNWo0MfGeIxMtc/yuyNgDUuN2SMMbgP5lSDsIFY6DgxuKb2INphF4PLOA==} + hasBin: true + '@graphprotocol/graph-cli@0.90.1': resolution: {integrity: sha512-BELpFrJ/+bjYj/p2qTEQdCgmmbbkGKE4Q2tJeGoTJ5ZJGPvwASDXvZlb1OwktCTkM5mJ5PLgJY+GB6rkSh2JSg==} engines: {node: '>=18'} @@ -3530,9 +3555,6 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - '@types/decompress@4.2.7': - resolution: {integrity: sha512-9z+8yjKr5Wn73Pt17/ldnmQToaFHZxK0N1GHysuk/JIPT8RIdQeoInM01wWPgypRcvb6VH1drjuFpQ4zmY437g==} - '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -3627,9 +3649,6 @@ packages: '@types/prettier@2.7.3': resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} - '@types/progress@2.0.7': - resolution: {integrity: sha512-iadjw02vte8qWx7U0YM++EybBha2CQLPGu9iJ97whVgJUT5Zq9MjAPYUnbfRI2Kpehimf1QjFJYxD0t8nqzu5w==} - '@types/qs@6.14.0': resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} @@ -4450,9 +4469,6 @@ packages: buffer-alloc@1.2.0: resolution: {integrity: sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==} - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - buffer-fill@1.0.0: resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==} @@ -4982,26 +4998,6 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} - decompress-tar@4.1.1: - resolution: {integrity: sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==} - engines: {node: '>=4'} - - decompress-tarbz2@4.1.1: - resolution: {integrity: sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==} - engines: {node: '>=4'} - - decompress-targz@4.1.1: - resolution: {integrity: sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==} - engines: {node: '>=4'} - - decompress-unzip@4.0.1: - resolution: {integrity: sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==} - engines: {node: '>=4'} - - decompress@4.2.1: - resolution: {integrity: sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==} - engines: {node: '>=4'} - deep-eql@4.1.4: resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} engines: {node: '>=6'} @@ -5719,9 +5715,6 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -5746,18 +5739,6 @@ packages: resolution: {integrity: sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg==} engines: {node: '>=18'} - file-type@3.9.0: - resolution: {integrity: sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==} - engines: {node: '>=0.10.0'} - - file-type@5.2.0: - resolution: {integrity: sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==} - engines: {node: '>=4'} - - file-type@6.2.0: - resolution: {integrity: sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==} - engines: {node: '>=4'} - filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} @@ -5932,10 +5913,6 @@ packages: resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} engines: {node: '>=12'} - get-stream@2.3.1: - resolution: {integrity: sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==} - engines: {node: '>=0.10.0'} - get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -5976,11 +5953,11 @@ packages: glob@5.0.15: resolution: {integrity: sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} @@ -6494,9 +6471,6 @@ packages: resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} engines: {node: '>= 0.4'} - is-natural-number@4.0.1: - resolution: {integrity: sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==} - is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} @@ -7059,10 +7033,6 @@ packages: main-event@1.0.1: resolution: {integrity: sha512-NWtdGrAca/69fm6DIVd8T9rtfDII4Q8NQbIbsKQq2VzS9eqOGYs8uaNQjcuaCq/d9H/o625aOTJX2Qoxzqw0Pw==} - make-dir@1.3.0: - resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} - engines: {node: '>=4'} - make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} @@ -7811,9 +7781,6 @@ packages: resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} engines: {node: '>= 0.10'} - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -7825,10 +7792,6 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} @@ -7841,14 +7804,6 @@ packages: resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} engines: {node: '>=10'} - pinkie-promise@2.0.1: - resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} - engines: {node: '>=0.10.0'} - - pinkie@2.0.4: - resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} - engines: {node: '>=0.10.0'} - pino-abstract-transport@0.5.0: resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} @@ -7971,10 +7926,6 @@ packages: progress-events@1.0.1: resolution: {integrity: sha512-MOzLIwhpt64KIVN64h1MwdKWiyKFNc/S6BoYKPIVUHFg0/eIEyBulhWCgn678v/4c0ri3FdGuzXymNCv02MUIw==} - progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - promise-inflight@1.0.1: resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} peerDependencies: @@ -8445,10 +8396,6 @@ packages: resolution: {integrity: sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==} engines: {node: '>=18.0.0'} - seek-bzip@1.0.6: - resolution: {integrity: sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==} - hasBin: true - semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -8807,9 +8754,6 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} - strip-dirs@2.1.0: - resolution: {integrity: sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==} - strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -9199,9 +9143,6 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} - unbzip2-stream@1.4.3: - resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} - uncrypto@0.1.3: resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} @@ -9838,9 +9779,6 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} @@ -12009,6 +11947,29 @@ snapshots: graphql: 16.11.0 typescript: 5.7.3 + '@graphprotocol/gnd-darwin-arm64@0.43.0': + optional: true + + '@graphprotocol/gnd-darwin-x64@0.43.0': + optional: true + + '@graphprotocol/gnd-linux-arm64@0.43.0': + optional: true + + '@graphprotocol/gnd-linux-x64@0.43.0': + optional: true + + '@graphprotocol/gnd-win32-x64@0.43.0': + optional: true + + '@graphprotocol/gnd@0.43.0': + optionalDependencies: + '@graphprotocol/gnd-darwin-arm64': 0.43.0 + '@graphprotocol/gnd-darwin-x64': 0.43.0 + '@graphprotocol/gnd-linux-arm64': 0.43.0 + '@graphprotocol/gnd-linux-x64': 0.43.0 + '@graphprotocol/gnd-win32-x64': 0.43.0 + '@graphprotocol/graph-cli@0.90.1(@types/node@22.18.11)(bufferutil@4.0.9)(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.7.3)(utf-8-validate@5.0.10)': dependencies: '@float-capital/float-subgraph-uncrashable': 0.0.0-internal-testing.5 @@ -12787,7 +12748,7 @@ snapshots: ethereumjs-util: 7.1.5 hardhat: 2.26.3(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.18.11)(typescript@5.7.3))(typescript@5.7.3)(utf-8-validate@5.0.10) - '@nomicfoundation/hardhat-toolbox@5.0.0(a47bc6n53ztcryifqiwdx7452m)': + '@nomicfoundation/hardhat-toolbox@5.0.0(9ece31874dfa6c570acf7259c19ebde2)': dependencies: '@nomicfoundation/hardhat-chai-matchers': 2.1.0(@nomicfoundation/hardhat-ethers@3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.3(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.18.11)(typescript@5.7.3))(typescript@5.7.3)(utf-8-validate@5.0.10)))(chai@4.5.0)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.3(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.18.11)(typescript@5.7.3))(typescript@5.7.3)(utf-8-validate@5.0.10)) '@nomicfoundation/hardhat-ethers': 3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.3(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.18.11)(typescript@5.7.3))(typescript@5.7.3)(utf-8-validate@5.0.10)) @@ -12808,7 +12769,7 @@ snapshots: typechain: 8.3.2(typescript@5.7.3) typescript: 5.7.3 - '@nomicfoundation/hardhat-toolbox@5.0.0(xbt4iz7jxygyqumkflknusgqv4)': + '@nomicfoundation/hardhat-toolbox@5.0.0(b8ab6a67c00eb2d486ed44ed0aeb23f9)': dependencies: '@nomicfoundation/hardhat-chai-matchers': 2.1.0(@nomicfoundation/hardhat-ethers@3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.3(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.18.11)(typescript@5.7.3))(typescript@5.7.3)(utf-8-validate@5.0.10)))(chai@5.3.3)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.3(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.18.11)(typescript@5.7.3))(typescript@5.7.3)(utf-8-validate@5.0.10)) '@nomicfoundation/hardhat-ethers': 3.1.0(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(hardhat@2.26.3(bufferutil@4.0.9)(ts-node@10.9.2(@types/node@22.18.11)(typescript@5.7.3))(typescript@5.7.3)(utf-8-validate@5.0.10)) @@ -13810,7 +13771,7 @@ snapshots: '@scure/bip32@1.6.2': dependencies: '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 + '@noble/hashes': 1.7.2 '@scure/base': 1.2.6 '@scure/bip32@1.7.0': @@ -13831,7 +13792,7 @@ snapshots: '@scure/bip39@1.5.4': dependencies: - '@noble/hashes': 1.7.1 + '@noble/hashes': 1.7.2 '@scure/base': 1.2.6 '@scure/bip39@1.6.0': @@ -14558,10 +14519,6 @@ snapshots: dependencies: '@types/ms': 2.1.0 - '@types/decompress@4.2.7': - dependencies: - '@types/node': 22.18.11 - '@types/deep-eql@4.0.2': {} '@types/estree-jsx@1.0.5': @@ -14652,10 +14609,6 @@ snapshots: '@types/prettier@2.7.3': {} - '@types/progress@2.0.7': - dependencies: - '@types/node': 22.18.11 - '@types/qs@6.14.0': {} '@types/react-dom@19.2.2(@types/react@19.2.2)': @@ -16136,8 +16089,6 @@ snapshots: buffer-alloc-unsafe: 1.1.0 buffer-fill: 1.0.0 - buffer-crc32@0.2.13: {} - buffer-fill@1.0.0: {} buffer-from@1.1.2: {} @@ -16734,44 +16685,6 @@ snapshots: dependencies: mimic-response: 3.1.0 - decompress-tar@4.1.1: - dependencies: - file-type: 5.2.0 - is-stream: 1.1.0 - tar-stream: 1.6.2 - - decompress-tarbz2@4.1.1: - dependencies: - decompress-tar: 4.1.1 - file-type: 6.2.0 - is-stream: 1.1.0 - seek-bzip: 1.0.6 - unbzip2-stream: 1.4.3 - - decompress-targz@4.1.1: - dependencies: - decompress-tar: 4.1.1 - file-type: 5.2.0 - is-stream: 1.1.0 - - decompress-unzip@4.0.1: - dependencies: - file-type: 3.9.0 - get-stream: 2.3.1 - pify: 2.3.0 - yauzl: 2.10.0 - - decompress@4.2.1: - dependencies: - decompress-tar: 4.1.1 - decompress-tarbz2: 4.1.1 - decompress-targz: 4.1.1 - decompress-unzip: 4.0.1 - graceful-fs: 4.2.11 - make-dir: 1.3.0 - pify: 2.3.0 - strip-dirs: 2.1.0 - deep-eql@4.1.4: dependencies: type-detect: 4.1.0 @@ -17783,10 +17696,6 @@ snapshots: dependencies: reusify: 1.1.0 - fd-slicer@1.1.0: - dependencies: - pend: 1.2.0 - fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -17810,12 +17719,6 @@ snapshots: transitivePeerDependencies: - supports-color - file-type@3.9.0: {} - - file-type@5.2.0: {} - - file-type@6.2.0: {} - filelist@1.0.4: dependencies: minimatch: 5.1.6 @@ -18008,11 +17911,6 @@ snapshots: get-stdin@9.0.0: {} - get-stream@2.3.1: - dependencies: - object-assign: 4.1.1 - pinkie-promise: 2.0.1 - get-stream@6.0.1: {} get-symbol-description@1.1.0: @@ -18783,8 +18681,6 @@ snapshots: call-bind: 1.0.8 define-properties: 1.2.1 - is-natural-number@4.0.1: {} - is-negative-zero@2.0.3: {} is-number-object@1.1.1: @@ -19319,10 +19215,6 @@ snapshots: main-event@1.0.1: {} - make-dir@1.3.0: - dependencies: - pify: 3.0.0 - make-error@1.3.6: {} markdown-table@1.1.3: {} @@ -20035,7 +19927,7 @@ snapshots: obliterator@2.0.5: {} - oclif@4.16.0(patch_hash=ofxhflhoc4vkbbfnh6gtk4pfua)(@types/node@22.18.11): + oclif@4.16.0(patch_hash=cf4f9ea2740997b73ebc5e1084352b6adf75960c91a5f924db548e17ce10c6da)(@types/node@22.18.11): dependencies: '@aws-sdk/client-cloudfront': 3.913.0 '@aws-sdk/client-s3': 3.913.0 @@ -20149,7 +20041,7 @@ snapshots: dependencies: '@adraffy/ens-normalize': 1.11.1 '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 + '@noble/hashes': 1.8.0 '@scure/bip32': 1.6.2 '@scure/bip39': 1.5.4 abitype: 1.0.8(typescript@5.7.3)(zod@4.1.12) @@ -20384,28 +20276,18 @@ snapshots: sha.js: 2.4.12 to-buffer: 1.2.2 - pend@1.2.0: {} - picocolors@1.1.1: {} picomatch@2.3.1: {} picomatch@4.0.3: {} - pify@2.3.0: {} - pify@3.0.0: {} pify@4.0.1: {} pify@5.0.0: {} - pinkie-promise@2.0.1: - dependencies: - pinkie: 2.0.4 - - pinkie@2.0.4: {} - pino-abstract-transport@0.5.0: dependencies: duplexify: 4.1.3 @@ -20510,8 +20392,6 @@ snapshots: progress-events@1.0.1: {} - progress@2.0.3: {} - promise-inflight@1.0.1: {} promise-retry@2.0.1: @@ -21060,10 +20940,6 @@ snapshots: node-addon-api: 5.1.0 node-gyp-build: 4.8.4 - seek-bzip@1.0.6: - dependencies: - commander: 2.20.3 - semver@5.7.2: {} semver@6.3.1: {} @@ -21492,10 +21368,6 @@ snapshots: strip-bom@3.0.0: {} - strip-dirs@2.1.0: - dependencies: - is-natural-number: 4.0.1 - strip-final-newline@2.0.0: {} strip-hex-prefix@1.0.0: @@ -21922,11 +21794,6 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 - unbzip2-stream@1.4.3: - dependencies: - buffer: 5.7.1 - through: 2.3.8 - uncrypto@0.1.3: {} undici-types@6.19.8: {} @@ -22648,11 +22515,6 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yauzl@2.10.0: - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - yn@3.1.1: {} yocto-queue@0.1.0: {} From c8864f3b76c68596f7317c78461eb7164360ddf2 Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Wed, 13 May 2026 17:33:18 -0700 Subject: [PATCH 4/6] feat(cli): delegate commands to gnd by default `graph ` now execs the matching `gnd ` (the Rust `@graphprotocol/gnd` binary). Two exceptions stay on the oclif/TS path: `local`, which has no gnd equivalent, and `dev`, which is a thin oclif shim that spawns `gnd dev` so the command is discoverable from `graph --help`. Set `GRAPH_CLI_IGNORE_GND=1` to force the TS implementation everywhere; the test suite does this automatically. --- packages/cli/CLAUDE.md | 20 +++++++++++++++++++- packages/cli/bin/run.js | 10 +++++++++- packages/cli/src/command-helpers/gnd.ts | 18 ++++++++++++++++++ packages/cli/src/commands/dev.ts | 15 +++++++++++++++ packages/cli/tests/cli/globalSetup.ts | 1 + 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 packages/cli/src/command-helpers/gnd.ts create mode 100644 packages/cli/src/commands/dev.ts diff --git a/packages/cli/CLAUDE.md b/packages/cli/CLAUDE.md index 378e20342..59ad7ecff 100644 --- a/packages/cli/CLAUDE.md +++ b/packages/cli/CLAUDE.md @@ -6,6 +6,23 @@ CLI for building and deploying subgraphs to The Graph Network. Built on [oclif](https://oclif.io/) command framework. Entry point: `bin/run.js` -> `dist/commands/`. +## gnd dispatch + +By default, `graph ` execs `gnd ` (the Rust `@graphprotocol/gnd` +binary). Exceptions: + +- `graph local` always runs the TypeScript implementation — gnd has no + equivalent command. +- `graph dev` is an oclif shim that spawns `gnd dev`, so the command is + discoverable from `graph --help` even when running in TS mode. + +Set `GRAPH_CLI_IGNORE_GND=1` to force every command through the oclif/TS +implementation. The test suite sets this automatically via +`tests/cli/globalSetup.ts`. + +The dispatch lives in `bin/run.js` and shares the spawn helper in +`src/command-helpers/gnd.ts` with `src/commands/dev.ts`. + ## Key Directories ``` @@ -34,7 +51,8 @@ src/ | `add` | Add data source to manifest | | `remove` | Remove data source from manifest | | `auth` | Set deploy key | -| `local` | Manage local Graph Node | +| `local` | Manage local Graph Node (always TS — gnd has no equivalent) | +| `dev` | Run graph-node in dev mode (delegates to `gnd dev`) | | `clean` | Remove build artifacts | ## Protocol System diff --git a/packages/cli/bin/run.js b/packages/cli/bin/run.js index e005f942c..1573165fc 100755 --- a/packages/cli/bin/run.js +++ b/packages/cli/bin/run.js @@ -3,6 +3,7 @@ import process from 'node:process'; import semver from 'semver'; import { execute } from '@oclif/core'; import { nodeVersion } from '../dist/version.js'; +import { runGnd } from '../dist/command-helpers/gnd.js'; if (!semver.satisfies(process.version, nodeVersion)) { process.stderr.write( @@ -11,4 +12,11 @@ if (!semver.satisfies(process.version, nodeVersion)) { process.exit(1); } -await execute({ dir: import.meta.url }); +const args = process.argv.slice(2); +const useGnd = !process.env.GRAPH_CLI_IGNORE_GND && args[0] !== 'local'; + +if (useGnd) { + runGnd(args); +} else { + await execute({ dir: import.meta.url }); +} diff --git a/packages/cli/src/command-helpers/gnd.ts b/packages/cli/src/command-helpers/gnd.ts new file mode 100644 index 000000000..a1a030fe0 --- /dev/null +++ b/packages/cli/src/command-helpers/gnd.ts @@ -0,0 +1,18 @@ +import { spawnSync } from 'node:child_process'; +import { createRequire } from 'node:module'; +import process from 'node:process'; + +const require = createRequire(import.meta.url); + +export function runGnd(args: string[]): never { + const gndEntry = require.resolve('@graphprotocol/gnd/bin/gnd.js'); + const result = spawnSync(process.execPath, [gndEntry, ...args], { stdio: 'inherit' }); + if (result.error) { + process.stderr.write(`Failed to launch gnd: ${result.error.message}\n`); + process.exit(1); + } + if (result.signal) { + process.kill(process.pid, result.signal); + } + process.exit(result.status ?? 1); +} diff --git a/packages/cli/src/commands/dev.ts b/packages/cli/src/commands/dev.ts new file mode 100644 index 000000000..d020036d9 --- /dev/null +++ b/packages/cli/src/commands/dev.ts @@ -0,0 +1,15 @@ +import { Command } from '@oclif/core'; +import { runGnd } from '../command-helpers/gnd.js'; + +export default class DevCommand extends Command { + static description = + 'Run graph-node in dev mode. Delegates to `gnd dev`; run `graph dev --help` (without GRAPH_CLI_IGNORE_GND set) for the full list of supported flags.'; + + static strict = false; + + static args = {}; + + async run() { + runGnd(['dev', ...this.argv]); + } +} diff --git a/packages/cli/tests/cli/globalSetup.ts b/packages/cli/tests/cli/globalSetup.ts index a89dc5d9f..64bbcf258 100644 --- a/packages/cli/tests/cli/globalSetup.ts +++ b/packages/cli/tests/cli/globalSetup.ts @@ -4,5 +4,6 @@ import { linkCli } from './link'; export default async () => { process.env.GRAPH_CLI_TESTS = '1'; + process.env.GRAPH_CLI_IGNORE_GND = '1'; await linkCli(); }; From 5bec0913f7b0143b8d93c90b9468d6f8d0c54e2e Mon Sep 17 00:00:00 2001 From: David Lutterkort Date: Fri, 15 May 2026 11:48:33 -0700 Subject: [PATCH 5/6] docs(cli): document gnd delegation switchover Add a changeset describing the major-version bump, document the new gnd dispatch in the CLI README (including the GRAPH_CLI_IGNORE_GND escape hatch and the removal of `graph node install`), add `graph dev` to the command list, and mark `graph local` as deprecated in favor of `graph dev`. --- .changeset/delegate-to-gnd.md | 20 ++++++++++++++++++++ packages/cli/README.md | 18 +++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 .changeset/delegate-to-gnd.md diff --git a/.changeset/delegate-to-gnd.md b/.changeset/delegate-to-gnd.md new file mode 100644 index 000000000..53a81b530 --- /dev/null +++ b/.changeset/delegate-to-gnd.md @@ -0,0 +1,20 @@ +--- +'@graphprotocol/graph-cli': major +--- + +Delegate commands to `gnd` by default + +`graph ` now execs the `@graphprotocol/gnd` binary (shipped as a +dependency) instead of running the bundled TypeScript implementation. +Set `GRAPH_CLI_IGNORE_GND=1` to force every command back through the +oclif/TS code path. + +Breaking changes: + +- The `graph node install` command has been removed. Install `gnd` via + the `@graphprotocol/gnd` npm package instead — it is now a direct + dependency of `@graphprotocol/graph-cli` and no separate download + step is required. +- `graph local` is the only command that still always runs the + TypeScript implementation; gnd has no equivalent. +- `graph dev` is an oclif shim that always delegates to `gnd dev`. diff --git a/packages/cli/README.md b/packages/cli/README.md index 31ab98ca9..3c9efd13d 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -17,13 +17,29 @@ As of today, the command line interface supports the following commands: - `graph auth` — Stores a [Graph Node](https://github.com/graphprotocol/graph-node) access token in the system's keychain. - `graph local` — Runs tests against a [Graph Node](https://github.com/graphprotocol/graph-node) - test environment (using Ganache by default). + test environment (using Ganache by default) (deprecated, use `graph dev` instead). +- `graph dev` — Runs a local + [Graph Node](https://github.com/graphprotocol/graph-node) in dev mode (delegates to + [`gnd dev`](https://www.npmjs.com/package/@graphprotocol/gnd)). - `graph test` — Downloads and runs the [Matchstick](https://github.com/LimeChain/matchstick) rust binary in order to test a subgraph. - `graph add` - Adds a new datasource to the yaml file and writes the necessary changes to other files - schema.graphql, abi and mapping. - `graph publish` - Publishes the subgraph to the Graph Network. +### Command dispatch via `gnd` + +By default, `graph ` execs the +[`@graphprotocol/gnd`](https://www.npmjs.com/package/@graphprotocol/gnd) binary, which is shipped +as a dependency of the CLI. The TypeScript implementation in this package is used as a fallback for +commands that `gnd` does not provide. + +- `graph local` always runs the TypeScript implementation — `gnd` has no equivalent. +- Set `GRAPH_CLI_IGNORE_GND=1` to route every command through the TypeScript implementation. + +The previous `graph node install` command, which downloaded a `gnd` binary from GitHub releases, +has been removed. Installing `@graphprotocol/graph-cli` is now sufficient to get `gnd`. + ## How It Works The Graph CLI takes a subgraph manifest (defaults to `subgraph.yaml`) with references to: From 8dc54c49e0b7476e02e3a1ae94b6cfd96a5f32f3 Mon Sep 17 00:00:00 2001 From: pinax-bot Date: Fri, 15 May 2026 23:04:20 +0000 Subject: [PATCH 6/6] chore(dependencies): updated changesets for modified dependencies --- .changeset/@graphprotocol_graph-cli-2125-dependencies.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/@graphprotocol_graph-cli-2125-dependencies.md diff --git a/.changeset/@graphprotocol_graph-cli-2125-dependencies.md b/.changeset/@graphprotocol_graph-cli-2125-dependencies.md new file mode 100644 index 000000000..d0d39c5c3 --- /dev/null +++ b/.changeset/@graphprotocol_graph-cli-2125-dependencies.md @@ -0,0 +1,7 @@ +--- +"@graphprotocol/graph-cli": patch +--- +dependencies updates: + - Added dependency [`@graphprotocol/gnd@^0.43.0` ↗︎](https://www.npmjs.com/package/@graphprotocol/gnd/v/0.43.0) (to `dependencies`) + - Removed dependency [`decompress@^4.2.1` ↗︎](https://www.npmjs.com/package/decompress/v/4.2.1) (from `dependencies`) + - Removed dependency [`progress@^2.0.3` ↗︎](https://www.npmjs.com/package/progress/v/2.0.3) (from `dependencies`)