Skip to content

Conversation

stalniy
Copy link
Contributor

@stalniy stalniy commented Oct 7, 2025

Why

Ref #1946 . In order to create JWT provider token for managed wallets, we need to expose this possibility via API

Summary by CodeRabbit

  • New Features

    • Provider API: POST /v1/create-jwt-token endpoint with request/response validation and OpenAPI docs.
  • Refactor

    • Switched JWT implementation to @akashnetwork/chain-sdk and standardized JwtTokenManager usage across services and proxy.
  • Tests

    • Added controller tests for token creation; updated unit and functional tests to use the new manager API.
  • Chores

    • Removed legacy jwt package and related scripts/configs, updated dependencies and TypeScript settings, and simplified pre-commit hook.

@stalniy stalniy requested a review from a team as a code owner October 7, 2025 02:30
"name": "@akashnetwork/console-api",
"version": "2.123.0",
"license": "Apache-2.0",
"dependencies": {
Copy link
Contributor

@github-actions github-actions bot Oct 7, 2025

Choose a reason for hiding this comment

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

🔄 Carefully review the package-lock.json diff

Resolve the comment if everything is ok

* node_modules/call-bind                                                                   1.0.7 -> 1.0.8
* node_modules/json-stable-stringify                                                       1.1.1 -> 1.3.0
* node_modules/long                                                                        5.3.1 -> 5.3.2
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/crypto                         0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/encoding                       0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/json-rpc                       0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/math                           0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/proto-signing                  0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/socket                         0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/stargate/node_modules/@cosmjs/amino 0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/stargate                       0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/stream                         0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/tendermint-rpc                 0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/@cosmjs/utils                          0.33.1  
+ node_modules/@akashnetwork/chain-sdk/node_modules/ws                                     7.5.10  
+ node_modules/@akashnetwork/chain-sdk                                                     1.0.0-alpha.3
+ node_modules/@bufbuild/protobuf                                                          2.9.0   
+ node_modules/@connectrpc/connect-node                                                    2.1.0   
+ node_modules/@connectrpc/connect                                                         2.1.0   

Copy link

coderabbitai bot commented Oct 7, 2025

Walkthrough

Replaces the internal packages/jwt implementation with @akashnetwork/chain-sdk (JwtTokenManager), removes the jwt package files/tests/configs, adds a provider JWT creation API (Zod schemas, controller, router, OpenAPI wiring), updates DI and tests, and removes jwt generation/staging from the pre-commit hook.

Changes

Cohort / File(s) Summary
Pre-commit hook
.husky/pre-commit
Removed jwt codegen (npm run generate -w packages/jwt) and staging (git add ./packages/jwt/src/generated) steps; other pre-commit tasks remain.
API deps
apps/api/package.json
Added @akashnetwork/chain-sdk@^1.0.0-alpha.3; removed @akashnetwork/jwt.
Provider JWT feature (API)
apps/api/src/provider/controllers/jwt-token/jwt-token.controller.ts, apps/api/src/provider/http-schemas/jwt-token.schema.ts, apps/api/src/provider/routes/jwt-token/jwt-token.router.ts, apps/api/src/provider/routes/index.ts, apps/api/src/rest-app.ts
Added Create JWT endpoint: Zod request/response schemas, controller (createJwtToken), OpenAPI router, route export, and OpenAPI wiring in rest-app.
JWT provider wiring
apps/api/src/provider/providers/jwt.provider.ts
Replaced @akashnetwork/jwt with named imports from @akashnetwork/chain-sdk and registered local jwt object (createSignArbitraryAkashWallet, JwtTokenManager) for DI.
Provider JWT service & tests
apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts, apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts, apps/api/src/provider/services/provider/provider.service.spec.ts
Migrated implementation/tests from JwtTokenJwtTokenManager; updated instantiation and calls (createTokengenerateToken), payload shape (iat, iss, jti, leases), types/mocks and expectations.
Provider-proxy deps/config
apps/provider-proxy/package.json, apps/provider-proxy/tsconfig.build.json
Replaced @akashnetwork/jwt with @akashnetwork/chain-sdk@^1.0.0-alpha.3; bumped @cosmjs/proto-signing devDependency; set compilerOptions.module to NodeNext.
Provider-proxy runtime & tests
apps/provider-proxy/src/utils/schema.ts, apps/provider-proxy/test/functional/provider-proxy-http.spec.ts, apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts
Switched to JwtTokenManager and createSignArbitraryAkashWallet from chain-sdk; updated token generation calls to generateToken and adjusted payloads in tests.
Remove jwt package (code, tests, configs)
Deleted:
packages/jwt/package.json, packages/jwt/src/index.ts, packages/jwt/src/jwt-token.ts, packages/jwt/src/jwt-validator.ts, packages/jwt/src/base64.ts, packages/jwt/src/types.ts, packages/jwt/src/wallet-utils.ts, packages/jwt/scripts/generate.ts, packages/jwt/tsconfig*.json, packages/jwt/.prettierrc.js, packages/jwt/jest.config.ts, packages/jwt/src/jwt-token.spec.ts, packages/jwt/src/jwt-validator.spec.ts, packages/jwt/src/test/*
Removed internal jwt package: public APIs, types, utilities, wallet signing helpers, generation script, tests, and config files.
Controller tests
apps/api/src/provider/controllers/jwt-token/jwt-token.controller.spec.ts
Added unit tests for JwtTokenController covering success, unauthorized, and bad-request (no wallet) scenarios.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant Router as OpenAPI Router
  participant Ctrl as JwtTokenController
  participant Auth as AuthService
  participant Repo as UserWalletRepository
  participant Svc as ProviderJwtTokenService
  participant SDK as JwtTokenManager (@chain‑sdk)

  Client->>Router: POST /v1/create-jwt-token { ttl, leases }
  Router->>Ctrl: createJwtToken(body)
  Ctrl->>Auth: getCurrentUser()
  alt no user
    Ctrl-->>Router: 401 Unauthorized
  else user present
    Ctrl->>Repo: find wallet with "sign" permission
    alt no wallet
      Ctrl-->>Router: 400 Bad Request
    else wallet found
      Ctrl->>Svc: generateJwtToken(walletId, leases, ttl)
      Svc->>SDK: generateToken(payload { iss, iat, jti, leases, ttl })
      SDK-->>Svc: token
      Svc-->>Ctrl: { token }
      Ctrl-->>Router: 201 { data: { token } }
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • baktun14

Poem

I nibbled old tokens, byte by byte,
Hopped to a chain where payloads take flight.
New routes hum soft beneath moonlight,
Scripts tucked in burrows, tests set right.
A rabbit cheers — fresh code, new light! 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly captures the primary feature introduced—exposing JWT generation for managed wallets—matching the PR objectives of providing an API endpoint for token creation without extraneous details or file names.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/api-jwt-route

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

socket-security bot commented Oct 7, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​akashnetwork/​chain-sdk@​1.0.0-alpha.37710010093100

View full report

Copy link

codecov bot commented Oct 7, 2025

❌ 4 Tests Failed:

Tests completed Failed Passed Skipped
1439 4 1435 0
View the top 1 failed test(s) by shortest run time
API Docs GET /v1/doc returns docs with all routes expected
Stack Traces | 0.174s run time
Error: expect(received).toMatchSnapshot()

Snapshot name: `API Docs GET /v1/doc returns docs with all routes expected 1`

- Snapshot  -   0
+ Received  + 238

@@ -3702,10 +3702,248 @@
          "tags": [
            "Wallet",
          ],
        },
      },
+     "/v1/create-jwt-token": {
+       "post": {
+         "requestBody": {
+           "content": {
+             "application/json": {
+               "schema": {
+                 "properties": {
+                   "data": {
+                     "properties": {
+                       "leases": {
+                         "oneOf": [
+                           {
+                             "properties": {
+                               "access": {
+                                 "enum": [
+                                   "full",
+                                 ],
+                                 "type": "string",
+                               },
+                               "scope": {
+                                 "items": {
+                                   "enum": [
+                                     "send-manifest",
+                                     "get-manifest",
+                                     "logs",
+                                     "shell",
+                                     "events",
+                                     "status",
+                                     "restart",
+                                     "hostname-migrate",
+                                     "ip-migrate",
+                                   ],
+                                   "type": "string",
+                                 },
+                                 "type": "array",
+                               },
+                             },
+                             "required": [
+                               "access",
+                             ],
+                             "type": "object",
+                           },
+                           {
+                             "properties": {
+                               "access": {
+                                 "enum": [
+                                   "granular",
+                                 ],
+                                 "type": "string",
+                               },
+                               "permissions": {
+                                 "items": {
+                                   "oneOf": [
+                                     {
+                                       "properties": {
+                                         "access": {
+                                           "enum": [
+                                             "full",
+                                           ],
+                                           "type": "string",
+                                         },
+                                         "provider": {
+                                           "type": "string",
+                                         },
+                                       },
+                                       "required": [
+                                         "provider",
+                                         "access",
+                                       ],
+                                       "type": "object",
+                                     },
+                                     {
+                                       "properties": {
+                                         "access": {
+                                           "enum": [
+                                             "scoped",
+                                           ],
+                                           "type": "string",
+                                         },
+                                         "provider": {
+                                           "type": "string",
+                                         },
+                                         "scope": {
+                                           "items": {
+                                             "enum": [
+                                               "send-manifest",
+                                               "get-manifest",
+                                               "logs",
+                                               "shell",
+                                               "events",
+                                               "status",
+                                               "restart",
+                                               "hostname-migrate",
+                                               "ip-migrate",
+                                             ],
+                                             "type": "string",
+                                           },
+                                           "type": "array",
+                                         },
+                                       },
+                                       "required": [
+                                         "provider",
+                                         "access",
+                                         "scope",
+                                       ],
+                                       "type": "object",
+                                     },
+                                     {
+                                       "properties": {
+                                         "access": {
+                                           "enum": [
+                                             "granular",
+                                           ],
+                                           "type": "string",
+                                         },
+                                         "deployments": {
+                                           "items": {
+                                             "properties": {
+                                               "dseq": {
+                                                 "type": "number",
+                                               },
+                                               "gseq": {
+                                                 "type": "number",
+                                               },
+                                               "oseq": {
+                                                 "type": "number",
+                                               },
+                                               "scope": {
+                                                 "items": {
+                                                   "enum": [
+                                                     "send-manifest",
+                                                     "get-manifest",
+                                                     "logs",
+                                                     "shell",
+                                                     "events",
+                                                     "status",
+                                                     "restart",
+                                                     "hostname-migrate",
+                                                     "ip-migrate",
+                                                   ],
+                                                   "type": "string",
+                                                 },
+                                                 "type": "array",
+                                               },
+                                               "services": {
+                                                 "items": {
+                                                   "type": "string",
+                                                 },
+                                                 "type": "array",
+                                               },
+                                             },
+                                             "required": [
+                                               "dseq",
+                                               "scope",
+                                             ],
+                                             "type": "object",
+                                           },
+                                           "type": "array",
+                                         },
+                                         "provider": {
+                                           "type": "string",
+                                         },
+                                       },
+                                       "required": [
+                                         "provider",
+                                         "access",
+                                         "deployments",
+                                       ],
+                                       "type": "object",
+                                     },
+                                   ],
+                                 },
+                                 "type": "array",
+                               },
+                             },
+                             "required": [
+                               "access",
+                               "permissions",
+                             ],
+                             "type": "object",
+                           },
+                         ],
+                       },
+                       "ttl": {
+                         "exclusiveMinimum": true,
+                         "minimum": 0,
+                         "type": "integer",
+                       },
+                     },
+                     "required": [
+                       "ttl",
+                       "leases",
+                     ],
+                     "type": "object",
+                   },
+                 },
+                 "required": [
+                   "data",
+                 ],
+                 "type": "object",
+               },
+             },
+           },
+         },
+         "responses": {
+           "201": {
+             "content": {
+               "application/json": {
+                 "schema": {
+                   "properties": {
+                     "data": {
+                       "properties": {
+                         "token": {
+                           "type": "string",
+                         },
+                       },
+                       "required": [
+                         "token",
+                       ],
+                       "type": "object",
+                     },
+                   },
+                   "required": [
+                     "data",
+                   ],
+                   "type": "object",
+                 },
+               },
+             },
+             "description": "JWT token created successfully",
+           },
+         },
+         "summary": "Create new JWT token for managed wallet",
+         "tags": [
+           "JWT Token",
+         ],
+       },
+     },
      "/v1/dashboard-data": {
        "get": {
          "responses": {
            "200": {
              "content": {
    at Object.<anonymous> (.../test/functional/docs.spec.ts:13:20)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
View the full list of 3 ❄️ flaky test(s)
Managed Wallet API Deployment Flow should execute a full deployment cycle with provider JWT auth

Flake rate in main: 100.00% (Passed 0 times, Failed 1 times)

Stack Traces | 89.2s run time
Error: expect(received).toMatchObject(expected)

Matcher error: received value must be a non-null object

Received has value: undefined
    at .../test/functional/managed-api-deployment-flow.spec.ts:60:19
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
Managed Wallet API Deployment Flow should execute a full deployment cycle with provider mTLS auth

Flake rate in main: 100.00% (Passed 0 times, Failed 1 times)

Stack Traces | 94.6s run time
Error: expect(received).toMatchObject(expected)

Matcher error: received value must be a non-null object

Received has value: undefined
    at .../test/functional/managed-api-deployment-flow.spec.ts:60:19
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
Managed Wallet API Deployment Flow should maintain read-only operations during blockchain node outages

Flake rate in main: 100.00% (Passed 0 times, Failed 1 times)

Stack Traces | 97.2s run time
Error: expect(received).toMatchObject(expected)

Matcher error: received value must be a non-null object

Received has value: undefined
    at Object.<anonymous> (.../test/functional/managed-api-deployment-flow.spec.ts:185:19)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9237fc and 06c32bf.

⛔ Files ignored due to path filters (5)
  • package-lock.json is excluded by !**/package-lock.json
  • packages/jwt/src/generated/jwt-schema-data.ts is excluded by !**/generated/**
  • packages/jwt/src/test/generated/jwt-claims-test-cases.ts is excluded by !**/generated/**
  • packages/jwt/src/test/generated/jwt-mnemonic.ts is excluded by !**/generated/**
  • packages/jwt/src/test/generated/jwt-signing-test-cases.ts is excluded by !**/generated/**
📒 Files selected for processing (31)
  • .husky/pre-commit (0 hunks)
  • apps/api/package.json (1 hunks)
  • apps/api/src/provider/controllers/jwt-token/jwt-token.controller.ts (1 hunks)
  • apps/api/src/provider/http-schemas/jwt-token.schema.ts (1 hunks)
  • apps/api/src/provider/providers/jwt.provider.ts (1 hunks)
  • apps/api/src/provider/routes/index.ts (1 hunks)
  • apps/api/src/provider/routes/jwt-token/jwt-token.router.ts (1 hunks)
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts (4 hunks)
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts (5 hunks)
  • apps/api/src/provider/services/provider/provider.service.spec.ts (1 hunks)
  • apps/api/src/rest-app.ts (2 hunks)
  • apps/provider-proxy/package.json (2 hunks)
  • apps/provider-proxy/src/utils/schema.ts (2 hunks)
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts (2 hunks)
  • apps/provider-proxy/tsconfig.build.json (1 hunks)
  • packages/jwt/.prettierrc.js (0 hunks)
  • packages/jwt/jest.config.ts (0 hunks)
  • packages/jwt/package.json (0 hunks)
  • packages/jwt/scripts/generate.ts (0 hunks)
  • packages/jwt/src/base64.ts (0 hunks)
  • packages/jwt/src/index.ts (0 hunks)
  • packages/jwt/src/jwt-token.spec.ts (0 hunks)
  • packages/jwt/src/jwt-token.ts (0 hunks)
  • packages/jwt/src/jwt-validator.spec.ts (0 hunks)
  • packages/jwt/src/jwt-validator.ts (0 hunks)
  • packages/jwt/src/test/seeders/akash-address.seeder.ts (0 hunks)
  • packages/jwt/src/test/test-utils.ts (0 hunks)
  • packages/jwt/src/types.ts (0 hunks)
  • packages/jwt/src/wallet-utils.ts (0 hunks)
  • packages/jwt/tsconfig.build.json (0 hunks)
  • packages/jwt/tsconfig.json (0 hunks)
💤 Files with no reviewable changes (17)
  • .husky/pre-commit
  • packages/jwt/src/jwt-token.ts
  • packages/jwt/src/jwt-validator.ts
  • packages/jwt/src/base64.ts
  • packages/jwt/src/index.ts
  • packages/jwt/.prettierrc.js
  • packages/jwt/src/types.ts
  • packages/jwt/package.json
  • packages/jwt/src/jwt-token.spec.ts
  • packages/jwt/tsconfig.json
  • packages/jwt/scripts/generate.ts
  • packages/jwt/src/test/test-utils.ts
  • packages/jwt/src/wallet-utils.ts
  • packages/jwt/src/jwt-validator.spec.ts
  • packages/jwt/src/test/seeders/akash-address.seeder.ts
  • packages/jwt/tsconfig.build.json
  • packages/jwt/jest.config.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

Never use type any or cast to type any. Always define the proper TypeScript types.

Files:

  • apps/api/src/provider/routes/index.ts
  • apps/api/src/provider/routes/jwt-token/jwt-token.router.ts
  • apps/api/src/provider/http-schemas/jwt-token.schema.ts
  • apps/api/src/provider/providers/jwt.provider.ts
  • apps/provider-proxy/src/utils/schema.ts
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts
  • apps/api/src/provider/controllers/jwt-token/jwt-token.controller.ts
  • apps/api/src/provider/services/provider/provider.service.spec.ts
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts
  • apps/api/src/rest-app.ts
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/api/src/provider/routes/index.ts
  • apps/api/src/provider/routes/jwt-token/jwt-token.router.ts
  • apps/api/src/provider/http-schemas/jwt-token.schema.ts
  • apps/api/src/provider/providers/jwt.provider.ts
  • apps/provider-proxy/src/utils/schema.ts
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts
  • apps/api/src/provider/controllers/jwt-token/jwt-token.controller.ts
  • apps/api/src/provider/services/provider/provider.service.spec.ts
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts
  • apps/api/src/rest-app.ts
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/api/src/provider/services/provider/provider.service.spec.ts
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: baktun14
PR: akash-network/console#1312
File: packages/jwt/src/jwt-token.ts:0-0
Timestamp: 2025-05-13T17:35:25.875Z
Learning: In the Akash JWT implementation, cryptographic signature verification is handled by the provider node code rather than in the JWT package itself. The JWT package only handles token creation, decoding, and basic validation (schema and time constraints).
🧬 Code graph analysis (4)
apps/api/src/provider/routes/jwt-token/jwt-token.router.ts (2)
apps/api/src/core/services/open-api-hono-handler/open-api-hono-handler.ts (1)
  • OpenApiHonoHandler (11-26)
apps/api/src/provider/http-schemas/jwt-token.schema.ts (2)
  • CreateJwtTokenRequestSchema (46-49)
  • CreateJwtTokenResponseSchema (53-55)
apps/api/src/provider/controllers/jwt-token/jwt-token.controller.ts (3)
apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts (1)
  • singleton (27-65)
apps/deploy-web/src/services/auth/auth/auth.service.ts (1)
  • AuthService (7-36)
apps/api/src/provider/http-schemas/jwt-token.schema.ts (2)
  • CreateJwtTokenRequest (51-51)
  • CreateJwtTokenResponse (56-56)
apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts (1)
apps/api/src/provider/providers/jwt.provider.ts (1)
  • JWTModule (10-10)
apps/api/src/rest-app.ts (1)
apps/api/src/provider/routes/jwt-token/jwt-token.router.ts (1)
  • providerJwtTokenRouter (9-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (16)
apps/provider-proxy/tsconfig.build.json (1)

6-7: LGTM! NodeNext module resolution is appropriate.

The addition of "module": "NodeNext" enables better ESM/CommonJS interop, which aligns well with the migration to @akashnetwork/chain-sdk and modern Node.js module patterns.

apps/provider-proxy/src/utils/schema.ts (3)

1-1: LGTM! Import migration is consistent with PR objectives.

The switch from @akashnetwork/jwt to @akashnetwork/chain-sdk aligns with the broader migration across the codebase.


36-36: LGTM! The {} as any cast is intentional.

Based on learnings, cryptographic signature verification is handled by the provider node code, not in the JWT package itself. The comment on lines 34-35 confirms this instance only needs validation and decoding, so the empty signer is acceptable.


84-90: Verify JwtTokenManager API compatibility in apps/provider-proxy/src/utils/schema.ts
Confirm decodeToken(token: string) returns the same payload type and validatePayload accepts that payload and returns { isValid: boolean; errors?: string[] } as in the original JwtToken implementation to avoid runtime errors.

apps/api/src/provider/services/provider/provider.service.spec.ts (1)

1-1: LGTM! Type import migration is straightforward.

The JwtTokenPayload type import path has been updated to @akashnetwork/chain-sdk consistently with the broader migration. The type usage throughout the file remains unchanged.

apps/api/src/provider/routes/index.ts (1)

10-10: LGTM! Router export follows existing patterns.

The JWT token router export is consistent with the other router exports in this module.

apps/api/src/rest-app.ts (2)

68-68: LGTM! Router import is properly added.

The providerJwtTokenRouter import is correctly placed among the other provider router imports.


144-144: LGTM! Router registration follows existing patterns.

The providerJwtTokenRouter is properly added to the openApiHonoHandlers array, ensuring it will be mounted and included in the OpenAPI documentation.

apps/api/src/provider/providers/jwt.provider.ts (2)

1-1: LGTM! Migration to named imports is clean.

The switch from default export to explicit named imports (createSignArbitraryAkashWallet and JwtTokenManager) from @akashnetwork/chain-sdk is appropriate for the new package structure.


5-8: LGTM! Object aggregation pattern works well with dependency injection.

Creating a jwt object to aggregate the imports provides a clean module interface for the DI container while maintaining flexibility to add more exports in the future.

apps/api/src/provider/routes/jwt-token/jwt-token.router.ts (1)

11-46: Authentication is correctly enforced
Global AuthInterceptor (rest-app.ts) and the assert(this.authService.currentUser, 401) in JwtTokenController.createJwtToken protect this endpoint.

apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts (5)

1-13: LGTM! Clean migration to chain-sdk.

The imports correctly reference JwtTokenManager and JwtTokenPayload from @akashnetwork/chain-sdk, and the test uses jest-mock-extended for mocking as required by the coding guidelines.


24-25: LGTM! Test expectations correctly updated.

The test properly verifies that JwtTokenManager is constructed with the wallet and that generateToken is called with the correct payload structure.


44-44: LGTM! Memoization test updated correctly.

The test verifies that JwtTokenManager is only instantiated once when called multiple times with the same parameters, confirming the memoization behavior.


68-126: LGTM! Setup function follows coding guidelines.

The setup function is properly positioned at the bottom of the describe block, creates the service under test with all necessary mocks, and returns test fixtures without using shared state. The structure adheres to all specified coding guidelines.


86-92: Mocks correctly reflect @akashnetwork/chain-sdk exports. No changes required.

"dependencies": {
"@akashnetwork/akash-api": "^1.3.0",
"@akashnetwork/akashjs": "^0.11.1",
"@akashnetwork/chain-sdk": "^1.0.0-alpha.3",
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Pin the alpha version more strictly.

Using ^1.0.0-alpha.3 allows npm to install any version >= 1.0.0-alpha.3 and < 2.0.0, including future alpha releases that may introduce breaking changes. For pre-release versions, use exact pinning or tilde (~) to limit updates to patch-level changes only.

Apply this diff to pin the version more strictly:

-    "@akashnetwork/chain-sdk": "^1.0.0-alpha.3",
+    "@akashnetwork/chain-sdk": "1.0.0-alpha.3",

Alternatively, if you want to allow patch-level updates:

-    "@akashnetwork/chain-sdk": "^1.0.0-alpha.3",
+    "@akashnetwork/chain-sdk": "~1.0.0-alpha.3",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"@akashnetwork/chain-sdk": "^1.0.0-alpha.3",
"@akashnetwork/chain-sdk": "1.0.0-alpha.3",
Suggested change
"@akashnetwork/chain-sdk": "^1.0.0-alpha.3",
"@akashnetwork/chain-sdk": "~1.0.0-alpha.3",
🤖 Prompt for AI Agents
In apps/api/package.json at line 42, the dependency is currently
"^1.0.0-alpha.3" which allows unintended pre-release upgrades; remove the caret
to pin exactly ("1.0.0-alpha.3") or, if you want to allow only patch-level
pre-release updates, replace the caret with a tilde ("~1.0.0-alpha.3"); update
the version string accordingly and run npm install / yarn to update lockfile.

@stalniy stalniy force-pushed the feat/api-jwt-route branch 2 times, most recently from e72f1bb to 05b9a4b Compare October 7, 2025 02:44
@stalniy stalniy force-pushed the feat/api-jwt-route branch from 05b9a4b to 5e362fd Compare October 7, 2025 02:59
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 05b9a4b and 5e362fd.

⛔ Files ignored due to path filters (5)
  • package-lock.json is excluded by !**/package-lock.json
  • packages/jwt/src/generated/jwt-schema-data.ts is excluded by !**/generated/**
  • packages/jwt/src/test/generated/jwt-claims-test-cases.ts is excluded by !**/generated/**
  • packages/jwt/src/test/generated/jwt-mnemonic.ts is excluded by !**/generated/**
  • packages/jwt/src/test/generated/jwt-signing-test-cases.ts is excluded by !**/generated/**
📒 Files selected for processing (33)
  • .husky/pre-commit (0 hunks)
  • apps/api/package.json (1 hunks)
  • apps/api/src/provider/controllers/jwt-token/jwt-token.controller.spec.ts (1 hunks)
  • apps/api/src/provider/controllers/jwt-token/jwt-token.controller.ts (1 hunks)
  • apps/api/src/provider/http-schemas/jwt-token.schema.ts (1 hunks)
  • apps/api/src/provider/providers/jwt.provider.ts (1 hunks)
  • apps/api/src/provider/routes/index.ts (1 hunks)
  • apps/api/src/provider/routes/jwt-token/jwt-token.router.ts (1 hunks)
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts (4 hunks)
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts (5 hunks)
  • apps/api/src/provider/services/provider/provider.service.spec.ts (1 hunks)
  • apps/api/src/rest-app.ts (2 hunks)
  • apps/provider-proxy/package.json (2 hunks)
  • apps/provider-proxy/src/utils/schema.ts (2 hunks)
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts (2 hunks)
  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts (2 hunks)
  • apps/provider-proxy/tsconfig.build.json (1 hunks)
  • packages/jwt/.prettierrc.js (0 hunks)
  • packages/jwt/jest.config.ts (0 hunks)
  • packages/jwt/package.json (0 hunks)
  • packages/jwt/scripts/generate.ts (0 hunks)
  • packages/jwt/src/base64.ts (0 hunks)
  • packages/jwt/src/index.ts (0 hunks)
  • packages/jwt/src/jwt-token.spec.ts (0 hunks)
  • packages/jwt/src/jwt-token.ts (0 hunks)
  • packages/jwt/src/jwt-validator.spec.ts (0 hunks)
  • packages/jwt/src/jwt-validator.ts (0 hunks)
  • packages/jwt/src/test/seeders/akash-address.seeder.ts (0 hunks)
  • packages/jwt/src/test/test-utils.ts (0 hunks)
  • packages/jwt/src/types.ts (0 hunks)
  • packages/jwt/src/wallet-utils.ts (0 hunks)
  • packages/jwt/tsconfig.build.json (0 hunks)
  • packages/jwt/tsconfig.json (0 hunks)
💤 Files with no reviewable changes (17)
  • packages/jwt/src/jwt-token.spec.ts
  • packages/jwt/tsconfig.build.json
  • packages/jwt/src/test/test-utils.ts
  • packages/jwt/src/types.ts
  • packages/jwt/src/jwt-validator.spec.ts
  • packages/jwt/src/base64.ts
  • packages/jwt/src/test/seeders/akash-address.seeder.ts
  • packages/jwt/scripts/generate.ts
  • packages/jwt/src/index.ts
  • packages/jwt/src/jwt-validator.ts
  • packages/jwt/src/jwt-token.ts
  • .husky/pre-commit
  • packages/jwt/src/wallet-utils.ts
  • packages/jwt/tsconfig.json
  • packages/jwt/jest.config.ts
  • packages/jwt/.prettierrc.js
  • packages/jwt/package.json
🚧 Files skipped from review as they are similar to previous changes (6)
  • apps/api/package.json
  • apps/provider-proxy/src/utils/schema.ts
  • apps/api/src/provider/services/provider/provider.service.spec.ts
  • apps/api/src/provider/routes/index.ts
  • apps/api/src/provider/routes/jwt-token/jwt-token.router.ts
  • apps/provider-proxy/test/functional/provider-proxy-ws.spec.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)

Don't use jest.mock() to mock dependencies in test files. Instead, use jest-mock-extended to create mocks and pass mocks as dependencies to the service under test.

**/*.spec.{ts,tsx}: Use setup function instead of beforeEach in test files
setup function must be at the bottom of the root describe block in test files
setup function creates an object under test and returns it
setup function should accept a single parameter with inline type definition
Don't use shared state in setup function
Don't specify return type of setup function

Files:

  • apps/api/src/provider/controllers/jwt-token/jwt-token.controller.spec.ts
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

Never use type any or cast to type any. Always define the proper TypeScript types.

Files:

  • apps/api/src/provider/controllers/jwt-token/jwt-token.controller.spec.ts
  • apps/api/src/provider/providers/jwt.provider.ts
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts
  • apps/api/src/rest-app.ts
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts
  • apps/api/src/provider/controllers/jwt-token/jwt-token.controller.ts
  • apps/api/src/provider/http-schemas/jwt-token.schema.ts
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/general.mdc)

