Skip to content

fix(nft): implement parent coin activation for NFTs#3010

Merged
CharlVS merged 10 commits intodevfrom
codex/add-function-to-activate-parent-coins-for-nfts
Jul 30, 2025
Merged

fix(nft): implement parent coin activation for NFTs#3010
CharlVS merged 10 commits intodevfrom
codex/add-function-to-activate-parent-coins-for-nfts

Conversation

@takenagain
Copy link
Copy Markdown
Contributor

@takenagain takenagain commented Jul 28, 2025

Fixes:

  • The NFT page for a fresh wallet remaining in the loading state indefinitely due to the required parent coins not being active. This can also be reproduced by disabling AVAX, MATIC, FTM, BNB, or ETH in an existing wallet after login.
  • a bug when quickly deactivating and reactivating the same coin in the same session. Skips the disable_coin RPC call for now, leaving the coin enabled in the background. Encountered with background NFT refresh tasks that try to activate the required parent and NFT coins before making requests.
  • skeleton loader list tile RenderBox assertion error in debug mode due to unconstrained height in list/sliver.

Summary by CodeRabbit

  • Bug Fixes

    • Improved reliability of NFT operations by ensuring required parent coins are activated before proceeding.
    • Enhanced error handling for NFT updates and retrievals, allowing partial successes even if some chains fail.
    • Prevented errors when deactivating coins by adjusting the deactivation process to avoid disabling coins directly.
  • New Features

    • Added a method to retrieve only active NFT chains from the SDK.
    • Introduced retry logic with exponential backoff for enabling NFT chains and updating NFTs.
    • Added an optional height parameter to the skeleton loader list tile widget for customizable UI appearance.
  • Refactor

    • Streamlined the process for updating and fetching NFTs by handling each blockchain individually and logging errors without interrupting the entire operation.
    • Standardized error logging for NFT operations for clearer diagnostics.
    • Improved event handling in NFT management with restartable event processing and enhanced logging for user state checks.

Copilot AI review requested due to automatic review settings July 28, 2025 11:06
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jul 28, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes refactor NFT-related repository and API logic to improve error handling, logging, and control flow. The NftsRepo now ensures parent coins are activated before NFT operations, with error logging standardized via the Dart logging package. The NFT API methods are restructured for per-chain processing, granular error handling, and improved result aggregation. Additionally, coin deactivation logic is adjusted to avoid disabling coins to prevent errors. The NFT main bloc adds retry logic and improved event handling. A UI widget is enhanced with a configurable height parameter.

Changes

Cohort / File(s) Change Summary
NFTsRepo: Parent Coin Activation & Logging
lib/bloc/nfts/nft_main_repo.dart
Adds _activateParentCoins to activate parent coins before NFT operations; updates imports; standardizes error logging to use Dart Logger; ensures preparatory coin activation in updateNft and getNfts.
NFT API: Per-Chain Refactor, Retry & Error Handling
lib/mm2/mm2_api/mm2_api_nft.dart
Removes broad enabling of NFT chains; adds getActiveNftChains method; refactors enabling logic to enable inactive chains individually with retry and error aggregation; updates enableNft to include retry with exponential backoff.
CoinsRepo: Deactivation Logic Adjustment
lib/bloc/coins_bloc/coins_repo.dart
Modifies deactivateCoinsSync to skip disabling coins to avoid errors; only cancels balance watchers and removes coins from activated list asynchronously; adds TODO for tracking issue.
NftMainBloc: Event Handling & Retry Logic
lib/bloc/nfts/nft_main_bloc.dart
Uses restartable() transformer for chain update events; adds warning logs for invalid states; wraps NFT update calls with retry and exponential backoff; improves robustness and observability.
UI Widget: SkeletonListTile Height Parameter
packages/komodo_ui_kit/lib/src/skeleton_loaders/skeleton_loader_list_tile.dart
Adds optional height parameter with default 122 to SkeletonListTile; updates container height in build method accordingly.

Sequence Diagram(s)

