feat: tc layer#155
Conversation
📝 WalkthroughWalkthroughThe pull request performs a large-scale service layer decomposition, splitting The wallet system is overhauled:
Across the codebase, imports are consolidated to use lighter module entry points: BigNumber utilities now import from 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Comment |
* feat: turnkey deterministic autosign (IFE-136) * refactor: minor
Reverts ea6748c so the wallet state isolation work can live on chore/performance-lighthouse-research.
* feat: tc layer service barrel import optimisation * fix: ai review
* fix: cosmos wallet broadcast issue * chore: update test file * refactor: minor
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
app/store/wallet/index.ts (1)
853-906:⚠️ Potential issue | 🟠 Major | ⚡ Quick winRead-only guard is bypassable through direct helper actions.
Line 853 and Line 911 allow direct calls to broadcast helpers without the read-only / wallet-connected checks added in Line 716 and Line 767. That allows callers to bypass the “read-only cannot sign” invariant by invoking helpers directly.
Suggested patch
async broadcastWithoutFeeDelegation( broadcastOptions: MsgBroadcasterTxOptions ) { const walletStore = useSharedWalletStore() + + if (walletStore.isReadOnly) { + throw new GeneralException( + new Error( + 'Read-only connection cannot sign or submit transactions. Connect a wallet to continue.' + ) + ) + } + + if (!walletStore.isUserConnected) { + throw new GeneralException(new Error('Wallet is not connected')) + } if (walletStore.isFeeDelegationEnabled) { throw new GeneralException( new Error( 'Broadcasting is not available for fee delegation, use broadcastWithFeeDelegation instead' @@ async broadcastWithFeeDelegation( broadcastOptions: MsgBroadcasterTxOptions ) { const walletStore = useSharedWalletStore() + + if (walletStore.isReadOnly) { + throw new GeneralException( + new Error( + 'Read-only connection cannot sign or submit transactions. Connect a wallet to continue.' + ) + ) + } + + if (!walletStore.isUserConnected) { + throw new GeneralException(new Error('Wallet is not connected')) + } if (!walletStore.isFeeDelegationEnabled) { throw new GeneralException( new Error( 'Broadcasting is not available for fee delegation, use broadcastWithoutFeeDelegation instead'Also applies to: 908-963
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/store/wallet/index.ts` around lines 853 - 906, The broadcastWithoutFeeDelegation method (and the related broadcastWithFeeDelegation method) are missing the read-only and wallet-connected validation checks that exist elsewhere in the module, allowing callers to bypass the read-only invariant by calling these methods directly. Add the same read-only guard checks from the existing validation locations (referenced at lines 716 and 767) to the beginning of both broadcastWithoutFeeDelegation and broadcastWithFeeDelegation methods before any broadcast logic is executed. These checks should throw an appropriate exception if the wallet is in read-only mode or not properly connected, ensuring the invariant cannot be bypassed through direct helper method invocation.app/wallet/strategy.ts (1)
172-193:⚠️ Potential issue | 🟠 Major | ⚡ Quick winOptions parameter ignored on subsequent calls due to caching.
The
optionsparameter is only used when creating the broadcaster on the first call. Subsequent calls return the cached promise, ignoring any newoptionspassed:getAutoSignMsgBroadcaster({ gasBufferCoefficient: 1.5 }) // creates instance with 1.5 getAutoSignMsgBroadcaster({ gasBufferCoefficient: 2.0 }) // returns cached instance with 1.5!If callers are expected to always pass the same options (or none), document this constraint. If different options need to be supported, either:
- Remove the options parameter and hardcode the configuration
- Create a new instance when options differ
- Add a separate factory that doesn't cache
Option 1: Remove the misleading parameter
-export const getAutoSignMsgBroadcaster = ( - options?: Partial<MsgBroadcasterOptions> -): Promise<MsgBroadcaster> => { +export const getAutoSignMsgBroadcaster = (): Promise<MsgBroadcaster> => { if (!autoSignMsgBroadcasterPromise) { autoSignMsgBroadcasterPromise = Promise.all([ import('`@injectivelabs/wallet-core`'), getAutoSignWalletStrategy() ]).then(([{ MsgBroadcaster }, walletStrategy]) => { return new MsgBroadcaster({ simulateTx: true, network: NETWORK, endpoints: ENDPOINTS, gasBufferCoefficient: 1.2, feePayerPubKey: FEE_PAYER_PUB_KEY, - walletStrategy, - ...options + walletStrategy }) }) } return autoSignMsgBroadcasterPromise }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/wallet/strategy.ts` around lines 172 - 193, The getAutoSignMsgBroadcaster function accepts an options parameter that is ignored on subsequent calls due to caching, creating a misleading API contract. Remove the options parameter from the function signature and the spread operator that applies it in the MsgBroadcaster instantiation, then hardcode all configuration values directly (including gasBufferCoefficient set to 1.2) so the function's behavior matches what callers would actually experience.
🧹 Nitpick comments (2)
app/wallet/utils/evm.ts (1)
189-207: 💤 Low valueReturn value doesn't distinguish success from skip.
The function returns
truein all cases: when the wallet isn't an EVM browser wallet (line 193), when strategy/provider is missing (line 201), and after successfully callingaddEvmNetwork(line 206). Callers cannot distinguish between "network was added" vs "skipped because not applicable".If this is intentional (callers don't need to differentiate), consider using
voidreturn type for clarity. If callers need to know whether the network switch actually occurred, consider returningfalseor a more descriptive result for the skip cases.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/wallet/utils/evm.ts` around lines 189 - 207, The switchToInjectiveEvmNetwork function returns true in all cases: when the wallet is not an EVM browser wallet, when the strategy or provider is missing, and after successfully calling addEvmNetwork, making it impossible for callers to distinguish between an actual network switch and a skipped operation. Either change the return type to void if callers do not need to differentiate between success and skip cases, or return false for the skip cases (the early returns when isEvmBrowserWallet check fails and when strategy or provider is missing) while keeping true for the successful execution path after addEvmNetwork is called..coderabbit.yaml (1)
36-40: ⚡ Quick winInclude
DO NOT MERGEin ignored title keywords.Given auto-review is enabled for drafts/all branches, adding
DO NOT MERGEto Line 36-40 prevents noisy reviews on intentionally blocked PRs.Proposed fix
ignore_title_keywords: - 'WIP' - 'DO NOT REVIEW' + - 'DO NOT MERGE' - '[skip-coderabbit]' - '[skip ci]'🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.coderabbit.yaml around lines 36 - 40, The ignore_title_keywords list in the .coderabbit.yaml configuration is missing the 'DO NOT MERGE' keyword. Add 'DO NOT MERGE' as a new entry to the ignore_title_keywords list alongside the existing keywords 'WIP', 'DO NOT REVIEW', '[skip-coderabbit]', and '[skip ci]' to prevent CodeRabbit from reviewing PRs that are intentionally blocked from merging.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/plugins/tracking.client.ts`:
- Around line 36-44: The async callback passed to scheduleGtagInstall lacks
error handling for potential failures during the dynamic import of vue-gtag or
the plugin initialization. Wrap the entire async function body (including both
the import('vue-gtag') call and the nuxtApp.vueApp.use() call) in a try/catch
block to handle any promise rejections gracefully and prevent unhandled errors
from affecting application stability.
In `@app/service/app/tokenPrice.ts`:
- Around line 45-56: The buildAssetPriceDenomsLeanQuery function excludes the
denom field from its query string, but consuming code relies on falling back to
the denom value when coingecko_id is undefined. Add denom to the fields
parameter in both return statements of buildAssetPriceDenomsLeanQuery by
appending it to the existing comma-separated fields list (alongside price.price,
price.market_cap, coingecko_id, and symbol) so that the API response includes
the denom field and the fallback logic can work correctly.
In `@app/service/nameCompat.ts`:
- Around line 8-25: The lazy-import caching in getInjNameService and
getInjBonfidaNameService functions stores rejected promises permanently when the
import fails. Add error handling with a catch block to both import chains that
resets the respective cache variable (injNameServicePromise and
injBonfidaNameServicePromise) back to null/undefined when an error occurs, then
re-throws the error. This ensures that if a transient import failure happens,
the next call to these functions will attempt to re-import the module instead of
returning the cached rejected promise.
In `@app/store/token.ts`:
- Around line 22-24: The tokenUsdPriceMap is being completely replaced at lines
172, 182, and 193 when filtered denoms are fetched, which overwrites previously
cached prices including the seeded USDC denom. Instead of assigning the fetched
prices directly to tokenUsdPriceMap, merge the new prices into the existing map
by using spread syntax or Object.assign to preserve previously cached values
while adding the newly fetched prices.
In `@app/store/wallet/index.spec.ts`:
- Around line 32-37: The mock path in the vi.mock call at the beginning of the
test file is using `../../service`, but the actual code in
app/store/wallet/index.ts imports web3GatewayService from `../../service/web3`.
Update the mock path in the vi.mock function to match the actual import path by
changing `../../service` to `../../service/web3`, ensuring the mock properly
intercepts the web3GatewayService dependency and its healthCheck method.
In `@scripts/gen-bff-types.ts`:
- Around line 77-83: The fetchOpenApiSpec function makes a fetch call without
any timeout, which can cause the generation job to hang indefinitely if the
network stalls. Add an AbortController instance and set a timeout (e.g., 15
seconds) that will abort the request if it exceeds the time limit. Pass the
abort signal from the controller in the fetch options headers, and ensure the
fetch call properly handles any abort errors that may be thrown.
- Around line 36-43: The validation check on line 36 uses the `in` operator
which checks both own and inherited properties of the BFF_OPENAPI_URLS object,
allowing inherited keys like toString or constructor to incorrectly pass
validation. Replace the condition `!(target in BFF_OPENAPI_URLS)` with
`!Object.hasOwn(BFF_OPENAPI_URLS, target)` to ensure only the explicitly
declared targets are accepted.
---
Outside diff comments:
In `@app/store/wallet/index.ts`:
- Around line 853-906: The broadcastWithoutFeeDelegation method (and the related
broadcastWithFeeDelegation method) are missing the read-only and
wallet-connected validation checks that exist elsewhere in the module, allowing
callers to bypass the read-only invariant by calling these methods directly. Add
the same read-only guard checks from the existing validation locations
(referenced at lines 716 and 767) to the beginning of both
broadcastWithoutFeeDelegation and broadcastWithFeeDelegation methods before any
broadcast logic is executed. These checks should throw an appropriate exception
if the wallet is in read-only mode or not properly connected, ensuring the
invariant cannot be bypassed through direct helper method invocation.
In `@app/wallet/strategy.ts`:
- Around line 172-193: The getAutoSignMsgBroadcaster function accepts an options
parameter that is ignored on subsequent calls due to caching, creating a
misleading API contract. Remove the options parameter from the function
signature and the spread operator that applies it in the MsgBroadcaster
instantiation, then hardcode all configuration values directly (including
gasBufferCoefficient set to 1.2) so the function's behavior matches what callers
would actually experience.
---
Nitpick comments:
In @.coderabbit.yaml:
- Around line 36-40: The ignore_title_keywords list in the .coderabbit.yaml
configuration is missing the 'DO NOT MERGE' keyword. Add 'DO NOT MERGE' as a new
entry to the ignore_title_keywords list alongside the existing keywords 'WIP',
'DO NOT REVIEW', '[skip-coderabbit]', and '[skip ci]' to prevent CodeRabbit from
reviewing PRs that are intentionally blocked from merging.
In `@app/wallet/utils/evm.ts`:
- Around line 189-207: The switchToInjectiveEvmNetwork function returns true in
all cases: when the wallet is not an EVM browser wallet, when the strategy or
provider is missing, and after successfully calling addEvmNetwork, making it
impossible for callers to distinguish between an actual network switch and a
skipped operation. Either change the return type to void if callers do not need
to differentiate between success and skip cases, or return false for the skip
cases (the early returns when isEvmBrowserWallet check fails and when strategy
or provider is missing) while keeping true for the successful execution path
after addEvmNetwork is called.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3b2d7a58-4d4f-4bb3-a07e-c9aaaf1a8c13
⛔ Files ignored due to path filters (4)
app/generated/bff-api-types.tsis excluded by!**/generated/**app/generated/bff-spec.jsonis excluded by!**/generated/**app/generated/bff.generated.tsis excluded by!**/generated/**,!**/*.generated.*pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml,!pnpm-lock.yaml
📒 Files selected for processing (61)
.coderabbit.yamlapp/classes/Tokens.tsapp/components/Amount/Usd.spec.tsapp/composables/hooks/onWalletConnected.tsapp/composables/useSharedWalletOptions.tsapp/data/oracle.tsapp/plugins/tracking.client.tsapp/providers/cacheApi/derivative.tsapp/providers/cacheApi/spot.tsapp/providers/cacheApi/staking.tsapp/providers/cacheApi/token.tsapp/service/account.tsapp/service/app/bffApi/index.tsapp/service/app/tokenClient.tsapp/service/app/tokenPrice.tsapp/service/bff.tsapp/service/cache.tsapp/service/chain.tsapp/service/derivative.tsapp/service/exchange.tsapp/service/faucet.tsapp/service/index.tsapp/service/indexer.tsapp/service/name.tsapp/service/nameCompat.tsapp/service/oracle.tsapp/service/price.tsapp/service/pyth.tsapp/service/rwa.tsapp/service/token.tsapp/service/tokenStaticFactory.tsapp/service/web3.tsapp/store/appConfig.tsapp/store/derivative.tsapp/store/json.tsapp/store/notification.tsapp/store/oracle/index.tsapp/store/param.tsapp/store/spot.tsapp/store/token.tsapp/store/wallet/extensions.tsapp/store/wallet/index.spec.tsapp/store/wallet/index.tsapp/store/wallet/magic.tsapp/store/wallet/turnkey.tsapp/tracking.spec.tsapp/types/wallet.tsapp/utils/constant/setup.tsapp/utils/helper.tsapp/wallet/autosign.tsapp/wallet/strategy.tsapp/wallet/utils/authz.tsapp/wallet/utils/cosmos.tsapp/wallet/utils/cosmostation.tsapp/wallet/utils/evm.tsnuxt-config/bugsnag.tsnuxt-config/vite/index.tsnuxt.config.tsnuxt/tsconfig.jsonpackage.jsonscripts/gen-bff-types.ts
💤 Files with no reviewable changes (5)
- nuxt-config/bugsnag.ts
- nuxt/tsconfig.json
- nuxt.config.ts
- nuxt-config/vite/index.ts
- app/composables/hooks/onWalletConnected.ts
| scheduleGtagInstall(async () => { | ||
| const { default: VueGtag } = await import('vue-gtag') | ||
|
|
||
| nuxtApp.vueApp.use(VueGtag as any, { | ||
| config: { | ||
| id: GOOGLE_ANALYTICS_KEY | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| if (HOTJAR_KEY) { | ||
| nuxtApp.vueApp.use(hotjar as any, { | ||
| id: HOTJAR_KEY | ||
| }) | ||
| } | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n app/plugins/tracking.client.ts | head -60Repository: InjectiveLabs/injective-ui
Length of output: 1436
🏁 Script executed:
grep -n "try\|catch\|console\." app/plugins/tracking.client.tsRepository: InjectiveLabs/injective-ui
Length of output: 52
🏁 Script executed:
grep -r "scheduleGtagInstall" --include="*.ts" --include="*.js" -nRepository: InjectiveLabs/injective-ui
Length of output: 227
🏁 Script executed:
find app/plugins -type f \( -name "*.ts" -o -name "*.js" \) -exec grep -l "defineNuxtPlugin\|import(" {} \; | head -5Repository: InjectiveLabs/injective-ui
Length of output: 101
🏁 Script executed:
cat -n app/plugins/*.ts 2>/dev/null | grep -A 10 "async\|try\|catch" | head -40Repository: InjectiveLabs/injective-ui
Length of output: 348
🏁 Script executed:
rg "import\(" app/plugins --type ts --type js -B 2 -A 2Repository: InjectiveLabs/injective-ui
Length of output: 362
🏁 Script executed:
rg "\.use\(" app/plugins --type ts --type js -B 2 -A 2Repository: InjectiveLabs/injective-ui
Length of output: 374
🏁 Script executed:
rg "\.catch\(|Promise\.|\.then\(" app/plugins/tracking.client.tsRepository: InjectiveLabs/injective-ui
Length of output: 52
🏁 Script executed:
node -e "console.log('Testing promise rejection scenario:'); const cb = async () => { throw new Error('test'); }; setTimeout(cb, 0);" 2>&1 || trueRepository: InjectiveLabs/injective-ui
Length of output: 512
🏁 Script executed:
cat -n app/plugins/tracking.client.tsRepository: InjectiveLabs/injective-ui
Length of output: 1436
Add error handling around the async vue-gtag initialization to prevent unhandled promise rejections.
The async callback passed to scheduleGtagInstall can fail at the import('vue-gtag') or plugin .use() call. Without error handling, promise rejections will be unhandled, potentially affecting application stability. Wrap the initialization in a try/catch block to isolate telemetry failures.
Proposed fix
scheduleGtagInstall(async () => {
- const { default: VueGtag } = await import('vue-gtag')
-
- nuxtApp.vueApp.use(VueGtag as any, {
- config: {
- id: GOOGLE_ANALYTICS_KEY
- }
- })
+ try {
+ const { default: VueGtag } = await import('vue-gtag')
+ nuxtApp.vueApp.use(VueGtag as any, {
+ config: {
+ id: GOOGLE_ANALYTICS_KEY
+ }
+ })
+ } catch (error) {
+ console.warn('Failed to initialize vue-gtag', error)
+ }
})📝 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.
| scheduleGtagInstall(async () => { | |
| const { default: VueGtag } = await import('vue-gtag') | |
| nuxtApp.vueApp.use(VueGtag as any, { | |
| config: { | |
| id: GOOGLE_ANALYTICS_KEY | |
| } | |
| }) | |
| } | |
| if (HOTJAR_KEY) { | |
| nuxtApp.vueApp.use(hotjar as any, { | |
| id: HOTJAR_KEY | |
| }) | |
| } | |
| }) | |
| scheduleGtagInstall(async () => { | |
| try { | |
| const { default: VueGtag } = await import('vue-gtag') | |
| nuxtApp.vueApp.use(VueGtag as any, { | |
| config: { | |
| id: GOOGLE_ANALYTICS_KEY | |
| } | |
| }) | |
| } catch (error) { | |
| console.warn('Failed to initialize vue-gtag', error) | |
| } | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/plugins/tracking.client.ts` around lines 36 - 44, The async callback
passed to scheduleGtagInstall lacks error handling for potential failures during
the dynamic import of vue-gtag or the plugin initialization. Wrap the entire
async function body (including both the import('vue-gtag') call and the
nuxtApp.vueApp.use() call) in a try/catch block to handle any promise rejections
gracefully and prevent unhandled errors from affecting application stability.
| const buildAssetPriceDenomsLeanQuery = (denoms: string[] = []) => { | ||
| if (denoms.length === 0) { | ||
| return 'v2/denoms?withPrice=true&onlyActive=true&fields=price.price,price.market_cap,coingecko_id,symbol' | ||
| } | ||
|
|
||
| const denomParams = denoms.map((denom) => 'denoms=' + denom) | ||
|
|
||
| return [ | ||
| 'v2/denoms?withPrice=true&onlyActive=true&fields=price.price,price.market_cap,coingecko_id,symbol', | ||
| ...denomParams | ||
| ].join('&') | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
BASE="https://k8s.global.mainnet.asset.injective.network/asset-price"
QUERY="v2/denoms?withPrice=true&onlyActive=true&fields=price.price,price.market_cap,coingecko_id,symbol&denoms=inj"
curl -s "${BASE}/${QUERY}" | jq -r '
.data.data
| to_entries[0]
| {
denom_key: .key,
value_keys: (.value | keys | sort),
has_denom_in_value: (.value | has("denom"))
}'Repository: InjectiveLabs/injective-ui
Length of output: 134
🏁 Script executed:
find . -type f -name "tokenPrice.ts" | head -20Repository: InjectiveLabs/injective-ui
Length of output: 102
🏁 Script executed:
wc -l ./app/service/app/tokenPrice.tsRepository: InjectiveLabs/injective-ui
Length of output: 106
🏁 Script executed:
cat -n ./app/service/app/tokenPrice.tsRepository: InjectiveLabs/injective-ui
Length of output: 8730
🏁 Script executed:
find . -type f \( -name "*.test.ts" -o -name "*.spec.ts" \) | xargs grep -l "tokenPrice\|TokenPrice" 2>/dev/null | head -10Repository: InjectiveLabs/injective-ui
Length of output: 52
🏁 Script executed:
rg "buildAssetPriceDenomsLeanQuery|fetchUsdTokenPriceLean" --type tsRepository: InjectiveLabs/injective-ui
Length of output: 397
🏁 Script executed:
sed -n '1,100p' app/store/token.ts | cat -nRepository: InjectiveLabs/injective-ui
Length of output: 3694
🏁 Script executed:
rg "fetchUsdTokenPriceLean" -A 5 -B 5 app/store/token.tsRepository: InjectiveLabs/injective-ui
Length of output: 429
Add denom field to lean price query and fix fallback logic to prevent undefined price keys.
The lean query at lines 47 and 53 excludes denom from the requested fields, but the code at line 120 falls back to tokenWithPrice.denom when coingecko_id is missing. If the API doesn't return denom and coingecko_id is undefined, id becomes undefined, causing prices to be stored under the wrong key.
Additionally, using Object.values() discards the denom key from the API response structure, eliminating a reliable fallback option.
Proposed fix
interface TokenStaticLeanWithPrice {
- denom: string
+ denom?: string
symbol: string
- coingecko_id: string
+ coingecko_id?: string
price?: {
price?: number
market_cap?: number
}
}
const buildAssetPriceDenomsLeanQuery = (denoms: string[] = []) => {
if (denoms.length === 0) {
- return 'v2/denoms?withPrice=true&onlyActive=true&fields=price.price,price.market_cap,coingecko_id,symbol'
+ return 'v2/denoms?withPrice=true&onlyActive=true&fields=denom,price.price,price.market_cap,coingecko_id,symbol'
}
const denomParams = denoms.map((denom) => 'denoms=' + denom)
return [
- 'v2/denoms?withPrice=true&onlyActive=true&fields=price.price,price.market_cap,coingecko_id,symbol',
+ 'v2/denoms?withPrice=true&onlyActive=true&fields=denom,price.price,price.market_cap,coingecko_id,symbol',
...denomParams
].join('&')
}
-const tokenPriceMap = Object.values(response.data.data).reduce(
- (tokenPriceMap: TokenPriceMap, tokenWithPrice) => {
- const id = tokenWithPrice.coingecko_id || tokenWithPrice.denom
+const tokenPriceMap = Object.entries(response.data.data).reduce(
+ (tokenPriceMap: TokenPriceMap, [denomKey, tokenWithPrice]) => {
+ const id = tokenWithPrice.coingecko_id || tokenWithPrice.denom || denomKey🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/service/app/tokenPrice.ts` around lines 45 - 56, The
buildAssetPriceDenomsLeanQuery function excludes the denom field from its query
string, but consuming code relies on falling back to the denom value when
coingecko_id is undefined. Add denom to the fields parameter in both return
statements of buildAssetPriceDenomsLeanQuery by appending it to the existing
comma-separated fields list (alongside price.price, price.market_cap,
coingecko_id, and symbol) so that the API response includes the denom field and
the fallback logic can work correctly.
| const getInjNameService = () => { | ||
| if (!injNameServicePromise) { | ||
| injNameServicePromise = import('./name').then( | ||
| ({ injNameService }) => injNameService | ||
| ) | ||
| } | ||
|
|
||
| return injNameServicePromise | ||
| } | ||
|
|
||
| const getInjBonfidaNameService = () => { | ||
| if (!injBonfidaNameServicePromise) { | ||
| injBonfidaNameServicePromise = import('./name').then( | ||
| ({ injBonfidaNameService }) => injBonfidaNameService | ||
| ) | ||
| } | ||
|
|
||
| return injBonfidaNameServicePromise |
There was a problem hiding this comment.
Reset failed lazy-import caches to avoid permanent failure state.
On Line 9 and Line 19, a failed import('./name') leaves the cached promise rejected forever. After one transient load error, all subsequent fetchInjName/fetchInjAddress calls keep failing until hard refresh.
💡 Suggested fix
const getInjNameService = () => {
if (!injNameServicePromise) {
- injNameServicePromise = import('./name').then(
- ({ injNameService }) => injNameService
- )
+ injNameServicePromise = import('./name')
+ .then(({ injNameService }) => injNameService)
+ .catch((error) => {
+ injNameServicePromise = undefined
+ throw error
+ })
}
return injNameServicePromise
}
const getInjBonfidaNameService = () => {
if (!injBonfidaNameServicePromise) {
- injBonfidaNameServicePromise = import('./name').then(
- ({ injBonfidaNameService }) => injBonfidaNameService
- )
+ injBonfidaNameServicePromise = import('./name')
+ .then(({ injBonfidaNameService }) => injBonfidaNameService)
+ .catch((error) => {
+ injBonfidaNameServicePromise = undefined
+ throw error
+ })
}
return injBonfidaNameServicePromise
}📝 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 getInjNameService = () => { | |
| if (!injNameServicePromise) { | |
| injNameServicePromise = import('./name').then( | |
| ({ injNameService }) => injNameService | |
| ) | |
| } | |
| return injNameServicePromise | |
| } | |
| const getInjBonfidaNameService = () => { | |
| if (!injBonfidaNameServicePromise) { | |
| injBonfidaNameServicePromise = import('./name').then( | |
| ({ injBonfidaNameService }) => injBonfidaNameService | |
| ) | |
| } | |
| return injBonfidaNameServicePromise | |
| const getInjNameService = () => { | |
| if (!injNameServicePromise) { | |
| injNameServicePromise = import('./name') | |
| .then(({ injNameService }) => injNameService) | |
| .catch((error) => { | |
| injNameServicePromise = undefined | |
| throw error | |
| }) | |
| } | |
| return injNameServicePromise | |
| } | |
| const getInjBonfidaNameService = () => { | |
| if (!injBonfidaNameServicePromise) { | |
| injBonfidaNameServicePromise = import('./name') | |
| .then(({ injBonfidaNameService }) => injBonfidaNameService) | |
| .catch((error) => { | |
| injBonfidaNameServicePromise = undefined | |
| throw error | |
| }) | |
| } | |
| return injBonfidaNameServicePromise | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/service/nameCompat.ts` around lines 8 - 25, The lazy-import caching in
getInjNameService and getInjBonfidaNameService functions stores rejected
promises permanently when the import fails. Add error handling with a catch
block to both import chains that resets the respective cache variable
(injNameServicePromise and injBonfidaNameServicePromise) back to null/undefined
when an error occurs, then re-throws the error. This ensures that if a transient
import failure happens, the next call to these functions will attempt to
re-import the module instead of returning the cached rejected promise.
| tokenUsdPriceMap: { | ||
| [usdcToken.denom]: 1 | ||
| }, |
There was a problem hiding this comment.
Filtered fetches are overwriting the entire USD maps.
Line 172/Line 182/Line 193 replace whole maps even when denoms is a subset. That drops previously cached prices (and the seeded USDC denom on Line 23), so non-requested tokens can regress to 0 in tokenUsdPrice.
Proposed fix
async fetchTokensUsdPriceMap(denoms: string[] = []) {
const sharedTokenStore = useSharedTokenStore()
const tokenUsdPriceMap =
await tokenPriceService.fetchUsdTokensPrice(denoms)
- sharedTokenStore.tokenUsdPriceMap = tokenUsdPriceMap.prices
- sharedTokenStore.tokenUsdMarketCapMap = tokenUsdPriceMap.marketCap
+ sharedTokenStore.tokenUsdPriceMap =
+ denoms.length === 0
+ ? tokenUsdPriceMap.prices
+ : { ...sharedTokenStore.tokenUsdPriceMap, ...tokenUsdPriceMap.prices }
+ sharedTokenStore.tokenUsdMarketCapMap =
+ denoms.length === 0
+ ? tokenUsdPriceMap.marketCap
+ : {
+ ...sharedTokenStore.tokenUsdMarketCapMap,
+ ...tokenUsdPriceMap.marketCap
+ }
},
async fetchTokensUsdPriceMapLean(denoms: string[] = []) {
const sharedTokenStore = useSharedTokenStore()
const tokenUsdPriceMap =
await tokenPriceService.fetchUsdTokenPriceLean(denoms)
- sharedTokenStore.tokenUsdPriceMap = tokenUsdPriceMap.prices
- sharedTokenStore.tokenUsdMarketCapMap = tokenUsdPriceMap.marketCap
+ sharedTokenStore.tokenUsdPriceMap =
+ denoms.length === 0
+ ? tokenUsdPriceMap.prices
+ : { ...sharedTokenStore.tokenUsdPriceMap, ...tokenUsdPriceMap.prices }
+ sharedTokenStore.tokenUsdMarketCapMap =
+ denoms.length === 0
+ ? tokenUsdPriceMap.marketCap
+ : {
+ ...sharedTokenStore.tokenUsdMarketCapMap,
+ ...tokenUsdPriceMap.marketCap
+ }
},Also applies to: 166-197
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/store/token.ts` around lines 22 - 24, The tokenUsdPriceMap is being
completely replaced at lines 172, 182, and 193 when filtered denoms are fetched,
which overwrites previously cached prices including the seeded USDC denom.
Instead of assigning the fetched prices directly to tokenUsdPriceMap, merge the
new prices into the existing map by using spread syntax or Object.assign to
preserve previously cached values while adding the newly fetched prices.
| vi.mock('../../service', () => ({ | ||
| getAuthZApi: vi.fn(), | ||
| web3GatewayService: { | ||
| healthCheck: vi.fn() | ||
| } | ||
| })) |
There was a problem hiding this comment.
Mock path no longer matches the module imported by the store.
Line 32 mocks ../../service, but app/store/wallet/index.ts imports web3GatewayService from ../../service/web3 (Line 4). This mock won’t intercept that dependency.
Suggested patch
-vi.mock('../../service', () => ({
- getAuthZApi: vi.fn(),
- web3GatewayService: {
- healthCheck: vi.fn()
- }
-}))
+vi.mock('../../service/web3', () => ({
+ web3GatewayService: {
+ healthCheck: vi.fn()
+ }
+}))📝 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.
| vi.mock('../../service', () => ({ | |
| getAuthZApi: vi.fn(), | |
| web3GatewayService: { | |
| healthCheck: vi.fn() | |
| } | |
| })) | |
| vi.mock('../../service/web3', () => ({ | |
| web3GatewayService: { | |
| healthCheck: vi.fn() | |
| } | |
| })) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/store/wallet/index.spec.ts` around lines 32 - 37, The mock path in the
vi.mock call at the beginning of the test file is using `../../service`, but the
actual code in app/store/wallet/index.ts imports web3GatewayService from
`../../service/web3`. Update the mock path in the vi.mock function to match the
actual import path by changing `../../service` to `../../service/web3`, ensuring
the mock properly intercepts the web3GatewayService dependency and its
healthCheck method.
| if (!target || !(target in BFF_OPENAPI_URLS)) { | ||
| console.error( | ||
| `Usage: tsx scripts/gen-bff-types.ts ${Object.keys(BFF_OPENAPI_URLS).join('|')}` | ||
| ) | ||
| process.exit(1) | ||
| } | ||
|
|
||
| return target as BffTypesTarget |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
head -50 scripts/gen-bff-types.tsRepository: InjectiveLabs/injective-ui
Length of output: 1401
Use Object.hasOwn() for strict own-property validation.
Line 36 uses the in operator, which checks both own and inherited properties. This means inherited keys like toString or constructor would incorrectly pass validation. Use Object.hasOwn() to ensure only the declared targets (dev, staging, production) are accepted.
Proposed fix
- if (!target || !(target in BFF_OPENAPI_URLS)) {
+ if (!target || !Object.hasOwn(BFF_OPENAPI_URLS, target)) {📝 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.
| if (!target || !(target in BFF_OPENAPI_URLS)) { | |
| console.error( | |
| `Usage: tsx scripts/gen-bff-types.ts ${Object.keys(BFF_OPENAPI_URLS).join('|')}` | |
| ) | |
| process.exit(1) | |
| } | |
| return target as BffTypesTarget | |
| if (!target || !Object.hasOwn(BFF_OPENAPI_URLS, target)) { | |
| console.error( | |
| `Usage: tsx scripts/gen-bff-types.ts ${Object.keys(BFF_OPENAPI_URLS).join('|')}` | |
| ) | |
| process.exit(1) | |
| } | |
| return target as BffTypesTarget |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/gen-bff-types.ts` around lines 36 - 43, The validation check on line
36 uses the `in` operator which checks both own and inherited properties of the
BFF_OPENAPI_URLS object, allowing inherited keys like toString or constructor to
incorrectly pass validation. Replace the condition `!(target in
BFF_OPENAPI_URLS)` with `!Object.hasOwn(BFF_OPENAPI_URLS, target)` to ensure
only the explicitly declared targets are accepted.
| async function fetchOpenApiSpec(openApiUrl: string, apiKey: string) { | ||
| const response = await fetch(openApiUrl, { | ||
| headers: { | ||
| 'x-api-key': apiKey | ||
| } | ||
| }) | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n scripts/gen-bff-types.ts | sed -n '70,100p'Repository: InjectiveLabs/injective-ui
Length of output: 936
🏁 Script executed:
cat -n scripts/gen-bff-types.ts | sed -n '93,150p'Repository: InjectiveLabs/injective-ui
Length of output: 1020
🏁 Script executed:
rg "fetch\(" scripts/gen-bff-types.ts -nRepository: InjectiveLabs/injective-ui
Length of output: 118
Add a timeout/abort to the OpenAPI fetch.
The fetch on line 78 has no timeout; a stalled network call can hang the generation job indefinitely. Use AbortController with a reasonable timeout (e.g., 15 seconds).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/gen-bff-types.ts` around lines 77 - 83, The fetchOpenApiSpec function
makes a fetch call without any timeout, which can cause the generation job to
hang indefinitely if the network stalls. Add an AbortController instance and set
a timeout (e.g., 15 seconds) that will abort the request if it exceeds the time
limit. Pass the abort signal from the controller in the fetch options headers,
and ensure the fetch call properly handles any abort errors that may be thrown.
There was a problem hiding this comment.
🧹 Nitpick comments (4)
app/wallet/pkBroadcaster.ts (1)
5-32: 🧹 Nitpick | 🔵 Trivial | 💤 Low valueConsider clearing the cached instance when the private key changes.
When a different
privateKeyis passed, the oldmsgBroadcasterWithPkInstanceis overwritten without cleanup. IfMsgBroadcasterWithPkholds any resources (connections, event listeners), they may leak. Additionally, concurrent calls with different private keys could race to overwrite the cache.If
MsgBroadcasterWithPkis stateless and lightweight, this is fine. Otherwise, consider explicitly nullifying the old instance or adding a cleanup method.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/wallet/pkBroadcaster.ts` around lines 5 - 32, When a different privateKey is passed to getMsgBroadcasterWithPk, the old msgBroadcasterWithPkInstance is overwritten without cleanup, which may cause resource leaks if MsgBroadcasterWithPk holds connections or event listeners. Before creating and assigning the new MsgBroadcasterWithPk instance in the import promise chain, first nullify the old msgBroadcasterWithPkInstance to ensure any resources are properly released. This should occur inside the .then block, after the conditional check fails but before constructing the new instance.app/store/oracle/index.ts (1)
76-80: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winExtract the hardcoded mainnet URL to a constant.
The mainnet oracle stream URL is hardcoded on Line 78, while the testnet path uses
ENDPOINTS.indexer. For consistency and maintainability, extract the mainnet URL to a constant (e.g., inapp/utils/constant/setup.tsalongsideENDPOINTS).♻️ Suggested refactor
In
app/utils/constant/setup.ts, add:export const ORACLE_STREAM_ENDPOINT = IS_MAINNET ? 'https://tc-derivatives.grpc-web.mainnet.asia.injective.network/' : ENDPOINTS.indexerThen update this file:
- const oracleStreamV2 = new IndexerGrpcOracleStreamV2( - IS_MAINNET - ? 'https://tc-derivatives.grpc-web.mainnet.asia.injective.network/' - : ENDPOINTS.indexer - ) + const oracleStreamV2 = new IndexerGrpcOracleStreamV2(ORACLE_STREAM_ENDPOINT)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/store/oracle/index.ts` around lines 76 - 80, Extract the hardcoded mainnet URL from the IndexerGrpcOracleStreamV2 instantiation in app/store/oracle/index.ts into a constant for consistency. Create a new constant called ORACLE_STREAM_ENDPOINT in app/utils/constant/setup.ts that returns the appropriate URL based on the IS_MAINNET flag (mainnet URL for true, ENDPOINTS.indexer for false). Then update the IndexerGrpcOracleStreamV2 constructor call to use this new constant instead of the inline conditional expression with the hardcoded URL.nuxt-config/vite/chunk/index.ts (1)
365-368: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winConsider documenting the vite/preload-helper special case.
The explicit routing of
vite/preload-helpertoSharedVendoris a sensible optimization (as a Vite internal used across entry points), but it lacks explanation. Consider adding a brief comment to help future maintainers understand this special case.📝 Suggested comment addition
export function manualChunks(id: string): string | undefined { + // Vite's preload helper is used across entry points; bundle it in SharedVendor + // to avoid duplication and ensure it's available early if (id.includes('vite/preload-helper')) { return ChunkName.SharedVendor }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@nuxt-config/vite/chunk/index.ts` around lines 365 - 368, The condition checking for vite/preload-helper lacks documentation explaining why this module is specifically routed to SharedVendor. Add a brief comment above the if statement that explains this is a Vite internal module used across multiple entry points, which makes it a sensible optimization candidate for shared vendor chunking. This will help future maintainers understand the rationale behind this special case routing.modules/preload-optimization.ts (1)
179-212: 🧹 Nitpick | 🔵 TrivialAdd clarifying comment explaining why both preload filtering hooks are necessary.
This PR adds a
vite:extendConfighook that filters preload dependencies at config-time viaresolveDependencies(lines 179-212), while the existingbuild:manifesthook applies a safety check at post-build time to ensure excluded files don't havepreload: true(lines 213-226). Both hooks use the sameshouldExcludeFromPreload()logic but operate on different data stages.Without a comment explaining why both mechanisms are needed, it's unclear whether this is intentional defense-in-depth or unintentional overlap. Consider adding a brief inline comment explaining the relationship between these two filtering stages.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@modules/preload-optimization.ts` around lines 179 - 212, Add a clarifying comment above the vite:extendConfig hook in the preload-optimization module explaining the relationship between the two filtering mechanisms. The comment should explain that this hook filters dependencies at config-time via the resolveDependencies callback, while the existing build:manifest hook applies a post-build safety check to ensure excluded files don't have preload:true set. Make it clear that both hooks use the same shouldExcludeFromPreload logic but operate at different stages (config-time vs post-build), establishing this as an intentional defense-in-depth approach to ensure excluded files are properly handled throughout the entire build process.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@app/store/oracle/index.ts`:
- Around line 76-80: Extract the hardcoded mainnet URL from the
IndexerGrpcOracleStreamV2 instantiation in app/store/oracle/index.ts into a
constant for consistency. Create a new constant called ORACLE_STREAM_ENDPOINT in
app/utils/constant/setup.ts that returns the appropriate URL based on the
IS_MAINNET flag (mainnet URL for true, ENDPOINTS.indexer for false). Then update
the IndexerGrpcOracleStreamV2 constructor call to use this new constant instead
of the inline conditional expression with the hardcoded URL.
In `@app/wallet/pkBroadcaster.ts`:
- Around line 5-32: When a different privateKey is passed to
getMsgBroadcasterWithPk, the old msgBroadcasterWithPkInstance is overwritten
without cleanup, which may cause resource leaks if MsgBroadcasterWithPk holds
connections or event listeners. Before creating and assigning the new
MsgBroadcasterWithPk instance in the import promise chain, first nullify the old
msgBroadcasterWithPkInstance to ensure any resources are properly released. This
should occur inside the .then block, after the conditional check fails but
before constructing the new instance.
In `@modules/preload-optimization.ts`:
- Around line 179-212: Add a clarifying comment above the vite:extendConfig hook
in the preload-optimization module explaining the relationship between the two
filtering mechanisms. The comment should explain that this hook filters
dependencies at config-time via the resolveDependencies callback, while the
existing build:manifest hook applies a post-build safety check to ensure
excluded files don't have preload:true set. Make it clear that both hooks use
the same shouldExcludeFromPreload logic but operate at different stages
(config-time vs post-build), establishing this as an intentional
defense-in-depth approach to ensure excluded files are properly handled
throughout the entire build process.
In `@nuxt-config/vite/chunk/index.ts`:
- Around line 365-368: The condition checking for vite/preload-helper lacks
documentation explaining why this module is specifically routed to SharedVendor.
Add a brief comment above the if statement that explains this is a Vite internal
module used across multiple entry points, which makes it a sensible optimization
candidate for shared vendor chunking. This will help future maintainers
understand the rationale behind this special case routing.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 01f9028b-b983-41d6-9958-07fc569bee5f
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml,!pnpm-lock.yaml
📒 Files selected for processing (66)
app/classes/TokenFactoryStatic.tsapp/classes/Tokens.tsapp/components/Amount/Base.vueapp/components/Amount/Index.spec.tsapp/components/Amount/Index.vueapp/components/Amount/Usd.spec.tsapp/components/Amount/Usd.vueapp/components/NumInput.vueapp/components/QRCode.vueapp/composables/useSharedBigNumberFormatted.tsapp/data/token.tsapp/data/tokenLogo.tsapp/providers/cacheApi/derivative.tsapp/providers/cacheApi/spot.tsapp/service/app/CoinGeckoApi.tsapp/service/app/Faucet.tsapp/service/app/SharedTokenClientStatic.tsapp/service/app/Web3Client.tsapp/service/app/Web3Gateway.tsapp/service/app/bonfida.tsapp/service/app/cacheRwaPriceFeedService.tsapp/service/app/ethGasPrice/estimator.tsapp/service/app/ethGasPrice/index.tsapp/service/app/nameService/utils.tsapp/service/app/pythClient.tsapp/service/app/tokenClient.tsapp/service/app/tokenPrice.tsapp/service/indexer.tsapp/store/evm.tsapp/store/geo.tsapp/store/json.tsapp/store/oracle/index.tsapp/store/param.tsapp/store/token.tsapp/store/wallet/extensions.tsapp/store/wallet/index.spec.tsapp/store/wallet/index.tsapp/store/wallet/magic.tsapp/store/wallet/turnkey.tsapp/transformer/explorer/index.tsapp/transformer/explorer/messageEvents.tsapp/transformer/explorer/messageSummary.tsapp/transformer/market/fundingRate.tsapp/transformer/market/index.tsapp/transformer/market/summary.tsapp/transformer/oracle.tsapp/transformer/trade/order.tsapp/types/market.tsapp/types/trade.tsapp/utils/constant/index.tsapp/utils/constant/setup.tsapp/utils/evm/Erc20Contract.tsapp/utils/evm/WETH9Contract.tsapp/utils/formatter.tsapp/utils/helper.tsapp/utils/ibc.tsapp/utils/index.tsapp/utils/time.tsapp/wallet/pkBroadcaster.tsapp/wallet/strategy.tsapp/wallet/utils/authz.tsmodules/preload-optimization.tsnuxt-config/vite/chunk/bridge.tsnuxt-config/vite/chunk/index.spec.tsnuxt-config/vite/chunk/index.tsnuxt.config.ts
💤 Files with no reviewable changes (1)
- nuxt-config/vite/chunk/bridge.ts
✅ Files skipped from review due to trivial changes (11)
- app/utils/constant/index.ts
- app/components/Amount/Index.spec.ts
- app/service/app/Web3Gateway.ts
- app/transformer/market/index.ts
- app/service/app/pythClient.ts
- app/service/app/CoinGeckoApi.ts
- app/utils/helper.ts
- app/classes/TokenFactoryStatic.ts
- app/types/market.ts
- app/transformer/oracle.ts
- app/transformer/market/summary.ts
🚧 Files skipped from review as they are similar to previous changes (12)
- app/wallet/utils/authz.ts
- app/store/wallet/turnkey.ts
- app/store/param.ts
- app/service/app/tokenClient.ts
- app/classes/Tokens.ts
- app/store/wallet/magic.ts
- app/components/Amount/Usd.spec.ts
- app/utils/constant/setup.ts
- app/providers/cacheApi/derivative.ts
- app/store/token.ts
- app/store/wallet/index.spec.ts
- app/service/app/tokenPrice.ts
Summary by CodeRabbit
@injectivelabsdeps to 1.20.17