Skip to content

Commit 46841af

Browse files
authored
feat!(network): uses meta.json instead of version.txt and removes GET /v1/version/{network}
BREAKING CHANGE: removes GET /v1/version/{network} closes #2091
1 parent bb25b00 commit 46841af

File tree

10 files changed

+85
-128
lines changed

10 files changed

+85
-128
lines changed

apps/api/src/network/controllers/network/network.controller.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,4 @@ export class NetworkController {
1212
async getNodes(network: GetNodesParams["network"]): Promise<Result<GetNodesResponse, HttpError>> {
1313
return await this.networkService.getNodes(network);
1414
}
15-
16-
async getVersion(network: GetNodesParams["network"]): Promise<Result<string, HttpError>> {
17-
return await this.networkService.getVersion(network);
18-
}
1915
}

apps/api/src/network/routes/network/network.router.ts

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { OpenApiHonoHandler } from "@src/core/services/open-api-hono-handler/ope
55
import { NetworkController } from "@src/network/controllers/network/network.controller";
66
import { GetNodesParamsSchema, GetNodesResponseSchema } from "@src/network/http-schemas/network.schema";
77

8+
export const networkRouter = new OpenApiHonoHandler();
9+
810
const getNodesRoute = createRoute({
911
method: "get",
1012
path: "/v1/nodes/{network}",
@@ -25,25 +27,6 @@ const getNodesRoute = createRoute({
2527
}
2628
});
2729

28-
const getVersionRoute = createRoute({
29-
method: "get",
30-
path: "/v1/version/{network}",
31-
summary: "Get network version.",
32-
description:
33-
"Provide a cached version of one of these files: [https://raw.githubusercontent.com/akash-network/net/master/mainnet/version.txt](https://raw.githubusercontent.com/akash-network/net/master/mainnet/version.txt), [https://raw.githubusercontent.com/akash-network/net/master/sandbox/version.txt](https://raw.githubusercontent.com/akash-network/net/master/sandbox/version.txt), [https://raw.githubusercontent.com/akash-network/net/master/testnet-02/version.txt](https://raw.githubusercontent.com/akash-network/net/master/testnet-02/version.txt)",
34-
tags: ["Chain"],
35-
request: {
36-
params: GetNodesParamsSchema
37-
},
38-
responses: {
39-
200: {
40-
description: "Network version"
41-
}
42-
}
43-
});
44-
45-
export const networkRouter = new OpenApiHonoHandler();
46-
4730
networkRouter.openapi(getNodesRoute, async function routeGetNodes(c) {
4831
const { network } = c.req.valid("param");
4932
const result = await container.resolve(NetworkController).getNodes(network);
@@ -54,14 +37,3 @@ networkRouter.openapi(getNodesRoute, async function routeGetNodes(c) {
5437

5538
throw result.val;
5639
});
57-
58-
networkRouter.openapi(getVersionRoute, async function routeGetVersion(c) {
59-
const { network } = c.req.valid("param");
60-
const result = await container.resolve(NetworkController).getVersion(network);
61-
62-
if (result.ok) {
63-
return c.text(result.val);
64-
}
65-
66-
throw result.val;
67-
});

apps/api/src/network/services/network/network.service.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,4 @@ export class NetworkService {
2828
throw error;
2929
}
3030
}
31-
32-
@Memoize({ ttlInSeconds: minutesToSeconds(5) })
33-
async getVersion(network: GetNodesParams["network"]): Promise<Result<string, HttpError>> {
34-
try {
35-
return Ok(await this.nodeHttpService.getVersion(this.netConfig.mapped(network)));
36-
} catch (error) {
37-
if (error instanceof AxiosError && error.status === 404) {
38-
return Err(new NotFound("Network version not found"));
39-
}
40-
41-
throw error;
42-
}
43-
}
4431
}

apps/api/test/functional/__snapshots__/docs.spec.ts.snap

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14104,35 +14104,6 @@ exports[`API Docs GET /v1/doc returns docs with all routes expected 1`] = `
1410414104
],
1410514105
},
1410614106
},
14107-
"/v1/version/{network}": {
14108-
"get": {
14109-
"description": "Provide a cached version of one of these files: [https://raw.githubusercontent.com/akash-network/net/master/mainnet/version.txt](https://raw.githubusercontent.com/akash-network/net/master/mainnet/version.txt), [https://raw.githubusercontent.com/akash-network/net/master/sandbox/version.txt](https://raw.githubusercontent.com/akash-network/net/master/sandbox/version.txt), [https://raw.githubusercontent.com/akash-network/net/master/testnet-02/version.txt](https://raw.githubusercontent.com/akash-network/net/master/testnet-02/version.txt)",
14110-
"parameters": [
14111-
{
14112-
"in": "path",
14113-
"name": "network",
14114-
"required": true,
14115-
"schema": {
14116-
"enum": [
14117-
"mainnet",
14118-
"testnet",
14119-
"sandbox",
14120-
],
14121-
"type": "string",
14122-
},
14123-
},
14124-
],
14125-
"responses": {
14126-
"200": {
14127-
"description": "Network version",
14128-
},
14129-
},
14130-
"summary": "Get network version.",
14131-
"tags": [
14132-
"Chain",
14133-
],
14134-
},
14135-
},
1413614107
"/v1/wallets": {
1413714108
"get": {
1413814109
"parameters": [

apps/api/test/functional/nodes-v1.spec.ts

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { netConfig } from "@akashnetwork/net";
2-
import { faker } from "@faker-js/faker";
32
import mcache from "memory-cache";
43
import nock from "nock";
54

@@ -48,30 +47,4 @@ describe("Nodes API", () => {
4847
expect(response.status).toBe(400);
4948
});
5049
});
51-
52-
describe("GET /version/{network}", () => {
53-
it.each(["mainnet", "sandbox", "testnet"])("should return %s node version", async network => {
54-
const version = `v${faker.number.int({ min: 0, max: 10 })}.${faker.number.int({ min: 0, max: 10 })}.${faker.number.int({ min: 0, max: 10 })}`;
55-
interceptor
56-
.get(`/net/master/${netConfig.mapped(network)}/version.txt`)
57-
.times(1)
58-
.reply(200, version, {
59-
"Content-Type": "text/plain"
60-
});
61-
62-
const resInit = await app.request(`/v1/version/${network}`);
63-
expect(resInit.status).toBe(200);
64-
expect(await resInit.text()).toEqual(version);
65-
66-
const resCached = await app.request(`/v1/version/${network}`);
67-
expect(resCached.status).toBe(200);
68-
expect(await resCached.text()).toEqual(version);
69-
});
70-
71-
it("throws 400 for an invalid network", async () => {
72-
const response = await app.request("/v1/version/invalid-network");
73-
74-
expect(response.status).toBe(400);
75-
});
76-
});
7750
});

packages/http-sdk/src/node/node-http.service.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
import type { SupportedChainNetworks } from "@akashnetwork/net";
2+
import z from "zod";
23

34
import { extractData } from "../http/http.service";
45
import type { HttpClient } from "../utils/httpClient";
56
import type { NetworkNode } from "./types";
67

8+
const metaSchema = z.object({
9+
codebase: z.object({
10+
recommended_version: z.string()
11+
})
12+
});
13+
14+
type Meta = z.infer<typeof metaSchema>;
15+
716
export class NodeHttpService {
817
constructor(private readonly httpClient: HttpClient) {}
918

@@ -14,4 +23,9 @@ export class NodeHttpService {
1423
async getVersion(network: SupportedChainNetworks): Promise<string> {
1524
return extractData(await this.httpClient.get<string>(`net/master/${network}/version.txt`));
1625
}
26+
27+
async getMeta(network: SupportedChainNetworks): Promise<Meta> {
28+
const response = extractData(await this.httpClient.get<unknown>(`net/master/${network}/meta.json`));
29+
return metaSchema.parse(response);
30+
}
1731
}

packages/net/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
},
2020
"devDependencies": {
2121
"jest": "^29.7.0",
22-
"typescript": "~5.8.2"
22+
"typescript": "~5.8.2",
23+
"zod": "3.*"
2324
}
2425
}

packages/net/scripts/generate.ts

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import fsp from "fs/promises";
22
import { dirname, join as joinPath, normalize } from "path";
33
import { fileURLToPath } from "url";
4+
import * as z from "zod";
5+
import { ZodError } from "zod";
46

57
const scriptDir = dirname(fileURLToPath(import.meta.url));
68
const PROJECT_DIR = normalize(joinPath(scriptDir, "..", "..", ".."));
@@ -9,23 +11,43 @@ const OUT_DIR = joinPath(PACKAGE_DIR, "src", "generated");
911
const AKASH_NET_BASE = "https://raw.githubusercontent.com/akash-network/net/main";
1012
const networks = ["mainnet", "sandbox", "sandbox-2", "testnet-02", "testnet-7"];
1113

14+
const apiSchema = z.object({
15+
address: z.string()
16+
});
17+
18+
const metaSchema = z.object({
19+
codebase: z.object({
20+
recommended_version: z.string()
21+
}),
22+
apis: z.object({
23+
rest: z.array(apiSchema),
24+
rpc: z.array(apiSchema)
25+
})
26+
});
27+
1228
async function main() {
1329
console.log(`Generate network configuration: ${networks.join(", ")}`);
1430
const config: Record<string, unknown> = {};
1531
for (const network of networks) {
1632
const baseConfigUrl = `${AKASH_NET_BASE}/${network}`;
17-
const [apiUrls, rpcUrls, version, faucetUrl] = await Promise.all([
18-
fetchText(`${baseConfigUrl}/api-nodes.txt`),
19-
fetchText(`${baseConfigUrl}/rpc-nodes.txt`),
20-
fetchText(`${baseConfigUrl}/version.txt`).catch(() => null),
33+
const [meta, faucetUrl] = await Promise.all([
34+
fetchJson(`${baseConfigUrl}/meta.json`)
35+
.then(res => metaSchema.parse(res))
36+
.catch(error => {
37+
if (error instanceof ZodError) {
38+
console.log("meta.json is invalid", error);
39+
}
40+
41+
return null;
42+
}),
2143
fetchText(`${baseConfigUrl}/faucet-url.txt`).catch(() => null)
2244
]);
2345

2446
const networkConfig = {
25-
version: version?.trim() ?? null,
47+
version: meta?.codebase?.recommended_version ?? null,
2648
faucetUrl: faucetUrl?.trim() ?? null,
27-
apiUrls: apiUrls.trim().split("\n"),
28-
rpcUrls: rpcUrls.trim().split("\n")
49+
apiUrls: meta?.apis?.rest?.map(({ address }) => address) ?? [],
50+
rpcUrls: meta?.apis?.rpc?.map(({ address }) => address) ?? []
2951
};
3052

3153
if (network === "mainnet") {
@@ -50,4 +72,13 @@ function fetchText(url: string): Promise<string> {
5072
});
5173
}
5274

75+
function fetchJson(url: string): Promise<unknown> {
76+
return fetch(url).then(res => {
77+
if (!res.ok) {
78+
throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
79+
}
80+
return res.json();
81+
});
82+
}
83+
5384
main().catch(console.error);

packages/net/src/NetConfig/NetConfig.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ export class NetConfig {
2020
throw new Error(`Network ${network} not supported`);
2121
}
2222

23-
getVersion(network: SupportedChainNetworks): string | null {
23+
getVersion(network: string): string | null {
2424
return netConfigData[this.mapped(network)].version;
2525
}
2626

27-
getBaseAPIUrl(network: SupportedChainNetworks): string {
27+
getBaseAPIUrl(network: string): string {
2828
const apiUrls = netConfigData[this.mapped(network)].apiUrls;
2929
return apiUrls[0];
3030
}
@@ -37,7 +37,7 @@ export class NetConfig {
3737
return netConfigData[this.mapped(network)].faucetUrl;
3838
}
3939

40-
getBaseRpcUrl(network: SupportedChainNetworks): string {
40+
getBaseRpcUrl(network: string): string {
4141
const rpcUrls = netConfigData[this.mapped(network)].rpcUrls;
4242
return rpcUrls[0];
4343
}

packages/net/src/generated/netConfigData.ts

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,53 @@
11
export const netConfigData = {
22
mainnet: {
3-
version: "0.38.0",
3+
version: "v0.38.1",
44
faucetUrl: null,
55
apiUrls: [
6-
"https://api.akashnet.net:443",
7-
"https://akash-api.polkachu.com:443",
6+
"https://rest-akash.ecostake.com",
7+
"https://rest.lavenderfive.com:443/akash",
8+
"https://akash-api.polkachu.com",
89
"https://akash.c29r3.xyz:443/api",
9-
"https://akash-api.global.ssl.fastly.net:443"
10+
"https://akash-mainnet-lcd.autostake.com:443",
11+
"https://akash-api.kleomedes.network",
12+
"https://api-akash-01.stakeflow.io",
13+
"https://akash-mainnet-rest.cosmonautstakes.com:443",
14+
"https://akash-api.w3coins.io",
15+
"https://akash-rest.publicnode.com",
16+
"https://akash-api.validatornode.com",
17+
"https://lcd.akash.bronbro.io:443"
1018
],
1119
rpcUrls: [
12-
"https://rpc.akashnet.net:443",
1320
"https://rpc-akash.ecostake.com:443",
14-
"https://akash-rpc.polkachu.com:443",
15-
"https://akash.c29r3.xyz:443/rpc",
16-
"https://akash-rpc.europlots.com:443"
21+
"https://rpc.lavenderfive.com:443/akash",
22+
"https://akash-rpc.polkachu.com",
23+
"https://akash.c29r3.xyz:80/rpc",
24+
"https://akash-rpc.kleomedes.network",
25+
"https://akash-mainnet-rpc.cosmonautstakes.com:443",
26+
"https://akash-rpc.w3coins.io",
27+
"https://akash-rpc.publicnode.com:443",
28+
"https://rpc.akash.bronbro.io:443"
1729
]
1830
},
1931
sandbox: {
20-
version: "0.38.0",
32+
version: "v0.38.1",
2133
faucetUrl: "http://faucet.sandbox-01.aksh.pw/",
2234
apiUrls: ["https://api.sandbox-01.aksh.pw:443"],
2335
rpcUrls: ["https://rpc.sandbox-01.aksh.pw:443"]
2436
},
2537
"sandbox-2": {
26-
version: "0.38.0",
38+
version: "v0.38.2",
2739
faucetUrl: "http://faucet.sandbox-2.aksh.pw/",
2840
apiUrls: ["https://api.sandbox-2.aksh.pw:443"],
2941
rpcUrls: ["https://rpc.sandbox-2.aksh.pw:443"]
3042
},
3143
"testnet-02": {
32-
version: "0.23.1-rc0",
44+
version: "v0.23.1-rc0",
3345
faucetUrl: "https://faucet.testnet-02.aksh.pw",
34-
apiUrls: ["https://api.testnet-02.aksh.pw:443", "https://akash-testnet-rest.cosmonautstakes.com:443"],
35-
rpcUrls: ["https://rpc.testnet-02.aksh.pw:443", "https://akash-testnet-rpc.cosmonautstakes.com:443"]
46+
apiUrls: ["https://api.testnet-02.aksh.pw:443"],
47+
rpcUrls: ["https://rpc.testnet-02.aksh.pw:443"]
3648
},
3749
"testnet-7": {
38-
version: "1.0.0-rc55",
50+
version: "v1.0.0-rc55",
3951
faucetUrl: "https://faucet.dev.akash.pub/",
4052
apiUrls: ["https://testnetapi.akashnet.net"],
4153
rpcUrls: ["https://testnetrpc.akashnet.net:443"]

0 commit comments

Comments
 (0)