Skip to content

Commit ea4765d

Browse files
committed
refactor: use deployments package
1 parent 9f2fba0 commit ea4765d

File tree

110 files changed

+2344
-7212
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+2344
-7212
lines changed

.eslintignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
# directories
22
.docusaurus
3+
build
34
node_modules
45
repos
6+
src/autogen/**/*.mdx
7+
static
58

69
# files
710
babel.config.js
811
docusaurus.config.ts
12+
sidebars.js

.gitignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
.docusaurus
44
build
55
node_modules
6+
src/autogen/**/*.mdx
67

78
# files
89
*.env
910
*.log
1011
*.tsbuildinfo
1112
.DS_Store
1213
.eslintcache
13-
.pnp.*
1414
package-lock.json
15-
pnpm-lock.yaml
16-
yarn.lock

.lintstagedrc.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
"*.{json,md,mdx,ts,tsx,yml}": "bun run fix"
1+
"*.{md,mdx,ts,tsx}": "bun run fix"
2+
"*.{json,yml}": "bun run prettier:write"

.prettierignore

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
# directories
2-
.cache-loader
32
.docusaurus
43
build
54
node_modules
65
repos
6+
src/autogen/**/*.mdx
7+
static
78

89
# files
9-
.pnp.*
1010
package-lock.json
11-
pnpm-lock.yaml

.vscode/settings.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
"eslint.validate": ["markdown", "mdx", "javascript", "javascriptreact", "typescript", "typescriptreact"],
44
"prettier.documentSelectors": ["**/*.tsx"],
55
"search.exclude": {
6-
"**/.docusaurus": true,
7-
"**/node_modules": true,
8-
"**/repos": true
6+
".docusaurus": true,
7+
"build": true,
8+
"node_modules": true,
9+
"repos": true
910
},
10-
"typescript.tsdk": "node_modules/typescript/lib"
11+
"typescript.tsdk": "node_modules/typescript/lib",
12+
"[javascript][javascriptreact][typescript][typescriptreact]": {
13+
"editor.defaultFormatter": "esbenp.prettier-vscode"
14+
}
1115
}

bun.lock

Lines changed: 1008 additions & 3730 deletions
Large diffs are not rendered by default.
File renamed without changes.

cli/commands/deployments.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { Command } from "commander";
2+
import { Protocol, type Sablier, sablier } from "sablier";
3+
import type { CliOptions } from "../types";
4+
import { Links } from "../../src/constants";
5+
import * as helpers from "../helpers";
6+
7+
export function createDeploymentsCommand(): Command {
8+
return new Command("deployments")
9+
.description("Generate deployment tables for all Sablier releases")
10+
.action(async (_options, command) => {
11+
const globalOptions = command.parent?.opts() || {};
12+
await generateDeployments(globalOptions);
13+
});
14+
}
15+
16+
export async function generateDeployments(options: CliOptions = {}): Promise<void> {
17+
for (const release of sablier.releases.getAll()) {
18+
if (release.protocol === Protocol.Legacy) {
19+
continue;
20+
}
21+
22+
const tables = generateTables(release);
23+
if (!tables) {
24+
continue;
25+
}
26+
27+
const fileName = helpers.autogenFileNames.deployments(release.version);
28+
const filePath = helpers.getAutogenFilePath(release.protocol, fileName);
29+
30+
if (helpers.writeFileWithOverride({ filePath, content: tables, options })) {
31+
helpers.log(`✅ Generated table with deployments for ${release.protocol} ${release.version}`, options);
32+
}
33+
}
34+
}
35+
36+
function generateTables(release: Sablier.Release) {
37+
const mainnetDeployments = release.deployments.filter((d) => {
38+
const chain = sablier.chains.get(d.chainId);
39+
return !chain.isTestnet;
40+
});
41+
const testnetDeployments = release.deployments.filter((d) => {
42+
const chain = sablier.chains.get(d.chainId);
43+
return chain.isTestnet;
44+
});
45+
46+
let content = "## Mainnets\n\n";
47+
for (const deployment of mainnetDeployments) {
48+
const chain = sablier.chains.get(deployment.chainId);
49+
content += `### ${chain.name}\n\n`;
50+
content += generateDeploymentTable(deployment, release.protocol, release.version);
51+
content += "\n";
52+
}
53+
54+
content += "## Testnets\n\n";
55+
for (const deployment of testnetDeployments) {
56+
const chain = sablier.chains.get(deployment.chainId);
57+
content += `### ${chain.name}\n\n`;
58+
content += generateDeploymentTable(deployment, release.protocol, release.version);
59+
content += "\n";
60+
}
61+
62+
return content;
63+
}
64+
65+
function generateDeploymentTable(deployment: Sablier.Deployment, protocol: Sablier.Protocol, version: string): string {
66+
let table = `| Contract | Address | Deployment |\n`;
67+
table += `| :-------- | :-------- | :--------- |\n`;
68+
69+
for (const contract of deployment.contracts) {
70+
let address: string;
71+
if (contract.explorerURL) {
72+
address = `[\`${contract.address}\`](${contract.explorerURL})`;
73+
} else {
74+
address = `\`${contract.address}\``;
75+
}
76+
const link = `[\`${protocol}-${version}\`](${Links.GitHub.SDK}/blob/main/deployments/${protocol}/${version})`;
77+
table += `| ${contract.name} | ${address} | ${link} |\n`;
78+
}
79+
80+
return table;
81+
}