sequenceDiagram
    participant UI
    participant NftsRepo
    participant CoinsRepo
    participant MM2ApiNft

    UI->>NftsRepo: updateNft/getNfts(chains)
    NftsRepo->>CoinsRepo: getKnownCoins()
    NftsRepo->>CoinsRepo: activateCoin(parentCoin) (for each chain)
    NftsRepo->>MM2ApiNft: updateNftList/getNftList(chains)
    MM2ApiNft->>MM2ApiNft: enable inactive chains with retry (per chain)
    MM2ApiNft->>MM2ApiNft: fetch active NFT chains
    MM2ApiNft->>MM2ApiNft: update/fetch NFTs (per chain)
    MM2ApiNft-->>NftsRepo: aggregated result or error map
    NftsRepo-->>UI: result or error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

QA

Suggested reviewers

  • AndrewDelaney
  • ShantanuSharma9873
  • CharlVS

Poem

In the warren where NFTs hop and play,
Parent coins now wake before the fray.
Chains enable with retries, no fear,
Errors logged loud for all to hear.
Balance watchers dance, coins stay bright,
UI tiles grow tall, a pleasing sight.
Rabbits review with joy and cheer! 🐇✨

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/add-function-to-activate-parent-coins-for-nfts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements parent coin activation for NFT operations and improves error handling resilience. The main goal is to ensure parent coins are activated before performing NFT operations and to make NFT fetching more robust by handling per-chain failures gracefully.

  • Adds automatic parent coin activation before NFT operations
  • Refactors updateNftList and getNftList to handle individual chain failures without stopping the entire operation
  • Improves error messages and logging for better debugging

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
lib/bloc/nfts/nft_main_repo.dart Adds parent coin activation logic and integrates it into NFT update/fetch operations
lib/mm2/mm2_api/mm2_api_nft.dart Refactors NFT API methods to process chains individually and handle failures gracefully

@takenagain takenagain marked this pull request as draft July 28, 2025 11:08
@takenagain takenagain self-assigned this Jul 28, 2025
@takenagain takenagain added the bug Something isn't working label Jul 28, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Jul 28, 2025

Visit the preview URL for this PR (updated for commit 6cee8f2):

https://walletrc--pull-3010-merge-zm0yuh3l.web.app

