feat: expose jwt generation for managed wallets#2019
Conversation
| @@ -40,6 +40,7 @@ | |||
| "dependencies": { | |||
There was a problem hiding this comment.
🔄 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
WalkthroughReplaces the internal packages/jwt implementation with @akashnetwork/chain-sdk, 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2019 +/- ##
==========================================
+ Coverage 45.95% 46.01% +0.06%
==========================================
Files 1014 1017 +3
Lines 28633 28673 +40
Branches 7513 7486 -27
==========================================
+ Hits 13158 13195 +37
+ Misses 15192 15095 -97
- Partials 283 383 +100
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (5)
package-lock.jsonis excluded by!**/package-lock.jsonpackages/jwt/src/generated/jwt-schema-data.tsis excluded by!**/generated/**packages/jwt/src/test/generated/jwt-claims-test-cases.tsis excluded by!**/generated/**packages/jwt/src/test/generated/jwt-mnemonic.tsis excluded by!**/generated/**packages/jwt/src/test/generated/jwt-signing-test-cases.tsis 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.tsapps/api/src/provider/routes/jwt-token/jwt-token.router.tsapps/api/src/provider/http-schemas/jwt-token.schema.tsapps/api/src/provider/providers/jwt.provider.tsapps/provider-proxy/src/utils/schema.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.tsapps/api/src/provider/controllers/jwt-token/jwt-token.controller.tsapps/api/src/provider/services/provider/provider.service.spec.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.tsapps/api/src/rest-app.tsapps/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.tsapps/api/src/provider/routes/jwt-token/jwt-token.router.tsapps/api/src/provider/http-schemas/jwt-token.schema.tsapps/api/src/provider/providers/jwt.provider.tsapps/provider-proxy/src/utils/schema.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.tsapps/api/src/provider/controllers/jwt-token/jwt-token.controller.tsapps/api/src/provider/services/provider/provider.service.spec.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.tsapps/api/src/rest-app.tsapps/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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under test.
**/*.spec.{ts,tsx}: Usesetupfunction instead ofbeforeEachin test files
setupfunction must be at the bottom of the rootdescribeblock in test files
setupfunction creates an object under test and returns it
setupfunction should accept a single parameter with inline type definition
Don't use shared state insetupfunction
Don't specify return type ofsetupfunction
Files:
apps/api/src/provider/services/provider/provider.service.spec.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.tsapps/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-sdkand 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/jwtto@akashnetwork/chain-sdkaligns with the broader migration across the codebase.
36-36: LGTM! The{} as anycast 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
ConfirmdecodeToken(token: string)returns the same payload type andvalidatePayloadaccepts that payload and returns{ isValid: boolean; errors?: string[] }as in the originalJwtTokenimplementation to avoid runtime errors.apps/api/src/provider/services/provider/provider.service.spec.ts (1)
1-1: LGTM! Type import migration is straightforward.The
JwtTokenPayloadtype import path has been updated to@akashnetwork/chain-sdkconsistently 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
providerJwtTokenRouterimport is correctly placed among the other provider router imports.
144-144: LGTM! Router registration follows existing patterns.The
providerJwtTokenRouteris properly added to theopenApiHonoHandlersarray, 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 (
createSignArbitraryAkashWalletandJwtTokenManager) from@akashnetwork/chain-sdkis appropriate for the new package structure.
5-8: LGTM! Object aggregation pattern works well with dependency injection.Creating a
jwtobject 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
GlobalAuthInterceptor(rest-app.ts) and theassert(this.authService.currentUser, 401)inJwtTokenController.createJwtTokenprotect 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
JwtTokenManagerandJwtTokenPayloadfrom@akashnetwork/chain-sdk, and the test usesjest-mock-extendedfor mocking as required by the coding guidelines.
24-25: LGTM! Test expectations correctly updated.The test properly verifies that
JwtTokenManageris constructed with the wallet and thatgenerateTokenis called with the correct payload structure.
44-44: LGTM! Memoization test updated correctly.The test verifies that
JwtTokenManageris only instantiated once when called multiple times with the same parameters, confirming the memoization behavior.
68-126: LGTM! Setup function follows coding guidelines.The
setupfunction is properly positioned at the bottom of thedescribeblock, 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-sdkexports. No changes required.
| "dependencies": { | ||
| "@akashnetwork/akash-api": "^1.3.0", | ||
| "@akashnetwork/akashjs": "^0.11.1", | ||
| "@akashnetwork/chain-sdk": "^1.0.0-alpha.3", |
There was a problem hiding this comment.
🛠️ 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.
| "@akashnetwork/chain-sdk": "^1.0.0-alpha.3", | |
| "@akashnetwork/chain-sdk": "1.0.0-alpha.3", |
| "@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.
05b9a4b to
5e362fd
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (5)
package-lock.jsonis excluded by!**/package-lock.jsonpackages/jwt/src/generated/jwt-schema-data.tsis excluded by!**/generated/**packages/jwt/src/test/generated/jwt-claims-test-cases.tsis excluded by!**/generated/**packages/jwt/src/test/generated/jwt-mnemonic.tsis excluded by!**/generated/**packages/jwt/src/test/generated/jwt-signing-test-cases.tsis 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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under test.
**/*.spec.{ts,tsx}: Usesetupfunction instead ofbeforeEachin test files
setupfunction must be at the bottom of the rootdescribeblock in test files
setupfunction creates an object under test and returns it
setupfunction should accept a single parameter with inline type definition
Don't use shared state insetupfunction
Don't specify return type ofsetupfunction
Files:
apps/api/src/provider/controllers/jwt-token/jwt-token.controller.spec.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.tsapps/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.tsapps/api/src/provider/providers/jwt.provider.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.tsapps/api/src/rest-app.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.tsapps/api/src/provider/controllers/jwt-token/jwt-token.controller.tsapps/api/src/provider/http-schemas/jwt-token.schema.tsapps/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.tsapps/api/src/provider/providers/jwt.provider.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.tsapps/api/src/rest-app.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.tsapps/api/src/provider/controllers/jwt-token/jwt-token.controller.tsapps/api/src/provider/http-schemas/jwt-token.schema.tsapps/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 ofJWT_MODULEnow callsJwtTokenManager.generateToken()and no code still usesJwtToken.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
JwtTokenManagerandgenerateTokeninstead of the previousJwtTokenandcreateToken. 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
JwtTokenManagerinstance is reused across multiple token generation calls.
| 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"); | ||
| }); |
There was a problem hiding this comment.
🛠️ 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.
5e362fd to
4558b9e
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (6)
apps/api/test/functional/__snapshots__/docs.spec.ts.snapis excluded by!**/*.snappackage-lock.jsonis excluded by!**/package-lock.jsonpackages/jwt/src/generated/jwt-schema-data.tsis excluded by!**/generated/**packages/jwt/src/test/generated/jwt-claims-test-cases.tsis excluded by!**/generated/**packages/jwt/src/test/generated/jwt-mnemonic.tsis excluded by!**/generated/**packages/jwt/src/test/generated/jwt-signing-test-cases.tsis 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)
- .husky/pre-commit
- packages/jwt/src/jwt-validator.spec.ts
- packages/jwt/src/test/test-utils.ts
- packages/jwt/src/base64.ts
- packages/jwt/src/jwt-token.ts
- packages/jwt/src/test/seeders/akash-address.seeder.ts
- packages/jwt/package.json
- packages/jwt/.prettierrc.js
- packages/jwt/src/types.ts
- packages/jwt/src/jwt-token.spec.ts
- packages/jwt/src/jwt-validator.ts
- packages/jwt/jest.config.ts
- packages/jwt/src/index.ts
- packages/jwt/tsconfig.json
- packages/jwt/scripts/generate.ts
- packages/jwt/src/wallet-utils.ts
- packages/jwt/tsconfig.build.json
🚧 Files skipped from review as they are similar to previous changes (9)
- apps/api/src/provider/routes/index.ts
- apps/provider-proxy/package.json
- apps/api/package.json
- apps/api/src/provider/controllers/jwt-token/jwt-token.controller.spec.ts
- apps/api/src/provider/http-schemas/jwt-token.schema.ts
- apps/api/src/provider/services/provider/provider.service.spec.ts
- apps/provider-proxy/src/utils/schema.ts
- apps/provider-proxy/tsconfig.build.json
- apps/api/src/rest-app.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, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under test.
**/*.spec.{ts,tsx}: Usesetupfunction instead ofbeforeEachin test files
setupfunction must be at the bottom of the rootdescribeblock in test files
setupfunction creates an object under test and returns it
setupfunction should accept a single parameter with inline type definition
Don't use shared state insetupfunction
Don't specify return type ofsetupfunction
Files:
apps/provider-proxy/test/functional/provider-proxy-ws.spec.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.tsapps/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/provider-proxy/test/functional/provider-proxy-ws.spec.tsapps/api/src/provider/controllers/jwt-token/jwt-token.controller.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.tsapps/provider-proxy/test/functional/provider-proxy-http.spec.tsapps/api/src/provider/providers/jwt.provider.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.tsapps/api/src/provider/routes/jwt-token/jwt-token.router.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/provider-proxy/test/functional/provider-proxy-ws.spec.tsapps/api/src/provider/controllers/jwt-token/jwt-token.controller.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.tsapps/provider-proxy/test/functional/provider-proxy-http.spec.tsapps/api/src/provider/providers/jwt.provider.tsapps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.tsapps/api/src/provider/routes/jwt-token/jwt-token.router.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 (3)
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)
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/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)
⏰ 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). (14)
- GitHub Check: validate / validate-app
- GitHub Check: validate / validate-app
- GitHub Check: test-build
- GitHub Check: validate / validate-app
- GitHub Check: validate / validate-app
- 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: test-build
- GitHub Check: Validate local packages
🔇 Additional comments (7)
apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts (4)
1-1: LGTM: Import migration to chain-sdk.The import has been correctly updated to use
JwtTokenManagerandJwtTokenPayloadfrom@akashnetwork/chain-sdk, replacing the previous@akashnetwork/jwtpackage.
25-25: Complex type extraction for AccessScope.The nested
Extracttypes are complex but provide type-safe extraction of the granular scope structure fromJwtTokenPayload["leases"]. This ensures compile-time type safety when working with scoped permissions.
35-48: LGTM: Token generation migrated correctly.The method has been properly updated to use
JwtTokenManager.generateToken()and now includes standard JWT claims (iat,iss,jti) alongside the customleasesfield, following JWT best practices.
59-64: LGTM: Helper method for granular leases.The method correctly constructs a granular lease structure with proper typing, providing a convenient way to create scoped permissions for providers.
apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.spec.ts (3)
1-1: LGTM: Test imports updated for chain-sdk migration.The import has been correctly updated to use
JwtTokenManagerfrom@akashnetwork/chain-sdk, aligning with the service file changes.
24-34: LGTM: Test expectations updated correctly.The test expectations have been properly updated to verify
JwtTokenManagerinstantiation andgenerateTokenmethod calls, including validation of the expanded JWT payload with standard claims (iat,iss,jti).
68-126: LGTM: Setup function follows coding guidelines.The setup function is properly structured and follows all coding guidelines:
- Positioned at the bottom of the describe block
- Uses
jest-mock-extendedfor mocks instead ofjest.mock()- No explicit return type specified
- No shared state between tests
- Mocks are correctly configured for
JwtTokenManagerandgenerateTokenAs per coding guidelines.
| const wallet = this.walletFactory(this.billingConfigService.get("MASTER_WALLET_MNEMONIC"), walletId); | ||
| const akashWallet = await this.jwtModule.createSignArbitraryAkashWallet(await wallet.getInstance(), walletId); | ||
| const jwtToken = new this.jwtModule.JwtToken(akashWallet); | ||
| const akashWallet = await this.jwtModule.createSignArbitraryAkashWallet((await wallet.getInstance()) as any, walletId); |
There was a problem hiding this comment.
Remove unsafe as any cast.
The as any cast violates the coding guidelines and bypasses TypeScript's type safety. Define the proper type for the wallet instance or update the type signature of createSignArbitraryAkashWallet to accept the actual return type of wallet.getInstance().
As per coding guidelines: "Never use type any or cast to type any. Always define the proper TypeScript types."
Apply this approach to fix the type safety:
- const akashWallet = await this.jwtModule.createSignArbitraryAkashWallet((await wallet.getInstance()) as any, walletId);
+ const walletInstance = await wallet.getInstance();
+ const akashWallet = await this.jwtModule.createSignArbitraryAkashWallet(walletInstance, walletId);Then ensure createSignArbitraryAkashWallet has the correct type signature to accept DirectSecp256k1HdWallet or the appropriate wallet type.
📝 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.
| const akashWallet = await this.jwtModule.createSignArbitraryAkashWallet((await wallet.getInstance()) as any, walletId); | |
| // before: | |
| - const akashWallet = await this.jwtModule.createSignArbitraryAkashWallet((await wallet.getInstance()) as any, walletId); | |
| // after: | |
| const walletInstance = await wallet.getInstance(); | |
| const akashWallet = await this.jwtModule.createSignArbitraryAkashWallet(walletInstance, walletId); |
🤖 Prompt for AI Agents
In
apps/api/src/provider/services/provider-jwt-token/provider-jwt-token.service.ts
around line 53, remove the unsafe `as any` cast on the result of
`wallet.getInstance()` by giving `wallet.getInstance()` a concrete return type
(e.g., DirectSecp256k1HdWallet or the actual wallet interface) and updating the
signature of `createSignArbitraryAkashWallet` in jwtModule to accept that exact
type; replace the cast with the properly typed value, import or declare the
wallet type where needed, and run TypeScript compilation to ensure no further
mismatches.
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
Refactor
Tests
Chores