cli/commands/indexers.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { type Indexer, indexers } from "@sablier/indexers";
2+
import { Command } from "commander";
3+
import { sablier } from "sablier";
4+
import type { CliOptions } from "../types";
5+
import * as helpers from "../helpers";
6+
7+
export function createIndexersCommand(): Command {
8+
return new Command("indexers")
9+
.description("Generate indexer endpoint tables for all Sablier protocols")
10+
.action(async (_options, command) => {
11+
const globalOptions = command.parent?.opts() || {};
12+
await generateIndexers(globalOptions);
13+
});
14+
}
15+
16+
export async function generateIndexers(options: CliOptions = {}): Promise<void> {
17+
generateTables("airdrops", options);
18+
generateTables("flow", options);
19+
generateTables("lockup", options);
20+
}
21+
22+
function generateTables(protocol: Indexer.Protocol, options: CliOptions): void {
23+
const graphTable = generateGraphTable(indexers.graph[protocol]);
24+
const envioTable = generateEnvioTable(indexers.envio[protocol]);
25+
26+
const graphFilePath = helpers.getAutogenFilePath(protocol, helpers.autogenFileNames.theGraph);
27+
if (helpers.writeFileWithOverride({ filePath: graphFilePath, content: graphTable, options })) {
28+
helpers.log(`✅ Generated table with The Graph subgraphs for ${protocol}`, options);
29+
}
30+
31+
const envioFilePath = helpers.getAutogenFilePath(protocol, helpers.autogenFileNames.envio);
32+
if (helpers.writeFileWithOverride({ filePath: envioFilePath, content: envioTable, options })) {
33+
helpers.log(`✅ Generated table with Envio endpoints for ${protocol}`, options);
34+
}
35+
}
36+
37+
function generateGraphTable(indexers: Indexer[]): string {
38+
let markdown = `| Chain | Production URL | Studio URL | Playground URL |\n`;
39+
markdown += `| -------- | -------------- | ---------- | -------------- |\n`;
40+
41+
for (const indexer of indexers) {
42+
const chain = sablier.chains.getOrThrow(indexer.chainId);
43+
44+
const productionURL = indexer.endpoint.url;
45+
const studioURL = indexer.explorerURL;
46+
const playgroundURL = indexer.playgroundURL;
47+
48+
const productionCell = `[${indexer.name}](${productionURL})`;
49+
const studioCell = studioURL ? `[Studio](${studioURL})` : "N/A";
50+
const playgroundCell = playgroundURL ? `[GraphiQL Playground](${playgroundURL})` : "N/A";
51+
52+
markdown += `| ${chain.name} | ${productionCell} | ${studioCell} | ${playgroundCell} |\n`;
53+
}
54+
55+
return markdown;
56+
}
57+
58+
function generateEnvioTable(indexers: Indexer[]): string {
59+
let markdown = `| Chain | Endpoint |\n`;
60+
markdown += `| -------- | -------- |\n`;
61+
62+
for (const indexer of indexers) {
63+
const chain = sablier.chains.get(indexer.chainId);
64+
if (!chain || !chain.name) {
65+
continue;
66+
}
67+
markdown += `| ${chain.name} | ${indexer.endpoint.url} |\n`;
68+
}
69+
70+
return markdown;
71+
}

cli/helpers.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as fs from "node:fs";
2+
import * as path from "node:path";
3+
import type { CliOptions } from "./types";
4+
import type { Sablier } from "sablier";
5+
6+
const ROOT_DIR = path.join(__dirname, "..");
7+
if (!fs.existsSync(path.join(ROOT_DIR, "package.json"))) {
8+
throw new Error("ROOT_DIR is not set correctly");
9+
}
10+
11+
export const autogenFileNames = {
12+
deployments: (version: Sablier.Version) =>
13+
`TableDeployments${version.charAt(0).toUpperCase() + version.slice(1)}.mdx`,
14+
envio: "TableEnvio.mdx",
15+
theGraph: "TableTheGraph.mdx",
16+
};
17+
18+
export function getAutogenFilePath(protocol: string, fileName: string): string {
19+
return path.join(ROOT_DIR, "src", "autogen", protocol, fileName);
20+
}
21+
export function log(message: string, options: CliOptions): void {
22+
if (options.verbose) {
23+
console.log(message);
24+
}
25+
}
26+
27+
type FileWriteParams = {
28+
filePath: string;
29+
content: string;
30+
encoding?: BufferEncoding;
31+
options: CliOptions;
32+
};
33+
34+
export function writeFileWithOverride(params: FileWriteParams): boolean {
35+
const { filePath, content, encoding = "utf8", options } = params;
36+
37+
if (fs.existsSync(filePath) && !options.override) {
38+
const relativePath = path.relative(process.cwd(), filePath);
39+
log(`❌ File already exists: ${relativePath}. Use --override flag to override.`, options);
40+
return false;
41+
}
42+
43+
fs.writeFileSync(filePath, content, encoding);
44+
return true;
45+
}

0 commit comments

Comments
 (0)