(expires Tue, 05 Aug 2025 20:33:36 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: f66a4ff03faa546f12f0ae5a841bd9eff2714dcc

takenagain and others added 2 commits July 28, 2025 13:11
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@takenagain takenagain changed the title Implement parent coin activation for NFTs fix(nft): implement parent coin activation for NFTs Jul 28, 2025
@takenagain
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jul 28, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@takenagain
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jul 28, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@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 9e3029d and c962821.

📒 Files selected for processing (5)
  • lib/bloc/coins_bloc/coins_repo.dart (2 hunks)
  • lib/bloc/nfts/nft_main_bloc.dart (5 hunks)
  • lib/bloc/nfts/nft_main_repo.dart (3 hunks)
  • lib/mm2/mm2_api/mm2_api_nft.dart (2 hunks)
  • packages/komodo_ui_kit/lib/src/skeleton_loaders/skeleton_loader_list_tile.dart (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/bloc/nfts/nft_main_repo.dart
  • lib/mm2/mm2_api/mm2_api_nft.dart
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: takenagain
PR: KomodoPlatform/komodo-wallet#2976
File: lib/bloc/coins_manager/coins_manager_bloc.dart:82-83
Timestamp: 2025-07-23T09:31:17.738Z
Learning: In the CoinsManagerBloc, `state.selectedCoins` is used separately from `state.coins` to indicate whether a coin is enabled or not in the UI. The order of Set deduplication when merging coin lists doesn't affect UI behavior because selection state is tracked independently from the coin list used for filtering and sorting.
Learnt from: takenagain
PR: KomodoPlatform/komodo-wallet#2566
File: lib/bloc/coins_bloc/coins_bloc.dart:10-10
Timestamp: 2025-04-01T15:51:37.060Z
Learning: In the Komodo Wallet project, part files share imports with their parent files. The import for `app_config.dart` in `coins_bloc.dart` is necessary because the part file `coins_state.dart` uses `excludedAssetList` from that package.
Learnt from: takenagain
PR: KomodoPlatform/komodo-wallet#2566
File: lib/bloc/coins_bloc/coins_bloc.dart:10-10
Timestamp: 2025-04-01T15:51:37.060Z
Learning: The `excludedAssetList` from `app_config.dart` is used in the `_filterExcludedAssets` method in `coins_state.dart`. Since `coins_state.dart` is a part file of `coins_bloc.dart`, the import needs to be in the parent file even though it's not directly used there. In Dart, part files share the namespace and imports of their parent files.
lib/bloc/coins_bloc/coins_repo.dart (3)

Learnt from: takenagain
PR: #2976
File: lib/bloc/coins_manager/coins_manager_bloc.dart:82-83
Timestamp: 2025-07-23T09:31:17.738Z
Learning: In the CoinsManagerBloc, state.selectedCoins is used separately from state.coins to indicate whether a coin is enabled or not in the UI. The order of Set deduplication when merging coin lists doesn't affect UI behavior because selection state is tracked independently from the coin list used for filtering and sorting.

Learnt from: takenagain
PR: #2566
File: lib/bloc/coins_bloc/coins_bloc.dart:10-10
Timestamp: 2025-04-01T15:51:37.060Z
Learning: The excludedAssetList from app_config.dart is used in the _filterExcludedAssets method in coins_state.dart. Since coins_state.dart is a part file of coins_bloc.dart, the import needs to be in the parent file even though it's not directly used there. In Dart, part files share the namespace and imports of their parent files.

Learnt from: takenagain
PR: #2566
File: lib/bloc/coins_bloc/coins_bloc.dart:10-10
Timestamp: 2025-04-01T15:51:37.060Z
Learning: In the Komodo Wallet project, part files share imports with their parent files. The import for app_config.dart in coins_bloc.dart is necessary because the part file coins_state.dart uses excludedAssetList from that package.

lib/bloc/nfts/nft_main_bloc.dart (6)

Learnt from: takenagain
PR: #2566
File: lib/bloc/coins_bloc/coins_bloc.dart:10-10
Timestamp: 2025-04-01T15:51:37.060Z
Learning: In the Komodo Wallet project, part files share imports with their parent files. The import for app_config.dart in coins_bloc.dart is necessary because the part file coins_state.dart uses excludedAssetList from that package.

Learnt from: takenagain
PR: #2566
File: lib/bloc/coins_bloc/coins_bloc.dart:10-10
Timestamp: 2025-04-01T15:51:37.060Z
Learning: The excludedAssetList from app_config.dart is used in the _filterExcludedAssets method in coins_state.dart. Since coins_state.dart is a part file of coins_bloc.dart, the import needs to be in the parent file even though it's not directly used there. In Dart, part files share the namespace and imports of their parent files.

Learnt from: takenagain
PR: #2608
File: lib/bloc/fiat/fiat_onramp_form/fiat_form_bloc.dart:2-3
Timestamp: 2025-05-01T21:00:36.970Z
Learning: It's acceptable to use unconditional dart:io imports in the Komodo wallet codebase when the usage is guarded by !kIsWeb conditional checks that prevent the platform-specific code from being executed in web environments.

Learnt from: takenagain
PR: #2611
File: test_units/tests/system_health/system_clock_repository_test.dart:7-8
Timestamp: 2025-05-08T19:07:13.442Z
Learning: In the Komodo Wallet project, test files are structured to define test functions that are called from a central test runner in test_units/main.dart, rather than each test file having its own main() function.

Learnt from: takenagain
PR: #2611
File: test_units/tests/system_health/system_clock_repository_test.dart:7-8
Timestamp: 2025-05-08T19:07:13.442Z
Learning: In the Komodo Wallet project, test files are structured to define test functions that are called from a central test runner in test_units/main.dart, rather than each test file having its own main() function.

Learnt from: takenagain
PR: #2611
File: test_units/tests/system_health/http_head_time_provider_test.dart:8-24
Timestamp: 2025-05-08T19:05:13.083Z
Learning: In the Komodo Wallet project, test functions are defined in individual files under test_units/tests/ but are executed through the central entry point in test_units/main.dart, so individual test files don't need their own main() function.

🪛 GitHub Actions: takenagain is validating code guidelines 🚀
lib/bloc/coins_bloc/coins_repo.dart

[warning] 495-495: The declaration '_disableCoin' isn't referenced.


[warning] 495-495: The declaration '_disableCoin' isn't referenced.

🔇 Additional comments (8)
packages/komodo_ui_kit/lib/src/skeleton_loaders/skeleton_loader_list_tile.dart (2)

4-9: LGTM! Clean parameterization of height.

The addition of the optional height parameter with a sensible default value of 122 maintains backward compatibility while providing flexibility for different use cases.


57-57: LGTM! Correct usage of height parameter.

The height parameter is properly utilized in the Container widget, completing the parameterization cleanly.

lib/bloc/coins_bloc/coins_repo.dart (1)

435-438: LGTM! Clear documentation of the temporary workaround.

The updated documentation clearly explains that only balance watchers are cancelled to avoid "NoSuchCoin" errors during reactivation, which aligns with the PR's goal of fixing coin reactivation issues.

lib/bloc/nfts/nft_main_bloc.dart (5)

4-4: LGTM! Appropriate imports for enhanced functionality.

The added imports support the new retry mechanism and concurrency control features. The specific import of retry and ExponentialBackoff from komodo_defi_type_utils aligns with the implementation in _getAllNfts.

Also applies to: 7-8


26-27: Good improvement: Restartable transformer prevents concurrent updates.

Using restartable() transformer for NftMainChainUpdateRequested events ensures that if a new update request comes in while one is already processing, the old one gets cancelled and the new one starts fresh. This is particularly valuable for NFT updates which can be time-consuming operations.


56-57: Enhanced observability with appropriate warning log.

The warning log provides clear diagnostic information when NFT tab changes are attempted in invalid states, helping with debugging the loading issues mentioned in the PR objectives.


89-89: Consistent logging pattern for unauthorized access.

The warning log follows the same pattern as the one in _onTabChanged, providing consistent diagnostic information across the bloc.


185-194: Excellent retry mechanism implementation with proper error handling.

The retry logic addresses the core issue described in the PR objectives where NFT operations fail due to parent coins not being activated. Key strengths:

  • Uses exponential backoff with 3 attempts, providing reasonable resilience
  • Properly catches and logs severe errors when all retries fail
  • The _repo.updateNft(chains) call likely includes the parent coin activation logic mentioned in the AI summary
  • Error logging includes both the exception and stack trace for debugging

This implementation ensures NFT updates are robust against transient failures while still proceeding with getNfts() even if updates fail completely.

Comment on lines +475 to +490
// Skip the deactivation step for now, as it results in "NoSuchCoin" errors
// when trying to re-enable the coin later in the same session.
// TODO: Revisit this and create an issue on KDF to track the problem.
// final deactivationTasks = [
// ...coins.map((coin) async {
// await _disableCoin(coin.id.id);
// if (notify) _broadcastAsset(coin.copyWith(state: CoinState.inactive));
// }),
// ...allChildCoins.map((child) async {
// await _disableCoin(child.id.id);
// if (notify) {
// _broadcastAsset(child.copyWith(state: CoinState.inactive));
// }
// }),
// ];
// await Future.wait(deactivationTasks);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Address the unused _disableCoin method and track the TODO.

The commented-out deactivation logic creates technical debt. The _disableCoin method is now unused (flagged by pipeline), and the TODO should be properly tracked.

Consider these actions:

  1. Remove the unused _disableCoin method since it's no longer called
  2. Create a proper issue to track the TODO comment about revisiting coin deactivation
  3. Add a reference to the created issue in the TODO comment

🏁 Script executed:

#!/bin/bash
# Verify that _disableCoin method is indeed unused throughout the codebase
rg -A 5 "_disableCoin" --type dart

Length of output: 1188


Remove unused deactivation logic and properly track the TODO

The private method _disableCoin is only referenced by the commented‐out block and is never invoked at runtime, and leaving both the dead code and the TODO in place creates unnecessary technical debt. Please:

  • In lib/bloc/coins_bloc/coins_repo.dart:
    • Remove the entire commented-out deactivation tasks block (around lines 475–490).
    • Delete the unused _disableCoin(String coinId) method definition (just below the commented block).
  • Create a new issue (e.g. KDF-XXXX) to investigate and resolve the “NoSuchCoin” errors when re-enabling coins in the same session.
  • Update the existing TODO comment to reference the newly created issue, for example:
    // TODO(KDF-XXXX): revisit coin deactivation and re-enable path
🤖 Prompt for AI Agents
In lib/bloc/coins_bloc/coins_repo.dart around lines 475 to 490, remove the
entire commented-out block containing the deactivation tasks since it is unused
and adds technical debt. Also delete the private method _disableCoin(String
coinId) defined just below this block as it is no longer called. Create a new
issue (e.g., KDF-XXXX) to track the “NoSuchCoin” errors when re-enabling coins,
and update the existing TODO comment to reference this issue with the format: //
TODO(KDF-XXXX): revisit coin deactivation and re-enable path.

@takenagain takenagain added this to the v0.9.2 Release milestone Jul 28, 2025
@takenagain takenagain marked this pull request as ready for review July 29, 2025 00:02
@takenagain takenagain requested review from CharlVS and smk762 July 29, 2025 00:04
@takenagain takenagain added the QA Ready for QA Testing label Jul 29, 2025
@smk762
Copy link
Copy Markdown
Collaborator

smk762 commented Jul 29, 2025

Init on a heavily spammed wallet took a few mins, but got there. Caught a stream of errors in console (brave) pretty much exactly when the NFTs became visible - but only briefly as then the tab crashed.

Console error log

main.dart.js:7031 Uncaught Error
at Object.f (main.dart.js:3877:20)
at DB.amz (main.dart.js:45566:9)
at DB.fD (main.dart.js:45561:13)
at a93.XW (main.dart.js_1.part.js:29441:22)
at aBD.cA (main.dart.js_1.part.js:29477:5)
at aBD.ds (main.dart.js:74070:33)
at aBF.cA (main.dart.js:78064:4)
at aBF.cA (main.dart.js:78150:6)
at aBF.ds (main.dart.js:74070:33)
at aBA.a7D (main.dart.js:78540:3)
cYR @ main.dart.js:7031
yA @ main.dart.js:7171
cKG @ main.dart.js:35082
$1 @ main.dart.js:129654
fX @ main.dart.js:10982
aiy @ main.dart.js:79444
aix @ main.dart.js:79446
asw @ main.dart.js:79430
aUZ @ main.dart.js:79402
(anonymous) @ main.dart.js:4030
AP @ main.dart.js:1249
$1 @ main.dart.js:40165
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
requestAnimationFrame
t1 @ main.dart.js:40148
t1 @ main.dart.js:79379
FH @ main.dart.js:79352
bgw @ main.dart.js:79522
(anonymous) @ main.dart.js:4031
aiy @ main.dart.js:79441
$2 @ main.dart.js:79483
aP @ main.dart.js:46655
hu @ main.dart.js:213
asr @ main.dart.js:79412
aUi @ main.dart.js:79398
(anonymous) @ main.dart.js:4031
AQ @ main.dart.js:1252
$1 @ main.dart.js:40162
cnB @ main.dart.js:5724
(anonymous) @ main.dart.js:133475
ut @ main.dart.js:48543
$1 @ main.dart.js:48583
d8V @ main.dart.js:8353
(anonymous) @ main.dart.js:8339
main.dart.js:7031 Uncaught Error
at EX.dW (main.dart.js:71659:9)
at bEE.$2 (main.dart.js:77131:23)
at vk.mS (main.dart.js:71559:5)
at a7u.eG (main.dart.js:77129:10)
at a7u.dW (main.dart.js:71659:21)
at bDT.$2 (main.dart.js:71719:25)
at vk.mS (main.dart.js:71559:5)
at EX.Di (main.dart.js:71708:6)
at EX.eG (main.dart.js:73168:21)
at EX.dW (main.dart.js:71659:21)

This was not replicated in chrome with a different seed, so it may be specific to the NFTs in wallet.
Upon further inspection, it may be due to failing requests to NFT images on IPFS?

Console error log

kdflib.js:1918 Uncaught Error: closure invoked recursively or after being dropped
at imports.wbg.__wbindgen_throw (kdflib.js:1918:15)
at kdflib_bg.wasm:0x152ac83
at kdflib_bg.wasm:0x1499c75
at __wbg_adapter_53 (kdflib.js:234:10)
at IDBTransaction.real (kdflib.js:207:20)
main.dart.js:8339 [Violation] 'requestAnimationFrame' handler took 129ms
main.dart.js:8339 [Violation] 'requestAnimationFrame' handler took 199ms
nfts:1 Access to XMLHttpRequest at 'https://bafybeigm4ihuwhxm5vptgqzkpr4vvewpwjbfscy3jsxg4rywuw3a57rzja.ipfs.nftstorage.link/' from origin 'https://walletrc--pull-3010-merge-zm0yuh3l.web.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
main.dart.js:68526
GET https://bafybeigm4ihuwhxm5vptgqzkpr4vvewpwjbfscy3jsxg4rywuw3a57rzja.ipfs.nftstorage.link/ net::ERR_FAILED 403 (Forbidden)
main.dart.js:36070 Error loading image: HTTP request failed, statusCode: 0, https://bafybeigm4ihuwhxm5vptgqzkpr4vvewpwjbfscy3jsxg4rywuw3a57rzja.ipfs.nftstorage.link/
main.dart.js:36070
main.dart.js:8339 [Violation] 'requestAnimationFrame' handler took 59ms
main.dart.js:36070 Error loading image: HTTP request failed, statusCode: 0, https://bafybeigm4ihuwhxm5vptgqzkpr4vvewpwjbfscy3jsxg4rywuw3a57rzja.ipfs.nftstorage.link/
main.dart.js:36070
nfts:1 Access to XMLHttpRequest at 'https://content.cryptotabnft.com/collections/positive-vibes/NFT_Positive-Vibes_03_1000px.png' from origin 'https://walletrc--pull-3010-merge-zm0yuh3l.web.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
main.dart.js:68526
GET https://content.cryptotabnft.com/collections/positive-vibes/NFT_Positive-Vibes_03_1000px.png net::ERR_FAILED 200 (OK)
main.dart.js:36070 Error loading image: HTTP request failed, statusCode: 0, https://content.cryptotabnft.com/collections/positive-vibes/NFT_Positive-Vibes_03_1000px.png

@smk762
Copy link
Copy Markdown
Collaborator

smk762 commented Jul 29, 2025

Confirmed that despite previously mentioned errors, NFT pages did load in app via web (chrome), desktop (linux) and mobile (android).

@smk762
Copy link
Copy Markdown
Collaborator

smk762 commented Jul 29, 2025

Related logs for same wallet running on linux desktop:

Error loading image: HTTP request failed, statusCode: 530, https://metadata.thesmurfssociety.com/ingredients/nft/17.Shooting_Star_Powder.jpg
#0      NetworkImage._loadAsync (package:flutter/src/painting/_network_image_io.dart:132:9)
<asynchronous suspension>
#1      MultiFrameImageStreamCompleter._handleCodecReady (package:flutter/src/painting/image_stream.dart:1027:3)
<asynchronous suspension>
Error loading image: HTTP request failed, statusCode: 530, https://metadata.thesmurfssociety.com/ingredients/nft/17.Shooting_Star_Powder.jpg
#0      NetworkImage._loadAsync (package:flutter/src/painting/_network_image_io.dart:132:9)
<asynchronous suspension>
#1      MultiFrameImageStreamCompleter._handleCodecReady (package:flutter/src/painting/image_stream.dart:1027:3)
<asynchronous suspension>
Error loading image: HTTP request failed, statusCode: 530, https://metadata.thesmurfssociety.com/ingredients/nft/17.Shooting_Star_Powder.jpg
#0      NetworkImage._loadAsync (package:flutter/src/painting/_network_image_io.dart:132:9)
<asynchronous suspension>
#1      MultiFrameImageStreamCompleter._handleCodecReady (package:flutter/src/painting/image_stream.dart:1027:3)
<asynchronous suspension>

@takenagain
Copy link
Copy Markdown
Contributor Author

@smk762 I split the image loading improvements into #3020 to avoid bloating and blocking this one. I merged dev into both, and this one into #3020.

The changes to the NFT image widget in #3020 are significant, so it might be safer to merge this PR and postpone the image loading improvements to the next release (assuming that the image loading errors are not significant enough to be a blocker).

@CharlVS CharlVS merged commit cdd3c32 into dev Jul 30, 2025
9 of 13 checks passed
@CharlVS CharlVS deleted the codex/add-function-to-activate-parent-coins-for-nfts branch July 30, 2025 18:09
smk762 pushed a commit that referenced this pull request Aug 1, 2025
* feat(nft): tolerate activation failures

* fix(nft): skip missing parents in firstWhere

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor(nft-main-repo): fix parent coin filter and use logging package

* fix(nft): don't return an error if there are no NFTs returned

* fix(nft): revert map-based error responses in favor of manual activation

* fix(skeleton-list-tile): add height constraint to fix renderflex assert

* fix(coin): temporarily skip calling deactivation RPC

circumvent "NoSuchCoin" error when re-enabling the coin in the same session.

* fix(activation): use more complete coin conversion function

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
smk762 pushed a commit that referenced this pull request Aug 1, 2025
* feat(nft): tolerate activation failures

* fix(nft): skip missing parents in firstWhere

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor(nft-main-repo): fix parent coin filter and use logging package

* fix(nft): don't return an error if there are no NFTs returned

* fix(nft): revert map-based error responses in favor of manual activation

* fix(skeleton-list-tile): add height constraint to fix renderflex assert

* fix(coin): temporarily skip calling deactivation RPC

circumvent "NoSuchCoin" error when re-enabling the coin in the same session.

* fix(activation): use more complete coin conversion function

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
smk762 pushed a commit that referenced this pull request Aug 1, 2025
* feat(nft): tolerate activation failures

* fix(nft): skip missing parents in firstWhere

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor(nft-main-repo): fix parent coin filter and use logging package

* fix(nft): don't return an error if there are no NFTs returned

* fix(nft): revert map-based error responses in favor of manual activation

* fix(skeleton-list-tile): add height constraint to fix renderflex assert

* fix(coin): temporarily skip calling deactivation RPC

circumvent "NoSuchCoin" error when re-enabling the coin in the same session.

* fix(activation): use more complete coin conversion function

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
smk762 pushed a commit that referenced this pull request Aug 1, 2025
* feat(nft): tolerate activation failures

* fix(nft): skip missing parents in firstWhere

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor(nft-main-repo): fix parent coin filter and use logging package

* fix(nft): don't return an error if there are no NFTs returned

* fix(nft): revert map-based error responses in favor of manual activation

* fix(skeleton-list-tile): add height constraint to fix renderflex assert

* fix(coin): temporarily skip calling deactivation RPC

circumvent "NoSuchCoin" error when re-enabling the coin in the same session.

* fix(activation): use more complete coin conversion function

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
smk762 pushed a commit that referenced this pull request Aug 1, 2025
* feat(nft): tolerate activation failures

* fix(nft): skip missing parents in firstWhere

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor(nft-main-repo): fix parent coin filter and use logging package

* fix(nft): don't return an error if there are no NFTs returned

* fix(nft): revert map-based error responses in favor of manual activation

* fix(skeleton-list-tile): add height constraint to fix renderflex assert

* fix(coin): temporarily skip calling deactivation RPC

circumvent "NoSuchCoin" error when re-enabling the coin in the same session.

* fix(activation): use more complete coin conversion function

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
smk762 pushed a commit that referenced this pull request Aug 8, 2025
* feat(nft): tolerate activation failures

* fix(nft): skip missing parents in firstWhere

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor(nft-main-repo): fix parent coin filter and use logging package

* fix(nft): don't return an error if there are no NFTs returned

* fix(nft): revert map-based error responses in favor of manual activation

* fix(skeleton-list-tile): add height constraint to fix renderflex assert

* fix(coin): temporarily skip calling deactivation RPC

circumvent "NoSuchCoin" error when re-enabling the coin in the same session.

* fix(activation): use more complete coin conversion function

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@coderabbitai coderabbitai bot mentioned this pull request Oct 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working codex QA Ready for QA Testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants