Skip to content

Commit aa82318

Browse files
feat: multi chain configuration using mustache templates (#228)
This pull request introduces multi-network support for the FWSS subgraph, enabling deployment to both mainnet and Calibration testnet with automated configuration and contract address management. The changes refactor the build and deployment workflow to use mustache templating for network-specific settings, add scripts for generating configuration and constants, and update documentation to guide users through the new process. Manual editing of contract addresses is replaced by automated generation from a central config file. **Copilot**
1 parent 8171da4 commit aa82318

File tree

12 files changed

+377
-86
lines changed

12 files changed

+377
-86
lines changed

subgraph/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ typechain-types
3232

3333
# Hardhat files
3434
cache
35+
36+
# Generated schema and subgraph.yaml
37+
schema.graphql
38+
subgraph.yaml

subgraph/README.md

Lines changed: 122 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Subgraph Deployment and Client Usage
1+
# Filecoin Services Subgraph - Multi-Network Deployment
22

3-
This guide details the steps required to deploy the provided subgraph to Goldsky and run the accompanying subgraph client application.
3+
This guide details the steps required to deploy the subgraph to multiple Filecoin networks (testnet and mainnet) using mustache templating for network-specific configurations.
44

55
## Prerequisites
66

@@ -17,7 +17,108 @@ Before you begin, ensure you have the following installed and set up:
1717
3. **Goldsky Account:** You need an account on Goldsky to host your subgraph. Sign up at [goldsky.com](https://goldsky.com/).
1818
4. **Goldsky CLI:** This tool allows you to deploy subgraphs to the Goldsky platform. Follow the installation instructions in the [Goldsky Documentation](https://docs.goldsky.com/introduction).
1919

20-
## Deploying the Subgraph to Goldsky
20+
## Multi-Network Configuration
21+
22+
This subgraph supports deployment to multiple Filecoin networks using mustache templating. The configuration is managed through:
23+
24+
- **`config/network.json`**: Contains network-specific contract addresses and start blocks
25+
- **`templates/subgraph.template.yaml`**: Template file with mustache variables for subgraph configuration
26+
- **`templates/constants.template.ts`**: Template file with mustache variables for TypeScript constants
27+
- **`scripts/generate-config.js`**: Script to extract network-specific configuration
28+
- **`scripts/generate-constants.js`**: Script to generate TypeScript constants from template
29+
30+
### Available Networks
31+
32+
- **Calibration**: Calibration network configuration (ready to use)
33+
- **Mainnet**: Filecoin mainnet configuration (requires contract addresses)
34+
35+
### Quick Start Commands
36+
37+
For **Calibration**:
38+
39+
```bash
40+
# Build for calibration
41+
npm run build:calibration
42+
43+
# Deploy to calibration
44+
goldsky subgraph deploy <your-subgraph-name>/<version>
45+
```
46+
47+
For **Mainnet**:
48+
49+
```bash
50+
# Build for mainnet
51+
npm run build:mainnet
52+
53+
# Deploy to mainnet
54+
goldsky subgraph deploy <your-subgraph-name>/<version>
55+
```
56+
57+
### Available Scripts
58+
59+
The following npm scripts are available for multi-network deployment:
60+
61+
**Network-specific builds:**
62+
63+
- `npm run build:calibration` - Build for calibration network
64+
- `npm run build:mainnet` - Build for mainnet
65+
66+
**Template generation:**
67+
68+
- `npm run generate:yaml:calibration` - Generate subgraph.yaml for calibration
69+
- `npm run generate:yaml:mainnet` - Generate subgraph.yaml for mainnet
70+
71+
**Constants generation:**
72+
73+
- `npm run generate:constants:calibration` - Generate contract addresses for calibration
74+
- `npm run generate:constants:mainnet` - Generate contract addresses for mainnet
75+
76+
**Environment variable approach:**
77+
78+
```bash
79+
# Set network via environment variable (defaults to calibration)
80+
NETWORK=mainnet npm run precodegen
81+
```
82+
83+
**Cross-Platform Compatibility**: All scripts are designed to work on Windows, macOS, and Linux without requiring shell-specific features like pipes or redirects.
84+
85+
## Automated Contract Address Generation
86+
87+
One of the key features of this setup is **automated contract address generation**. Instead of manually updating hardcoded addresses in your TypeScript files, the system automatically generates them from your network configuration.
88+
89+
### How It Works
90+
91+
1. **Configuration Source**: Contract addresses are defined in `config/network.json`
92+
2. **Template Files**: Mustache templates in `templates/` define structure for generated files
93+
3. **Generation Scripts**:
94+
- `scripts/generate-config.js` extracts network config and optionally generates subgraph.yaml (cross-platform)
95+
- `scripts/generate-constants.js` uses `templates/constants.template.ts` to generate TypeScript constants
96+
4. **Generated Files**: Creates `src/generated/constants.ts` and `subgraph.yaml` with network-specific data
97+
5. **Import**: Your code imports from the generated file via `src/utils/constants.ts`
98+
99+
### Generated Constants Structure
100+
101+
The generated `src/generated/constants.ts` includes:
102+
103+
```typescript
104+
export class ContractAddresses {
105+
static readonly PDPVerifier: Address = Address.fromBytes(/*...*/);
106+
static readonly ServiceProviderRegistry: Address = Address.fromBytes(/*...*/);
107+
static readonly FilecoinWarmStorageService: Address = Address.fromBytes(/*...*/);
108+
static readonly USDFCToken: Address = Address.fromBytes(/*...*/);
109+
}
110+
```
111+
112+
### Usage in Code
113+
114+
```typescript
115+
import { ContractAddresses } from "./constants";
116+
117+
// Use network-specific addresses
118+
const pdpContract = PDPVerifier.bind(ContractAddresses.PDPVerifier);
119+
```
120+
121+
## Deploying the Subgraph
21122
22123
Follow these steps to build and deploy the subgraph:
23124
@@ -35,6 +136,8 @@ Follow these steps to build and deploy the subgraph:
35136
npm install
36137
# or
37138
yarn install
139+
# or
140+
npm install
38141
```
39142
40143
3. **Authenticate with Goldsky:**
@@ -44,21 +147,16 @@ Follow these steps to build and deploy the subgraph:
44147
goldsky login
45148
```
46149
47-
4. **Generate Code:**
48-
The Graph CLI uses the `subgraph.yaml` manifest and GraphQL schema (`schema.graphql`) to generate AssemblyScript types.
49-
50-
```bash
51-
graph codegen
52-
```
53-
54-
5. **Build the Subgraph:**
55-
Compile your subgraph code into WebAssembly (WASM).
150+
4. **Build the Subgraph:**
151+
Compile your subgraph code into WebAssembly (WASM) for the selected network ( calibration or mainnet).
56152
57153
```bash
58-
graph build
154+
npm run build:calibration
155+
# or
156+
npm run build:mainnet
59157
```
60158
61-
6. **Deploy to Goldsky:**
159+
5. **Deploy to Goldsky:**
62160
Use the Goldsky CLI to deploy your built subgraph.
63161
64162
```bash
@@ -69,8 +167,8 @@ Follow these steps to build and deploy the subgraph:
69167
- Replace `<version>` with a version identifier (e.g., `v0.0.1`).
70168
- You can manage your deployments and find your subgraph details in the [Goldsky Dashboard](https://app.goldsky.com/). The deployment command will output the GraphQL endpoint URL for your subgraph upon successful completion. **Copy this URL**, as you will need it for the client.
71169
72-
7. **Tag the Subgraph (Optional):**
73-
Tag the subgraph you deployed in step 6.
170+
6. **Tag the Subgraph (Optional):**
171+
Tag the subgraph you deployed in step 5.
74172
75173
```bash
76174
goldsky subgraph tag create <your-subgraph-name>/<version> --tag <tag-name>
@@ -90,43 +188,21 @@ If you need to make changes to the subgraph's logic, schema, or configuration, f
90188
91189
1. **Modify Code:** Edit the relevant files:
92190
93-
- `schema.graphql`: To change the data structure and entities being stored.
94-
- `subgraph.yaml`: To update contract addresses, ABIs, start blocks, or event handlers.
191+
- `config/network.json`: To update contract addresses.
192+
- `schemas/schema.*.graphql`: To change the data structure and entities being stored.
193+
- `templates/subgraph.template.yaml`: To update contract addresses, ABIs, start blocks, or event handlers.
95194
- `src/*.ts`: To alter the logic that processes blockchain events and maps them to the defined schema entities.
96195
- `src/utils/*.ts`: If modifying shared utility functions or constants.
97196
98-
2. **Important Note on PDPVerifier Address:** Several handlers make a contract call to the PDPVerifier and ServiceProviderRegistry contract. The address for these contracts is currently hardcoded in `subgraph/src/utils/constants.ts`:
99-
100-
```typescript
101-
// subgraph/src/utils/constants.ts
102-
export class ContractAddresses {
103-
static readonly PDPVerifier: Address = Address.fromBytes(
104-
Bytes.fromHexString("0x445238Eca6c6aB8Dff1Aa6087d9c05734D22f137"),
105-
);
106-
static readonly ServiceProviderRegistry: Address = Address.fromBytes(
107-
Bytes.fromHexString("0xA8a7e2130C27e4f39D1aEBb3D538D5937bCf8ddb"),
108-
);
109-
static readonly USDFCToken: Address = Address.fromBytes(
110-
Bytes.fromHexString("0xb3042734b608a1B16e9e86B374A3f3e389B4cDf0"),
111-
);
112-
}
113-
```
114-
115-
**If you update the `PDPVerifier` and `ServiceProviderRegistry` contract address in your `subgraph.yaml` file to index a different deployment, you MUST also update the `ContractAddresses.PDPVerifier` and `ContractAddresses.ServiceProviderRegistry` constants in `subgraph/src/utils/constants.ts` to match the new addresses.** Failure to do so will result in the wrong contract instance being called.
116-
117-
3. **Regenerate Code:** After modifying the schema or manifest, always regenerate the AssemblyScript types:
118-
119-
```bash
120-
graph codegen
121-
```
122-
123-
4. **Rebuild:** Compile the updated subgraph code:
197+
2. **Rebuild:** Compile the updated subgraph code using `npm run build:<network>`:
124198
125199
```bash
126-
graph build
200+
npm run build:calibration
201+
# or
202+
npm run build:mainnet
127203
```
128204
129-
5. **Redeploy:** Deploy the new version to Goldsky. It's good practice to increment the version number:
205+
3. **Redeploy:** Deploy the new version to Goldsky. It's good practice to increment the version number:
130206
```bash
131207
goldsky subgraph deploy <your-subgraph-name>/<new-version> --path ./
132208
```

subgraph/config/network.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"networks": {
3+
"calibration": {
4+
"name": "filecoin-testnet",
5+
"PDPVerifier": {
6+
"address": "0x445238Eca6c6aB8Dff1Aa6087d9c05734D22f137",
7+
"startBlock": 2988297
8+
},
9+
"FilecoinWarmStorageService": {
10+
"address": "0x80617b65FD2EEa1D7fDe2B4F85977670690ed348",
11+
"startBlock": 2988329
12+
},
13+
"ServiceProviderRegistry": {
14+
"address": "0xA8a7e2130C27e4f39D1aEBb3D538D5937bCf8ddb",
15+
"startBlock": 2988311
16+
},
17+
"USDFCToken": {
18+
"address": "0xb3042734b608a1B16e9e86B374A3f3e389B4cDf0",
19+
"startBlock": 2988000
20+
}
21+
},
22+
"mainnet": {
23+
"name": "filecoin",
24+
"PDPVerifier": {
25+
"address": "0x0000000000000000000000000000000000000000",
26+
"startBlock": 1000000,
27+
"comment": "TODO: Replace with actual mainnet deployment address"
28+
},
29+
"FilecoinWarmStorageService": {
30+
"address": "0x0000000000000000000000000000000000000000",
31+
"startBlock": 1000000,
32+
"comment": "TODO: Replace with actual mainnet deployment address"
33+
},
34+
"ServiceProviderRegistry": {
35+
"address": "0x0000000000000000000000000000000000000000",
36+
"startBlock": 1000000,
37+
"comment": "TODO: Replace with actual mainnet deployment address"
38+
},
39+
"USDFCToken": {
40+
"address": "0x0000000000000000000000000000000000000000",
41+
"startBlock": 1000000,
42+
"comment": "TODO: Replace with actual mainnet deployment address"
43+
}
44+
}
45+
}
46+
}

subgraph/networks.json

Lines changed: 0 additions & 12 deletions
This file was deleted.

subgraph/package.json

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,36 @@
11
{
2-
"name": "synapse-m1",
2+
"name": "synapse",
33
"license": "UNLICENSED",
44
"scripts": {
5+
"precodegen": "pnpm generate:constants && pnpm generate:schema && pnpm generate:yaml",
56
"codegen": "graph codegen",
7+
"generate:constants": "node ./scripts/generate-constants.js",
8+
"generate:constants:calibration": "node ./scripts/generate-constants.js calibration",
9+
"generate:constants:mainnet": "node ./scripts/generate-constants.js mainnet",
10+
"generate:yaml": "node ./scripts/generate-config.js --yaml",
11+
"generate:yaml:calibration": "node ./scripts/generate-config.js calibration --yaml",
12+
"generate:yaml:mainnet": "node ./scripts/generate-config.js mainnet --yaml",
13+
"generate:schema": "cp ./schemas/schema.${VERSION:-v1}.graphql schema.graphql",
14+
"prebuild": "pnpm codegen",
615
"build": "graph build",
7-
"deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ synapse-m1",
8-
"create-local": "graph create --node http://localhost:8020/ synapse-m1",
9-
"remove-local": "graph remove --node http://localhost:8020/ synapse-m1",
10-
"deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 synapse-m1",
16+
"build:calibration": "NETWORK=calibration pnpm run build",
17+
"build:mainnet": "NETWORK=mainnet pnpm run build",
18+
"deploy": "goldsky subgraph deploy synapse/1.0.0 --path ./",
19+
"deploy:calibration": "pnpm run build:calibration && pnpm run deploy",
20+
"deploy:mainnet": "pnpm run build:mainnet && pnpm run deploy",
21+
"create-local": "graph create --node http://localhost:8020/ synapse",
22+
"remove-local": "graph remove --node http://localhost:8020/ synapse",
23+
"deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 synapse",
24+
"deploy-local:calibration": "pnpm run build:calibration && pnpm run deploy-local",
25+
"deploy-local:mainnet": "pnpm run build:mainnet && pnpm run deploy-local",
1126
"test": "graph test"
1227
},
1328
"dependencies": {
1429
"@graphprotocol/graph-cli": "0.97.0",
1530
"@graphprotocol/graph-ts": "0.37.0"
1631
},
1732
"devDependencies": {
18-
"matchstick-as": "0.6.0"
33+
"matchstick-as": "0.6.0",
34+
"mustache": "^4.2.0"
1935
}
2036
}
File renamed without changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env node
2+
3+
const fs = require("fs");
4+
const path = require("path");
5+
const mustache = require("mustache");
6+
const { loadNetworkConfig } = require("./utils/config-loader");
7+
8+
// Parse command line arguments
9+
const args = process.argv.slice(2);
10+
const shouldGenerateYaml = args.includes("--yaml");
11+
12+
// Get network from command line arguments (excluding flags) or environment variable
13+
const networkArgs = args.filter((arg) => !arg.startsWith("--"));
14+
const network = process.env.NETWORK || networkArgs[0] || "calibration";
15+
16+
const selectedConfig = loadNetworkConfig(network);
17+
18+
if (shouldGenerateYaml) {
19+
const templatePath = path.join(__dirname, "..", "templates", "subgraph.template.yaml");
20+
let templateContent;
21+
22+
try {
23+
templateContent = fs.readFileSync(templatePath, "utf8");
24+
} catch (error) {
25+
console.error(`Error: Failed to read subgraph template at: ${templatePath}`);
26+
console.error(`Template Error: ${error.message}`);
27+
process.exit(1);
28+
}
29+
30+
const yamlContent = mustache.render(templateContent, selectedConfig);
31+
32+
const outputPath = path.join(__dirname, "..", "subgraph.yaml");
33+
34+
try {
35+
fs.writeFileSync(outputPath, yamlContent);
36+
console.log(`✅ Generated subgraph.yaml for ${network} network at: ${outputPath}`);
37+
} catch (error) {
38+
console.error(`Error: Failed to write subgraph.yaml to: ${outputPath}`);
39+
console.error(`Write Error: ${error.message}`);
40+
process.exit(1);
41+
}
42+
} else {
43+
console.log(JSON.stringify(selectedConfig, null, 2));
44+
}

0 commit comments

Comments
 (0)