**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code

Files:

  • apps/api/src/provider/controllers/jwt-token/jwt-token.controller.spec.ts
  • apps/api/src/provider/providers/jwt.provider.ts
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts
  • apps/api/src/rest-app.ts
  • apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts
  • apps/api/src/provider/controllers/jwt-token/jwt-token.controller.ts
  • apps/api/src/provider/http-schemas/jwt-token.schema.ts
  • apps/provider-proxy/test/functional/provider-proxy-http.spec.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: baktun14
PR: akash-network/console#1312
File: packages/jwt/src/jwt-token.ts:0-0
Timestamp: 2025-05-13T17:35:25.875Z
Learning: In the Akash JWT implementation, cryptographic signature verification is handled by the provider node code rather than in the JWT package itself. The JWT package only handles token creation, decoding, and basic validation (schema and time constraints).
🧬 Code graph analysis (4)
apps/api/src/provider/controllers/jwt-token/jwt-token.controller.spec.ts (3)
apps/api/test/seeders/user.seeder.ts (1)
  • UserSeeder (5-45)
apps/api/test/seeders/user-wallet.seeder.ts (1)
  • UserWalletSeeder (6-29)
apps/api/src/provider/http-schemas/jwt-token.schema.ts (1)
  • CreateJwtTokenRequest (51-51)
apps/api/src/rest-app.ts (1)
apps/api/src/provider/routes/jwt-token/jwt-token.router.ts (1)
  • providerJwtTokenRouter (9-9)
apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts (1)
apps/api/src/provider/providers/jwt.provider.ts (1)
  • JWTModule (10-10)
apps/api/src/provider/controllers/jwt-token/jwt-token.controller.ts (2)
apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts (1)
  • singleton (27-65)
apps/api/src/provider/http-schemas/jwt-token.schema.ts (2)
  • CreateJwtTokenRequest (51-51)
  • CreateJwtTokenResponse (56-56)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: validate / validate-app
  • GitHub Check: test-build
  • GitHub Check: test-build
  • GitHub Check: Validate local packages
🔇 Additional comments (6)
apps/api/src/provider/providers/jwt.provider.ts (3)

5-8: LGTM!

The wrapper object pattern is appropriate for dependency injection scenarios. It provides a single registration point and makes testing easier by allowing the entire module to be mocked as a single unit.


1-1: Confirm alpha release usage of @akashnetwork/chain-sdk
Dependencies reference @akashnetwork/chain-sdk@^1.0.0-alpha.3 (alpha); ensure this is intentional and acceptable for production or upgrade to a stable release if available.


10-15: Verify all consumers have been updated to the new API.
DI setup is correct; manually confirm that every injection of JWT_MODULE now calls JwtTokenManager.generateToken() and no code still uses JwtToken.createToken().

apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts (3)

1-1: LGTM!

The import correctly references the new SDK types for JWT token management.


24-34: LGTM!

The test assertions and mock setup have been correctly updated to use JwtTokenManager and generateToken instead of the previous JwtToken and createToken. The payload structure includes all required JWT claims (exp, nbf, iat, iss, jti) plus the custom leases field, which aligns with standard JWT practices.

Also applies to: 86-92


44-44: LGTM!

The memoization test correctly verifies that the JwtTokenManager instance is reused across multiple token generation calls.

Comment on lines +37 to +54
it("throws 401 when user is not authenticated", async () => {
const { controller, authService } = setup();

authService.currentUser = undefined as any;

await expect(controller.createJwtToken(createPayload())).rejects.toThrow("Unauthorized");
});

it("throws 400 when user has no wallet", async () => {
const user = UserSeeder.create();
const { controller, authService, userWalletRepository } = setup({ user });

authService.currentUser = user;
userWalletRepository.accessibleBy.mockReturnThis();
userWalletRepository.findOneByUserId.mockResolvedValue(undefined);

await expect(controller.createJwtToken(createPayload())).rejects.toThrow("User does not have a wallet");
});
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Drop the as any cast in favor of typed setup wiring

Casting to any at Line 40 violates our TypeScript guideline (“Never use type any or cast to type any”). You can avoid the cast altogether by letting setup() initialize authService.currentUser when a user is provided, and then remove both the manual assignment in the happy-path test and the undefined as any line here; setup() without a user will already leave currentUser undefined. For example:

-      const user = UserSeeder.create();
-      const { controller, authService, userWalletRepository, providerJwtTokenService, jwtToken, wallet } = setup({ user });
-
-      authService.currentUser = user;
+      const user = UserSeeder.create();
+      const { controller, authService, userWalletRepository, providerJwtTokenService, jwtToken, wallet } = setup({ user });-      const { controller, authService } = setup();
-
-      authService.currentUser = undefined as any;
+      const { controller, authService } = setup();
…
   function setup(input?: { user?: UserOutput }) {
     const authService = mock<AuthService>();
+    if (input?.user) {
+      authService.currentUser = input.user;
+    }

That keeps the tests readable and compliant with the repo rules. As per coding guidelines.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/api/src/provider/controllers/jwt-token/jwt-token.controller.spec.ts
around lines 37 to 54, the test uses an `undefined as any` cast to
force-authService.currentUser to undefined; remove the `as any` cast and instead
update the `setup()` helper to accept an optional `user` parameter and
initialize `authService.currentUser` accordingly (undefined when no user
passed). Then change the unauthenticated test to call `setup()` with no user and
remove the manual `authService.currentUser` assignment, and in the
wallet-missing test call `setup({ user })` and remove the redundant
`authService.currentUser = user` assignment; ensure `setup()` returns correctly
typed authService so tests compile without any `any` casts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants