Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: OpenAPI integrated for mirror node models generation #329

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,49 @@ To **format** the code run:
npm run format
```

### OpenAPI Model Generation

The TCK uses OpenAPI model generation to create TypeScript interfaces and types from the `Hiero Mirror Node API` specification. This allows for type-safe interaction with the Mirror Node API and provides better development experience with autocompletion and type checking.

The OpenAPI specification is defined in `mirror-node.yaml` and contains the complete API schema, including:
- API endpoints and their paths
- Request/response structures
- Data types and models
- Query parameters
- Authentication methods

#### Generation Process

1. Generate the TypeScript models:
```bash
npm run generate-mirror-node-models
```

2. Clean up and reorganize the generated files:
```bash
task cleanup-generated-mirror-node-models
```

The cleanup task (defined in `Taskfile.yaml`) performs the following:
- Removes unnecessary `core` and `services` directories
- Flattens the directory structure by moving files from `models/` to the root
- Updates import paths in `index.ts` to reflect the new structure

### You can also run both steps together using (*recommended*):
```bash
task generate-mirror-node-models
```

This command uses `openapi-typescript-codegen` to parse the `mirror-node.yaml` file and generate corresponding TypeScript models in `src/utils/models/mirror-node-models`


## Contributing

Whether you’re fixing bugs, enhancing features, or improving documentation, your contributions are important — let’s build something great together!

Please read our [contributing guide](https://github.com/hiero-ledger/.github/blob/main/CONTRIBUTING.md) to see how you can get involved.


## Code of Conduct

Hiero uses the Linux Foundation Decentralised Trust [Code of Conduct](https://www.lfdecentralizedtrust.org/code-of-conduct).
Expand Down
35 changes: 35 additions & 0 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
version: "3"

tasks:
cleanup-generated-mirror-node-models:
desc: Cleans up generated OpenAPI files and reorganizes the structure
cmds:
# Remove core and services directories
- rm -rf src/utils/models/mirror-node-models/core
- rm -rf src/utils/models/mirror-node-models/services

# Move all files from models directory to mirror-node-models
- mv src/utils/models/mirror-node-models/models/* src/utils/models/mirror-node-models/

# Remove the now-empty models directory
- rm -rf src/utils/models/mirror-node-models/models

# Update index.ts using Node.js
- node -e "
const fs = require('fs');
const path = 'src/utils/models/mirror-node-models/index.ts';
let content = fs.readFileSync(path, 'utf8');
content = content.split('\n')
.filter(line => !line.includes('/core/') && !line.includes('/services/'))
.map(line => line.replace('./models/', './'))
.join('\n');
fs.writeFileSync(path, content);
"
status:
- test ! -d src/utils/models/mirror-node-models

generate-mirror-node-models:
desc: Generates OpenAPI models and cleans up the structure
cmds:
- npm run generate-mirror-node-models
- task: cleanup-generated-mirror-node-models
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"scripts": {
"test": "mocha --require ts-node/register --require tsconfig-paths/register --recursive 'src/tests/**/*.ts' --reporter mochawesome --exit",
"test:file": "mocha --require ts-node/register --require tsconfig-paths/register --reporter mochawesome --exit",
"generate-mirror-node-models": "npx openapi-typescript-codegen --input mirror-node.yaml --output src/utils/models/mirror-node-models.ts",
"generate-mirror-node-models": "npx openapi-typescript-codegen --input mirror-node.yaml --output src/utils/models/mirror-node-models",
"format": "prettier --write .",
"lint": "eslint ."
},
Expand Down
5 changes: 3 additions & 2 deletions src/services/MirrorNodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { fetchData } from "@helpers/fetch-data";
import { retryOnError } from "@helpers/retry-on-error";

import {
TokenRelationshipResponse,
AccountInfo,
CryptoAllowancesResponse,
NftAllowancesResponse,
Nfts,
TokenInfo,
} from "@models/mirror-node-models.ts";
} from "@models/mirror-node-models";

class MirrorNodeClient {
private mirrorNodeRestUrl: string | undefined;
Expand Down Expand Up @@ -56,7 +57,7 @@ class MirrorNodeClient {
async getTokenRelationships(
rwalworth marked this conversation as resolved.
Show resolved Hide resolved
accountId: string,
tokenId: string,
): Promise<any> {
): Promise<TokenRelationshipResponse> {
const url = `${this.mirrorNodeRestUrl}/api/v1/accounts/${accountId}/tokens?token.id=${tokenId}`;
return retryOnError(async () => fetchData(url));
}
Expand Down
2 changes: 1 addition & 1 deletion src/tests/token-service/test-token-mint-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
/**
* Tests for TokenMintTransaction
*/
describe("TokenMintTransaction", function () {
describe.only("TokenMintTransaction", function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
describe.only("TokenMintTransaction", function () {
describe("TokenMintTransaction", function () {

// Tests should not take longer than 30 seconds to fully execute.
this.timeout(30000);

Expand Down
2 changes: 1 addition & 1 deletion src/utils/helpers/allowances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect } from "chai";

import mirrorNodeClient from "@services/MirrorNodeClient";

import { Allowance, Nft, NftAllowance } from "@models/mirror-node-models.ts";
import { Allowance, Nft, NftAllowance } from "@models/mirror-node-models";

export const verifyHbarAllowance = async (
ownerAccountId: string,
Expand Down
4 changes: 2 additions & 2 deletions src/utils/helpers/verify-token-tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import mirrorNodeClient from "@services/MirrorNodeClient";
import consensusInfoClient from "@services/ConsensusInfoClient";

import { TokenInfo as TokenInfoMirrorNode } from "@models/mirror-node-models.ts";
import { TokenInfo as TokenInfoMirrorNode } from "@models/mirror-node-models";

export const verifyTokenKey = async (
tokenId: string,
Expand Down Expand Up @@ -109,7 +109,7 @@ export const verifyTokenExpirationTimeUpdate = async (
(await consensusInfoClient.getTokenInfo(tokenId)).expirationTime,
);

const mirrorNodeExpirationDateNanoseconds = await (
const mirrorNodeExpirationDateNanoseconds = (
await mirrorNodeClient.getTokenData(tokenId)
).expiry_timestamp;

Expand Down
19 changes: 0 additions & 19 deletions src/utils/models/mirror-node-models.ts/Allowance.ts

This file was deleted.

181 changes: 0 additions & 181 deletions src/utils/models/mirror-node-models.ts/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */

/* eslint-disable */
/**
* Account alias in the format of 'shard.realm.alias', 'realm.alias', or 'alias'. 'alias' is the RFC4648 no-padding base32 encoded string of the account's alias.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */

/* eslint-disable */
/**
* RFC4648 no-padding base32 encoded account alias
*/
Expand Down
20 changes: 20 additions & 0 deletions src/utils/models/mirror-node-models/Allowance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { EntityId } from './EntityId';
import type { TimestampRange } from './TimestampRange';
export type Allowance = {
/**
* The amount remaining of the original amount granted.
*/
amount?: number;
/**
* The granted amount of the spender's allowance.
*/
amount_granted?: number;
owner?: EntityId;
spender?: EntityId;
timestamp?: TimestampRange;
};

Loading