From 9209076956165a16e2c0ca695d7df03d2b6aad32 Mon Sep 17 00:00:00 2001 From: William Richter Date: Thu, 21 Aug 2025 16:33:10 +0200 Subject: [PATCH 01/18] chore(docs,ci): add AGENTS.md, local validation script, CI workflow, PR/issue templates; runtime overrides for Polkadot SDK alignment; composite build for local fearless-utils; README/CONTRIBUTING cross-links --- .github/ISSUE_TEMPLATE/bug_report.md | 38 ++++++++ .github/ISSUE_TEMPLATE/config.yml | 6 ++ .github/ISSUE_TEMPLATE/feature_request.md | 26 ++++++ .github/pull_request_template.md | 45 ++++++++++ .github/workflows/android-ci.yml | 65 ++++++++++++++ AGENTS.md | 65 ++++++++++++++ CONTRIBUTING.md | 2 + README.md | 38 +++++++- runtime/build.gradle | 19 ++-- scripts/validate-local.sh | 102 ++++++++++++++++++++++ settings.gradle | 12 +++ 11 files changed, 412 insertions(+), 6 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/android-ci.yml create mode 100644 AGENTS.md create mode 100644 scripts/validate-local.sh diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..c884d6c26a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Report a problem in Fearless Wallet Android +labels: bug +--- + +## Summary + +What happened? A clear, concise description. + +## App & Environment + +- App version (Settings → About): +- Install source (Play Store / APK / Android Studio): +- Device model and Android version: + +## Steps to Reproduce + +1. +2. +3. + +## Expected Behavior + +What you expected to happen. + +## Actual Behavior + +What actually happened (include messages, screenshots, or recordings if helpful). + +## Logs / Crash + +Attach logs or stack traces if available. + +## Additional Context + +Links, related issues, wallet/network, or account specifics (redact sensitive data). + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..1364932fd1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,6 @@ +blank_issues_enabled: false +contact_links: + - name: Community Support (Telegram) + url: https://t.me/fearlesshappiness + about: Ask general questions and get community help + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..798f9dae11 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,26 @@ +--- +name: Feature request +about: Suggest an idea or improvement for Fearless Wallet Android +labels: enhancement +--- + +## Problem / Motivation + +What problem does this solve? Why is it important? + +## Proposed Solution + +Describe the change. If you have mockups or sketches, attach them. + +## Alternatives Considered + +Other approaches you thought about. + +## Affected Areas + +Screens, modules, or flows this touches. + +## Additional Context + +Links, related issues, or prior art. + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000000..be8211e09b --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,45 @@ +## Summary + +Describe the change and why it’s needed. + +## Related Issue + +Closes # (or) Relates to # + +## Type of Change + +- [ ] feat (new feature) +- [ ] fix (bug fix) +- [ ] refactor (no functional change) +- [ ] chore/build (tooling, CI, deps) +- [ ] docs (README/AGENTS, comments) + +## Screenshots / Videos + +If UI changes, include before/after. + +## Test Plan + +Commands run locally: + +``` +./gradlew detektAll +./gradlew runTest +./gradlew :app:lint +``` + +Additional checks and scenarios covered: +- + +## Risks & Rollout + +Potential impact, migrations, or config/secrets required. + +## Checklist + +- [ ] Linked an issue and added a clear description +- [ ] Added/updated tests for changed code (where applicable) +- [ ] Updated docs (README/AGENTS) when behavior or commands changed +- [ ] Ran detektAll, runTest, and :app:lint locally (or via CI) +- [ ] No secrets or local.properties committed + diff --git a/.github/workflows/android-ci.yml b/.github/workflows/android-ci.yml new file mode 100644 index 0000000000..99f5dbc69e --- /dev/null +++ b/.github/workflows/android-ci.yml @@ -0,0 +1,65 @@ +name: Android CI + +on: + pull_request: + push: + branches: [ main, develop ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-and-test: + runs-on: ubuntu-latest + timeout-minutes: 45 + env: + CI: true + # Provide safe stubs to avoid repository/config failures during resolution + PAY_WINGS_REPOSITORY_URL: https://maven.google.com + PAY_WINGS_USERNAME: "" + PAY_WINGS_PASSWORD: "" + MOONPAY_TEST_SECRET: stub + MOONPAY_PRODUCTION_SECRET: stub + FL_BLAST_API_ETHEREUM_KEY: stub + FL_BLAST_API_BSC_KEY: stub + FL_BLAST_API_SEPOLIA_KEY: stub + FL_BLAST_API_GOERLI_KEY: stub + FL_BLAST_API_POLYGON_KEY: stub + FL_ANDROID_ETHERSCAN_API_KEY: stub + FL_ANDROID_BSCSCAN_API_KEY: stub + FL_ANDROID_POLYGONSCAN_API_KEY: stub + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Java 21 (Temurin) + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '21' + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + with: + packages: | + platforms;android-35 + build-tools;35.0.0 + platform-tools + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 + + - name: Gradle version + run: ./gradlew --version --no-daemon --console=plain + + - name: Static analysis (detekt) + run: ./gradlew detektAll --no-daemon --console=plain + + - name: Unit tests + coverage + run: ./gradlew runTest --no-daemon --console=plain + + - name: Android Lint (app) + run: ./gradlew :app:lint --no-daemon --console=plain + diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..34515673f0 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,65 @@ +# Repository Guidelines + + +> **About this codebase** +> This repository contains the codebase for a cryptocurrency wallet compatible with the **Polkadot**, **EVM**, and **TON** ecosystems. +> It uses dependencies available in the [soramitsu/fearless-utils-Android](https://github.com/soramitsu/fearless-utils-Android) repository and has an iOS equivalent in [soramitsu/fearless-iOS](https://github.com/soramitsu/fearless-iOS). + + + +[![Android CI](https://github.com/soramitsu/fearless-Android/actions/workflows/android-ci.yml/badge.svg)](https://github.com/soramitsu/fearless-Android/actions/workflows/android-ci.yml) + +## Project Structure & Modules +- `app/`: Android app entry; build types `debug/release/staging/develop/pr`. +- `feature-*/`: Split by domain with `-api` and `-impl` modules (e.g., `feature-wallet-api`, `feature-wallet-impl`). +- `core-api/`, `core-db/`, `runtime/`, `runtime-permission/`, `common/`: Shared foundations. +- `test-shared/`: Test-only utilities reused across modules. +- `buildSrc/`, `detekt/`, `scripts/`, `docs/`: Gradle plugins/config, static analysis, helper scripts, documentation. +- Per-module sources: `src/main/java|kotlin`, resources `src/main/res`, unit tests `src/test`, instrumentation tests `src/androidTest`. + +## Build, Test, and Dev Commands +- Build app (APK): `./gradlew :app:assembleDebug` (use `assembleRelease` for release). +- Full build + checks: `./gradlew clean build`. +- Static analysis: `./gradlew detektAll` (auto-fix formatting: `./gradlew detektFormat`). +- Unit tests (aggregated): `./gradlew runTest` (runs detekt, unit tests, JaCoCo report). +- Per-module unit tests: `./gradlew :core-db:testDebugUnitTest` (or `testDevelopDebugUnitTest` if present). +- Android Lint: `./gradlew :app:lint`. +- Coverage report: `./gradlew jacocoTestReport` (outputs under each module’s `build/reports/jacoco`). +- App version: `./gradlew :app:printVersion`. +- Local validation helper: `bash scripts/validate-local.sh`. + +## Coding Style & Naming +- Language: Kotlin 2.1, Java 21 target; Compose enabled where applicable. +- Formatting: Detekt + detekt-formatting; 4-space indent; max line length per `detekt/detekt.yml`. +- Files: one public class per file; filename matches class (`PascalCase`). +- Packages: lowercase dot-separated; avoid acronyms. +- Resources: layouts `activity_*.xml`, `fragment_*.xml`; ids `btnX`, `tvX`; strings `feature_action_label`. +- KDoc for public APIs; prefer immutable data and explicit visibility. + +## Testing Guidelines +- Frameworks: JUnit4, AndroidX Test, Room testing, Coroutines test; Mockito/MockK available. +- Structure: unit tests in `src/test`, instrumentation in `src/androidTest`. +- Naming: mirror class under test, e.g., `AccountRepositoryTest.kt`; methods `fun shouldDoX_whenY()`. +- Run: module `testDebugUnitTest` (or `testDevelopDebugUnitTest`), or root `runTest`. +- Coverage: maintain/raise JaCoCo coverage for changed code. + +## Commit & Pull Requests +- Commits: imperative, concise subject; reference issues (`#123`). Prefer Conventional Commits (`feat:`, `fix:`, `refactor:`) when possible. +- Before PR: ensure `./gradlew runTest` passes and `detektAll` is clean. +- PR checklist: clear description, linked issue, screenshots/video for UI, steps to test, notes on config/secrets. + - Use the PR template; CI must be green (Android CI badge above). + +## Security & Configuration +- Secrets are read via `scripts/secrets.gradle`; set in env vars or `local.properties` (see `README.md`). +- Do not commit keys or `local.properties`. Use the provided debug keystore only for local builds. +- Polkadot runtime sources: to align with a specific Polkadot SDK release (e.g., `polkadot-stable2503`), you can override chain/type registries without code changes: + - `TYPES_URL_OVERRIDE`, `DEFAULT_V13_TYPES_URL_OVERRIDE`, `CHAINS_URL_OVERRIDE` + - Example in `local.properties`: + - `TYPES_URL_OVERRIDE=https://.../all_chains_types_android.json` + - `CHAINS_URL_OVERRIDE=https://.../chains.json` + - After updating, run `./gradlew detektAll runTest :app:lint`. + +## Local Utils (fearless-utils-Android) +- To develop against a local utils checkout, set `FEARLESS_UTILS_PATH` or place it at `/Users/williamrichter/Git/fearless-utils-Android`. +- The build auto-includes it as a composite build and substitutes `jp.co.soramitsu.fearless-utils:fearless-utils` with the local project. +- This helps test against utils changes required by specific Polkadot SDK releases. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9ee7b7b254..c409ea18e5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,6 +3,8 @@ Welcome to Android repository of Fearless Wallet application. If you would like to help us to make the best wallet in Polkadot/Kusama ecosystem, please find appropriate section which describes how you can help us. +For developer setup, module structure, commands, and coding conventions, see the Contributor Guide in [AGENTS.md](AGENTS.md). It complements this document with practical instructions for building, testing, and submitting PRs. + ### 🐞 Reporting bugs In case you have found any issues with an existing app, feel free to report it directly to [Issues board](https://github.com/soramitsu/fearless-Android/issues). In your report please mention following data: diff --git a/README.md b/README.md index 8cabeee351..731e62ab29 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ### Fearless Wallet Android -[![Google Play](https://img.shields.io/badge/Google%20Play-Android-green?logo=google%20play)](https://play.google.com/store/apps/details?id=jp.co.soramitsu.fearless) +[![Google Play](https://img.shields.io/badge/Google%20Play-Android-green?logo=google%20play)](https://play.google.com/store/apps/details?id=jp.co.soramitsu.fearless) [![Android CI](https://github.com/soramitsu/fearless-Android/actions/workflows/android-ci.yml/badge.svg)](https://github.com/soramitsu/fearless-Android/actions/workflows/android-ci.yml) ![logo](/docs/fearlesswallet_promo.png) @@ -85,5 +85,41 @@ FL_ANDROID_BSCSCAN_API_KEY FL_ANDROID_POLYGONSCAN_API_KEY ```` +## Local Validation + +Run static analysis, unit tests, lint, and set up Android SDK packages: + +``` +bash scripts/validate-local.sh +``` + +Manual equivalents if you prefer: + +``` +./gradlew detektAll +./gradlew runTest +./gradlew :app:lint +``` + +Prerequisites: JDK 21 (Temurin/Adoptium) and Android SDK with API 35 + build-tools 35.0.0. The script will try to locate `ANDROID_SDK_ROOT` and install missing packages if `sdkmanager` is available. + +### Use a local fearless-utils-Android + +If you have a local checkout of `fearless-utils-Android`, the build can use it via a composite build. + +``` +export FEARLESS_UTILS_PATH=/absolute/path/to/fearless-utils-Android +./gradlew :app:assembleDebug +``` + +When set, Gradle substitutes the binary dependency `jp.co.soramitsu.fearless-utils:fearless-utils` with the local project. + +Prereqs for local utils build: NDK (25.2.9519653) and Rust toolchain available on PATH (`rustup`, `cargo`). + +## Contributing + +- Contributor Guide: see [AGENTS.md](AGENTS.md) for project layout, commands, and conventions. +- Process & community details: see [CONTRIBUTING.md](CONTRIBUTING.md). + ## License Fearless Wallet Android is available under the Apache 2.0 license. See the LICENSE file for more info. diff --git a/runtime/build.gradle b/runtime/build.gradle index f909b4f428..6dc45cea0b 100644 --- a/runtime/build.gradle +++ b/runtime/build.gradle @@ -12,17 +12,26 @@ android { targetSdkVersion rootProject.targetSdkVersion testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - buildConfigField "String", "TYPES_URL", "\"https://raw.githubusercontent.com/soramitsu/shared-features-utils/master/chains/all_chains_types_android.json\"" - buildConfigField("String", "DEFAULT_V13_TYPES_URL", "\"https://raw.githubusercontent.com/soramitsu/shared-features-utils/master/chains/default_v13_types.json\"") + // Allow overriding runtime/type sources to align with specific Polkadot SDK releases + def TYPES_URL_DEFAULT = "https://raw.githubusercontent.com/soramitsu/shared-features-utils/master/chains/all_chains_types_android.json" + def DEFAULT_V13_TYPES_URL_DEFAULT = "https://raw.githubusercontent.com/soramitsu/shared-features-utils/master/chains/default_v13_types.json" + def typesUrl = readSecret("TYPES_URL_OVERRIDE") ?: TYPES_URL_DEFAULT + def defaultV13TypesUrl = readSecret("DEFAULT_V13_TYPES_URL_OVERRIDE") ?: DEFAULT_V13_TYPES_URL_DEFAULT + buildConfigField "String", "TYPES_URL", "\"${typesUrl}\"" + buildConfigField "String", "DEFAULT_V13_TYPES_URL", "\"${defaultV13TypesUrl}\"" } buildTypes { debug { - buildConfigField "String", "CHAINS_URL", "\"https://raw.githubusercontent.com/soramitsu/shared-features-utils/develop-free/chains/v13/chains_dev_prod.json\"" + def CHAINS_URL_DEBUG_DEFAULT = "https://raw.githubusercontent.com/soramitsu/shared-features-utils/develop-free/chains/v13/chains_dev_prod.json" + def chainsUrlDebug = readSecret("CHAINS_URL_DEBUG_OVERRIDE") ?: (readSecret("CHAINS_URL_OVERRIDE") ?: CHAINS_URL_DEBUG_DEFAULT) + buildConfigField "String", "CHAINS_URL", "\"${chainsUrlDebug}\"" } release { - buildConfigField "String", "CHAINS_URL", "\"https://raw.githubusercontent.com/soramitsu/shared-features-utils/master/chains/v13/chains.json\"" + def CHAINS_URL_RELEASE_DEFAULT = "https://raw.githubusercontent.com/soramitsu/shared-features-utils/master/chains/v13/chains.json" + def chainsUrlRelease = readSecret("CHAINS_URL_RELEASE_OVERRIDE") ?: (readSecret("CHAINS_URL_OVERRIDE") ?: CHAINS_URL_RELEASE_DEFAULT) + buildConfigField "String", "CHAINS_URL", "\"${chainsUrlRelease}\"" } } @@ -77,4 +86,4 @@ dependencies { implementation libs.web3jDep implementation libs.bundles.ton -} \ No newline at end of file +} diff --git a/scripts/validate-local.sh b/scripts/validate-local.sh new file mode 100644 index 0000000000..b44e31fbba --- /dev/null +++ b/scripts/validate-local.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +set -euo pipefail + +REQUIRED_JAVA=21 +REQUIRED_API=35 +REQUIRED_BUILD_TOOLS=35.0.0 + +log() { echo -e "[validate] $*"; } +warn() { echo -e "[validate][warn] $*" >&2; } +err() { echo -e "[validate][error] $*" >&2; } + +detect_java_major() { + if ! command -v java >/dev/null 2>&1; then + echo ""; return 0 + fi + local v + v=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}') + echo "${v%%.*}" +} + +ensure_java() { + local major + major=$(detect_java_major) + if [[ -z "$major" ]]; then + warn "Java not found. Install Temurin/Adoptium JDK ${REQUIRED_JAVA}." + warn "macOS: brew install --cask temurin@${REQUIRED_JAVA}" + warn "Linux: https://adoptium.net/ or SDKMAN: sdk install java ${REQUIRED_JAVA}" + return 1 + fi + if (( major < REQUIRED_JAVA )); then + err "Java ${REQUIRED_JAVA}+ required, found ${major}. Update your JDK." + return 1 + fi + log "Java OK (version $(java -version 2>&1 | head -n1))." +} + +ensure_android_sdk() { + if [[ -z "${ANDROID_SDK_ROOT:-}" ]]; then + # Try common locations + local candidates=("$HOME/Library/Android/sdk" "$HOME/Android/Sdk") + for d in "${candidates[@]}"; do + if [[ -d "$d" ]]; then export ANDROID_SDK_ROOT="$d"; break; fi + done + fi + if [[ -z "${ANDROID_SDK_ROOT:-}" || ! -d "$ANDROID_SDK_ROOT" ]]; then + warn "ANDROID_SDK_ROOT not set. Install Android SDK (commandline-tools) and set ANDROID_SDK_ROOT." + warn "Docs: https://developer.android.com/studio#command-tools" + return 1 + fi + log "Using ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT" +} + +find_sdkmanager() { + if command -v sdkmanager >/dev/null 2>&1; then echo "$(command -v sdkmanager)"; return; fi + local paths=( + "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" + "$ANDROID_SDK_ROOT/cmdline-tools/bin/sdkmanager" + "$ANDROID_SDK_ROOT/tools/bin/sdkmanager" + ) + for p in "${paths[@]}"; do + [[ -x "$p" ]] && { echo "$p"; return; } + done + echo "" +} + +prepare_android_packages() { + local sm + sm=$(find_sdkmanager || true) + if [[ -z "$sm" ]]; then + warn "sdkmanager not found. Ensure Android commandline-tools are installed under ANDROID_SDK_ROOT." + return 1 + fi + log "Accepting licenses (if any)…" + yes | "$sm" --licenses >/dev/null || true + log "Ensuring required SDK packages (platforms;android-${REQUIRED_API}, build-tools;${REQUIRED_BUILD_TOOLS}, platform-tools)…" + "$sm" --install "platforms;android-${REQUIRED_API}" "build-tools;${REQUIRED_BUILD_TOOLS}" "platform-tools" +} + +run_gradle_tasks() { + if [[ ! -x "./gradlew" ]]; then + err "Gradle wrapper not found. Run from repo root."; return 1 + fi + log "Gradle version…" + ./gradlew --version --no-daemon --console=plain || true + log "Running detektAll…" + ./gradlew detektAll --no-daemon --console=plain + log "Running unit tests + coverage (runTest)…" + ./gradlew runTest --no-daemon --console=plain + log "Running Android Lint (app)…" + ./gradlew :app:lint --no-daemon --console=plain + log "Done. Coverage reports under */build/reports/jacoco and HTML in */build/reports/tests." +} + +main() { + ensure_java || exit 1 + ensure_android_sdk || warn "SDK not fully configured; continuing if tasks do not require it." + prepare_android_packages || warn "Could not ensure SDK packages; unit tests may still run." + run_gradle_tasks +} + +main "$@" + diff --git a/settings.gradle b/settings.gradle index ab39949612..b8cdf17a8d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -30,3 +30,15 @@ include ':feature-nft-api' include ':feature-nft-impl' include ':feature-liquiditypools-api' include ':feature-liquiditypools-impl' + +// Optionally include a local fearless-utils-Android checkout for composite build +def localUtilsPath = System.getenv("FEARLESS_UTILS_PATH") ?: "/Users/williamrichter/Git/fearless-utils-Android" +def localUtilsDir = new File(localUtilsPath) +if (localUtilsDir.exists()) { + println("Including local fearless-utils from: ${localUtilsDir}") + includeBuild(localUtilsDir) { + dependencySubstitution { + substitute module("jp.co.soramitsu.fearless-utils:fearless-utils") using project(":fearless-utils") + } + } +} From 8d55cd4ed01f2d3813d96ab829fff31f0cbc69b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AD=A6=E5=AE=AE=E8=AA=A0?= Date: Fri, 22 Aug 2025 18:32:57 +0400 Subject: [PATCH 02/18] update docs --- README.md | 7 + app/AGENTS.md | 40 ++++ app/src/main/java/jp/co/soramitsu/app/App.kt | 18 +- common/AGENTS.md | 27 +++ core-db/AGENTS.md | 32 +++ docs/ARCHITECTURE.md | 54 ++++++ docs/CURRENT_STATE.md | 53 +++++ docs/MODULES.md | 35 ++++ docs/roadmap.md | 183 ++++++++++++++++++ docs/status.md | 71 +++++++ feature-account-impl/AGENTS.md | 30 +++ feature-wallet-impl/AGENTS.md | 35 ++++ runtime/AGENTS.md | 33 ++++ .../runtime/multiNetwork/ChainRegistry.kt | 32 ++- .../EthereumEnvironmentConfigurator.kt | 5 +- 15 files changed, 649 insertions(+), 6 deletions(-) create mode 100644 app/AGENTS.md create mode 100644 common/AGENTS.md create mode 100644 core-db/AGENTS.md create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/CURRENT_STATE.md create mode 100644 docs/MODULES.md create mode 100644 docs/roadmap.md create mode 100644 docs/status.md create mode 100644 feature-account-impl/AGENTS.md create mode 100644 feature-wallet-impl/AGENTS.md create mode 100644 runtime/AGENTS.md diff --git a/README.md b/README.md index 731e62ab29..0b069bb16c 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,13 @@ Fearless Wallet roadmap is available for everyone: [roadmap link](https://sorami ## Dev Status Track features development: [board link](https://soramitsucoltd.aha.io/shared/343e5db57d53398e3f26d0048158c4a2) +## Architecture & Current State +- Architecture overview: see `docs/ARCHITECTURE.md` for module layout, layers, and flows. +- Module map: see `docs/MODULES.md` for a quick feature-by-feature guide. +- Current state: see `docs/CURRENT_STATE.md` for supported ecosystems, integrations, and TODO hotspots. + - Status snapshot: see `docs/status.md` for health, risks, and what’s incomplete. + - Roadmap: see `docs/roadmap.md` for prioritized, actionable tasks. + ## How to build To build Fearless Wallet Android project, you need to provide several keys either in environment variables or in `local.properties` file: diff --git a/app/AGENTS.md b/app/AGENTS.md new file mode 100644 index 0000000000..a590a13949 --- /dev/null +++ b/app/AGENTS.md @@ -0,0 +1,40 @@ +# AGENTS Guide: app + +Purpose +- Hosts the Android application entry point, wiring DI and navigation. +- Depends on feature `-api` and `-impl` modules and ties them together. + +Key Entry Points +- `jp.co.soramitsu.app.App` — Hilt bootstrap, locale, OptionsProvider, WalletConnect v2 init. +- `jp.co.soramitsu.app.root.presentation.RootActivity` — NavHost container, app-level navigation. +- `app/src/main/res/navigation/*.xml` — `main_nav_graph.xml`, `root_nav_graph.xml`, `onboarding_nav_graph.xml`, `bottom_nav_graph.xml`. +- Root ViewModels & routers under `app/src/main/java/jp/co/soramitsu/app/root/presentation/*`. + +Build Types +- `debug`, `release`, `staging`, `develop`, `pr`. +- R8/shrinker toggled for remote builds; Firebase App Distribution configured on CI branches. + +Configs & Secrets (see README for details) +- WalletConnect: `WALLET_CONNECT_PROJECT_ID` in `BuildConfig`. +- Moonpay: `MOONPAY_TEST_SECRET`, `MOONPAY_PRODUCTION_SECRET`. +- EVM/API keys: `FL_BLAST_API_*`, `FL_ANDROID_*SCAN_API_KEY`. +- SoraCard & X1: multiple Gradle properties required (test/prod creds). + +Common Tasks +- Add a new feature screen: + 1) Add destination to an appropriate nav graph. + 2) Inject feature router (from `feature-*-api`) into `RootActivity`/host fragment. + 3) Wire ViewModel with Hilt in the feature `-impl` module. +- Add a feature module dependency: Update `app/build.gradle` to include `:feature-xyz-api` and `:feature-xyz-impl`. +- Adjust app metadata for WalletConnect: Update the AppMetaData fields in `App.setupWalletConnect()`. + +Run, Lint, Test +- Build debug: `./gradlew :app:assembleDebug` +- Lint: `./gradlew :app:lint` +- Full checks: `./gradlew detektAll runTest` + +Troubleshooting +- WalletConnect init errors: verify `WALLET_CONNECT_PROJECT_ID` and network reachability. +- Missing features at runtime: ensure `matchingFallbacks` and proper build type are used. +- Local utils: set `FEARLESS_UTILS_PATH` to include local `fearless-utils-Android` in the composite build. + diff --git a/app/src/main/java/jp/co/soramitsu/app/App.kt b/app/src/main/java/jp/co/soramitsu/app/App.kt index 7296fd37d3..b2111c4e1d 100644 --- a/app/src/main/java/jp/co/soramitsu/app/App.kt +++ b/app/src/main/java/jp/co/soramitsu/app/App.kt @@ -14,6 +14,14 @@ import jp.co.soramitsu.common.data.network.OptionsProvider import jp.co.soramitsu.common.resources.ContextManager import jp.co.soramitsu.common.resources.LanguagesHolder +/** + * Application entry point. + * + * - Boots Hilt DI via `@HiltAndroidApp`. + * - Applies current locale using `ContextManager` and `LanguagesHolder`. + * - Publishes build metadata (version, build type) through `OptionsProvider`. + * - Initializes WalletConnect v2 (Reown SDK) for dApp connections. + */ @HiltAndroidApp open class App : Application() { @@ -38,9 +46,17 @@ open class App : Application() { OptionsProvider.CURRENT_VERSION_NAME = BuildConfig.VERSION_NAME OptionsProvider.CURRENT_BUILD_TYPE = BuildConfig.BUILD_TYPE + // WalletConnect v2 setup (requires BuildConfig.WALLET_CONNECT_PROJECT_ID) setupWalletConnect() } + /** + * Configure the WalletConnect v2 client. + * + * Uses the Reown SDK with `AUTOMATIC` connection type and the project ID from + * BuildConfig (`WALLET_CONNECT_PROJECT_ID`). When changing the relay or metadata + * fields (name, description, icons), ensure they match Brand/App Store guidelines. + */ private fun setupWalletConnect() { val connectionType = ConnectionType.AUTOMATIC // ConnectionType.AUTOMATIC or ConnectionType.MANUAL val projectId = BuildConfig.WALLET_CONNECT_PROJECT_ID // Project ID at https://cloud.walletconnect.com/ @@ -68,7 +84,7 @@ open class App : Application() { val initParams = Wallet.Params.Init(core = CoreClient) WalletKit.initialize(initParams) { error -> - // Error will be thrown if there's an issue during initialization + // Will log exceptions if initialization fails (e.g., invalid project ID, network issues) error.throwable.printStackTrace() } } diff --git a/common/AGENTS.md b/common/AGENTS.md new file mode 100644 index 0000000000..6efc3c2685 --- /dev/null +++ b/common/AGENTS.md @@ -0,0 +1,27 @@ +# AGENTS Guide: common + +Purpose +- Shared UI base classes, error handling, utilities, and small domain helpers reused across features. + +Key Areas +- Base UI: `base/*` (e.g., `BaseFragment`, `BaseComposeFragment`, `BaseViewModel`). +- Errors: `base/errors/*` including `FearlessException`, `ValidationException`, `TitledException`. +- Validation: `validation/*` (`Validation`, `ValidationExecutor`). +- Storage/Encryption: `data/storage/*` with `EncryptedPreferences` and `PreferencesImpl`. +- Utilities: `utils/*` (e.g., `Base58Ext`, `TonUtils`, coroutines helpers), QR scanning in `qrScanner/*`. + +Common Tasks +- Add a reusable bottom sheet or view: place in `view/*` and keep dependencies minimal. +- Add a validation: define a `Validation` and wire with `ValidationExecutor` in ViewModels. +- Add a utility: prefer extension functions; keep platform-specific code isolated. + +Known TODOs/Tech Debt +- `base/errors/FearlessException.kt`: replace TODOs with localized string resources. +- `data/storage/PreferencesImpl.kt`: note about listener GC — consider rework. +- `data/network/rpc/SocketSingleRequestExecutor.kt`: marked unused; confirm and remove if truly dead. +- `utils/Base58Ext.kt`: consider moving Base58 to `fearless-utils`. + +Tests & Checks +- Use `:test-shared` utilities where applicable. +- Run: `./gradlew :common:testDebugUnitTest` and `./gradlew detektAll`. + diff --git a/core-db/AGENTS.md b/core-db/AGENTS.md new file mode 100644 index 0000000000..84dce7ee2d --- /dev/null +++ b/core-db/AGENTS.md @@ -0,0 +1,32 @@ +# AGENTS Guide: core-db + +Purpose +- Central Room database with entities, DAOs, and migrations for chains, assets, accounts, operations, and integrations. + +Key Files +- `AppDatabase.kt` — database definition, versioning, and type converters. +- Entities: `model/*` and `model/chain/*` (e.g., `ChainLocal`, `ChainAssetLocal`, `MetaAccountLocal`). +- DAOs: `dao/*` (e.g., `ChainDao`, `AssetDao`, `MetaAccountDao`). +- Migrations: `migrations/*` with helpers for version-to-version upgrades. +- Schemas: `schemas/` for Room schema snapshots (used by migration tests). + +Common Tasks +- Add a table/column: + 1) Add/update entity model(s) with Room annotations. + 2) Increment DB version in `AppDatabase`. + 3) Add a migration under `migrations/` and wire it in `Migrations.kt`. + 4) Update DAOs. + 5) Write a migration test. + +Migration Testing +- Pattern: use Room’s auto-migration/migration test harness. +- Run: `./gradlew :core-db:testDebugUnitTest`. + +Integration +- `runtime` consumes `ChainDao` for chain info, nodes, and sync decisions. +- Feature modules query/update asset/account data via DAOs. + +Notes +- Keep converters focused; large JSON fields should be carefully versioned. +- Ensure `@Transaction` is used for multi-DAO updates where consistency matters. + diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000000..f68a05b48e --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,54 @@ +# Architecture Overview + +This document explains how the Android app is structured, how modules interact, and where to look when making changes. + +## Layers & Composition +- UI & Navigation: Lives in `app/` and `feature-*/impl` modules. UI uses Android Views and Jetpack Compose where applicable. Navigation is driven via `NavHost` graphs under `app/src/main/res/navigation` and `RootActivity` (`jp.co.soramitsu.app.root.presentation.RootActivity`). +- Features: Each feature has a pair of modules: `feature--api` (interfaces, contracts, lightweight models) and `feature--impl` (DI wiring, repositories, interactors, ViewModels, UI). The `app` module depends on feature `-api` and `-impl` modules. +- Shared Foundations: + - `common/`: UI base classes, utilities, error handling, QR scanning, small domain helpers. + - `core-api/`: Core interfaces and models used across features (runtime config, storage abstractions). + - `core-db/`: Room database, DAOs, entities, and migrations. + - `runtime/`: Chain metadata, connections, runtime files, and multi-ecosystem (Substrate/EVM/TON) integration. + - `runtime-permission/`: Lightweight runtime permissions helper library. + - `test-shared/`: Test utilities reused by multiple modules. + +## Dependency Injection +- DI is powered by Hilt. The `App` class (`jp.co.soramitsu.app.App`) is annotated with `@HiltAndroidApp` and bootstraps DI. +- Feature `-impl` modules usually declare Hilt modules/components for their screens and interactors. + +## Navigation +- Entry point: `RootActivity` and `main_nav_graph.xml` (plus `root_nav_graph.xml`, `onboarding_nav_graph.xml`, `bottom_nav_graph.xml`). +- Features expose routers or navigator interfaces from their `-api` modules to decouple navigation from implementations. + +## Data Flow & Persistence +- Storage: `core-db` hosts the Room database (`AppDatabase`) with DAOs like `AssetDao`, `ChainDao`, `MetaAccountDao`, etc. Migrations are under `core-db/src/main/java/.../migrations`. +- Networking & Chain Runtime: `runtime` manages chain metadata and connections: + - `ChainRegistry` coordinates runtime providers, subscriptions, and connections per chain. + - Connection pools for Substrate and EVM (`ConnectionPool`, `EthereumConnectionPool`). + - TON utilities and contracts are available under `runtime/.../chain/ton`. + - Local metadata/type files are under `runtime/src/main/assets` and can be overridden via properties (see AGENTS.md / README for overrides). + +## Ecosystems +- Substrate/Polkadot: Runtime metadata, types, and websocket connections managed under `runtime`. +- EVM (Ethereum, BSC, Polygon, etc.): EVM chains are configured via `EthereumEnvironmentConfigurator` and managed in `EthereumConnectionPool`. +- TON: Supported via TON-specific remote sources, contracts, and DB tables. + +## External Integrations +- WalletConnect v2: Initialized in `App.setupWalletConnect()` using the Reown WalletConnect SDK. Project ID set via `BuildConfig.WALLET_CONNECT_PROJECT_ID`. +- TON Connect: Dedicated feature modules `feature-tonconnect-api` and `feature-tonconnect-impl` with persistence in `core-db` (`TonConnectDao`). +- Sora Card: `feature-soracard-*` modules; requires credentials via Gradle properties. + +## Build Types & Tooling +- Build types: `debug`, `release`, `staging`, `develop`, `pr`. R8/shrinker is enabled on remote builds for closer prod parity. +- Static analysis: Detekt (`./gradlew detektAll`) with formatting (`detektFormat`). +- Unit tests: `./gradlew runTest` aggregates checks and test reports. +- Local utils development: `settings.gradle` includes a composite build for a local `fearless-utils-Android` checkout via `FEARLESS_UTILS_PATH`. + +## Where To Start +- App lifecycle and global initialization: `app/src/main/java/jp/co/soramitsu/app/App.kt`. +- Navigation: `app/src/main/res/navigation/*` and `RootActivity`. +- Chains and connections: `runtime/multiNetwork/*` and `core-db` chain entities. +- Wallet features (send/receive/history): `feature-wallet-api` and `feature-wallet-impl`. +- Accounts/onboarding: `feature-account-*`, `feature-onboarding-*`. + diff --git a/docs/CURRENT_STATE.md b/docs/CURRENT_STATE.md new file mode 100644 index 0000000000..35d32f6d26 --- /dev/null +++ b/docs/CURRENT_STATE.md @@ -0,0 +1,53 @@ +# Current State + +This document summarizes the current state of the codebase as observed in this repository. It is meant to help new contributors orient quickly. + +## Supported Ecosystems +- Substrate/Polkadot: Present via `runtime` (metadata, types, connections) and used across wallet, staking, and crowdloan features. +- EVM (Ethereum-compatible): Present via `runtime` (`EthereumConnectionPool`) and environment configurator; history providers and API keys are configurable via Gradle properties. +- TON: Present via `runtime` TON utilities and `core-db` tables; TON Connect flows live in dedicated feature modules. + +## Key Features Present +- Wallet (send/receive/manage assets/history): `feature-wallet-api` and `feature-wallet-impl`. +- Account & Onboarding: `feature-account-*`, `feature-onboarding-*`. +- Staking & Crowdloans: `feature-staking-*`, `feature-crowdloan-*` (Substrate-centric). +- Swaps & Pools: `feature-polkaswap-*`, `feature-liquiditypools-*`. +- NFTs: `feature-nft-*`. +- Connectors: `feature-walletconnect-*` (WalletConnect v2), `feature-tonconnect-*` (TON Connect). +- Sora Card: `feature-soracard-*` (requires credentials via Gradle properties; see README). + +These features vary in maturity; consult TODOs below and module code for specifics. + +## Global Initialization +- `App` (`jp.co.soramitsu.app.App`) configures language/locale, sets `OptionsProvider` (build info), and initializes WalletConnect v2. +- BuildConfig fields provide IDs/secrets required by external integrations (e.g., WalletConnect project ID). + +## Configuration & Secrets +- Place integration keys in environment variables or `local.properties` as described in README. +- Common keys include Moonpay, Ethereum blast API keys, and Etherscan/Polygonscan keys. +- Sora Card requires repository credentials and API keys; see README. + +## Build Types +- `debug`, `release`, `staging`, `develop`, `pr` — see `app/build.gradle` for differences (R8/shrinker, suffixes, Firebase App Distribution setup on CI builds). + +## Runtime Types & Chains +- Default types and chain metadata are embedded under `runtime/src/main/assets`. +- You can override types/chains with `TYPES_URL_OVERRIDE`, `DEFAULT_V13_TYPES_URL_OVERRIDE`, and `CHAINS_URL_OVERRIDE` properties (see AGENTS.md/README). + +## Known TODO/FIXME Hotspots +Ripgrep shows TODO/FIXME markers in these areas (non-exhaustive): +- Account models and meta-account adoption +- NFT details screen placeholders +- Sora Card details screen placeholders +- Crowdloan interactors (Karura) TODO marker +- Error text TODOs (`FearlessException`) +- Substrate balance loader hardcoded defaults +- Staking validator oversubscription/slashed logic FIXME + +These markers indicate areas where behavior may be incomplete or needs refinement. Use `rg -n "TODO|FIXME"` to explore further. + +## What To Verify Locally +- Secrets and endpoints present: Without keys, some flows (Moonpay, history providers) won’t fully function. +- Local utils integration: If you maintain `fearless-utils-Android`, set `FEARLESS_UTILS_PATH` to verify against local changes. +- Android SDK/NDK and JDK versions: See README and `scripts/validate-local.sh`. + diff --git a/docs/MODULES.md b/docs/MODULES.md new file mode 100644 index 0000000000..2fcc9c896a --- /dev/null +++ b/docs/MODULES.md @@ -0,0 +1,35 @@ +# Module Map + +Short descriptions of modules to speed up discovery. + +## App & Foundations +- `app/`: Android application module. Wires features, sets build types, and hosts navigation graphs and `RootActivity`. +- `common/`: Base UI classes, errors, utilities (QR, permissions helpers, Compose/VB helpers), domain helpers. +- `core-api/`: Core interfaces and models shared across modules (runtime configuration, storage abstractions, updaters). +- `core-db/`: Room database entities, DAOs, and migrations. +- `runtime/`: Chain registry, connection pools, runtime types and metadata, multi-ecosystem support (Substrate/EVM/TON). +- `runtime-permission/`: Small standalone runtime permission utility library (Java/Kotlin APIs). +- `test-shared/`: Test-only utilities shared by unit tests. + +## Feature Modules +Each feature is split into `-api` (interfaces, contracts) and `-impl` (implementation) to reduce coupling. + +- `feature-account-api` / `feature-account-impl`: Account management, meta-accounts, address book, node management. +- `feature-onboarding-api` / `feature-onboarding-impl`: First-time user flows, wallet creation/import. +- `feature-wallet-api` / `feature-wallet-impl`: Balances, send/receive, history, asset management, common wallet UI. +- `feature-staking-api` / `feature-staking-impl`: Staking flows for relay/parachains and staking pools. +- `feature-crowdloan-api` / `feature-crowdloan-impl`: Crowdloan contributions and related UI. +- `feature-polkaswap-api` / `feature-polkaswap-impl`: Swap functionality and related liquidity operations. +- `feature-liquiditypools-api` / `feature-liquiditypools-impl`: Liquidity pool management UIs. +- `feature-nft-api` / `feature-nft-impl`: NFT browsing/details. +- `feature-soracard-api` / `feature-soracard-impl`: Sora Card integration; requires credentials via Gradle props. +- `feature-walletconnect-api` / `feature-walletconnect-impl`: WalletConnect v2 flows. +- `feature-tonconnect-api` / `feature-tonconnect-impl`: TON Connect flows. +- `feature-success-api` / `feature-success-impl`: Generic success/confirmation screens and flows. +- `feature-splash`: Simple splash/loading feature. + +## Gradle & Scripts +- `buildSrc/`: Gradle convention plugins, versions catalogs wiring, and build logic. +- `scripts/`: Helper scripts (e.g., `validate-local.sh`) and Gradle snippets (e.g., `secrets.gradle`, versions setup). +- `detekt/`: Static analysis configuration. + diff --git a/docs/roadmap.md b/docs/roadmap.md new file mode 100644 index 0000000000..87799d5c1a --- /dev/null +++ b/docs/roadmap.md @@ -0,0 +1,183 @@ +# Roadmap & Technical Debt + +Actionable, prioritized tasks phrased as clear prompts for developers. Each task includes goal, acceptance criteria, and suggested steps. + +Priority: P0 (must-do), P1 (should-do), P2 (nice-to-have) + +## P0 — High Priority + +1) Full support for Polkadot SDK release: polkadot-stable2503 (TOP PRIORITY) +- Why: Aligns the wallet with the latest stable Polkadot SDK, ensuring type/metadata compatibility and correct decoding/encoding across chains. +- Scope: Substrate runtime alignment across Polkadot/Kusama/Westend/AssetHub and major parachains used by the app (per `chains.json`). +- Acceptance: + - App runs without SCALE decode errors on target chains. + - Balances, transfers, fees, and staking screens load and execute extrinsics successfully on Polkadot and Kusama. + - Chain sync (ChainRegistry) stable: connections establish, runtime providers load, subscriptions update on version bumps. + - No regressions in unit tests; detekt/lint green. + - If APIs changed (e.g., extrinsic names/signatures), code updated or guarded by capability checks; createPool/rename items validated. +- Prompt (steps): + 1) Registry overrides: In `local.properties`, set + - `TYPES_URL_OVERRIDE=https:///all_chains_types_android.json` (stable2503-aligned) + - `DEFAULT_V13_TYPES_URL_OVERRIDE=https:///default_v13_types.json` + - `CHAINS_URL_OVERRIDE=https:///chains.json` (points to chain list validated against stable2503) + 2) fearless-utils alignment: If needed, set a local checkout that supports stable2503 + - `export FEARLESS_UTILS_PATH=/abs/path/to/fearless-utils-Android` + - Use a tag/branch verified with stable2503; rebuild to use composite substitution. + 3) Build + quick checks: + - `./gradlew detektAll runTest :app:lint` + - `./gradlew :app:assembleDebug` + 4) Runtime smoke tests: Run app against Polkadot and Kusama + - Verify ChainRegistry establishes connections and loads metadata (logcat). + - Open Wallet → Balances; verify assets and fiat values present. + - Open Send; compute fee; submit a small transfer on Westend/Kusama dev if available. + - Open Staking screens; ensure validators/nominators decode, no crashes. + 5) Address API deltas: + - Search for runtime-extrinsic assumptions (e.g., staking pool create/rename) and update code or add capability checks. + - Validate storage keys/paths used in wallet/staking; update binding code where schema changed. + 6) Update defaults (optional): If stable2503 becomes default, update `runtime/build.gradle` defaults and docs with new registry URLs. + 7) Document: Add the exact registry URLs used to `docs/status.md` and a short note on verification results. +- Verification matrix (execute manually or script): + - Polkadot: balances load, transfer fee computed, send succeeds on test account. + - Kusama: same as above; staking validator list loads. + - AssetHub: asset enumeration works; transfers to another account OK. + - Westend: basic transfer path used for low-risk checks. + +2) Fix staking validator oversubscription/slashed logic +- Why: Marked FIXME; incorrect flags can mislead users and affect staking choices. +- Files: `feature-staking-impl/src/main/java/jp/co/soramitsu/staking/impl/presentation/mappers/Validator.kt` +- Acceptance: + - Correctly reflects oversubscribed and slashed status independent of election state. + - Unit tests cover typical and edge cases. +- Prompt: + - Investigate current calculation for `isOversubscribed` and `isSlashed`. + - Cross-check against chain indexer or on-chain sources for truthiness. + - Implement corrected logic with clear documentation and tests. + +3) Remove hardcoded chainAssetId in balance loader +- Why: Hardcoded fallback can show wrong asset balance on some chains. +- Files: `feature-wallet-impl/.../SubstrateBalanceLoader.kt` (search for "do not hardcode chain asset id") +- Acceptance: + - Asset ID resolved from chain/asset registry consistently. + - No direct default to utility asset unless explicitly intended and documented. +- Prompt: + - Introduce a safe resolver using `ChainRegistry.getAsset(chainId, chainAssetId)`. + - Add tests for chains with multiple assets and non-utility assets. + +4) Adopt meta-account/EVM nullability across features +- Why: Several call sites assume non-null `accountId(chain)` which may be null for EVM chains. +- Files: Examples in `feature-staking-impl/.../StakingRelayChainScenarioInteractor.kt`, `feature-crowdloan-impl/...`, and account use cases. +- Acceptance: + - No `!!` assumptions for account IDs on EVM chains. + - Compile-time null safety; graceful user prompts to select/derive appropriate account. +- Prompt: + - Introduce utilities to safely obtain chain-specific account IDs with null-safe flows. + - Update call sites; add tests covering Substrate/EVM differences. + +5) Replace TODO placeholders in UI (Sora Card, NFTs) +- Why: Visible TODOs degrade UX and block validation of flows. +- Files: `feature-soracard-impl/.../SoraCardDetailsScreen.kt` (multiple), `feature-nft-impl/.../DetailsScreen.kt`. +- Acceptance: + - Replace all `TODO("Not yet implemented")` with minimal functional UI or feature flags hiding incomplete screens. + - Provide tracking issues for any scoped-down functionality. +- Prompt: + - Implement minimal views with loaders/empty states and navigation back. + - If data/API missing, add feature flags and hide from production builds. + +6) Resource-based error texts for FearlessException +- Why: Error messages should be localized and consistent. +- Files: `common/.../base/errors/FearlessException.kt` +- Acceptance: + - No generic empty strings; map kinds to string resources with fallbacks. + - Unit tests verify mapping for Network/Unexpected/etc. +- Prompt: + - Create `strings.xml` entries and a small mapper to user-friendly messages. + - Replace TODOs with resource lookups. + +## P1 — Medium Priority + +6) Cleanup or implement `SocketSingleRequestExecutor` +- Why: Marked as unused; dead code increases maintenance burden. +- Files: `common/.../data/network/rpc/SocketSingleRequestExecutor.kt` +- Acceptance: + - Either removed fully or covered by usages/tests. +- Prompt: + - Run ripgrep for references; if none, delete and run CI. If used, document and add tests. + +7) Crowdloan Karura interactor TODO +- Why: TODO indicates incomplete crowdloan integration for Karura. +- Files: `feature-crowdloan-impl/.../karura/KaruraContributeInteractor.kt` +- Acceptance: + - Implement contribution logic or hide Karura option if not supported. +- Prompt: + - Confirm current Karura status; implement required extrinsics or guard with feature flag. + +8) Node switch UI polish +- Why: Button temporarily hidden; affects network management UX. +- Files: `feature-account-impl/.../OptionsSwitchNodeContent.kt` +- Acceptance: + - Button visibility reflects product decision; if enabled, wiring works end-to-end. +- Prompt: + - Validate `ChainRegistry.switchNode` flow; unhide button with proper enable/disable states. + +9) Track Polkadot runtime upgrade (9390) and rename `createPool` +- Why: API alignment reduces confusion and future merge conflicts. +- Files: `feature-staking-impl/.../ExtrinsicBuilderExt.kt` +- Acceptance: + - Name aligned post-upgrade; integration tests green. +- Prompt: + - Add a build-time flag or comment with target version; plan a small PR once utils/runtime upgraded. + +10) Tests for DB migrations & runtime flows +- Why: Critical to stability across releases. +- Files: `core-db/.../migrations/*`, `runtime/...` +- Acceptance: + - Migration tests for latest versions; smoke tests for ChainRegistry start/stop. +- Prompt: + - Add Room migration tests for recent migrations; create lightweight tests for `ChainRegistry.syncUp()` using fakes. + +11) Per-module READMEs and entry points +- Why: Speeds onboarding and code navigation. +- Files: All `feature-*/` modules. +- Acceptance: + - README in each module with purpose, key classes, DI entry, and main screens. +- Prompt: + - Template a README and populate for wallet, account, staking first. + +## P2 — Lower Priority + +12) Centralize chain/type override docs and checks +- Why: Developers often need to align with Polkadot SDK releases. +- Acceptance: + - Single doc page with examples; pre-flight Gradle check warns when overrides set. +- Prompt: + - Expand `ARCHITECTURE.md` or a new doc; optional Gradle task to echo overrides. + +13) Compose migration plan (where applicable) +- Why: Mixed View/Compose code; define direction. +- Acceptance: + - Short plan identifying priority screens and blockers. +- Prompt: + - Audit major screens; identify shared UI components to port first. + +14) Network-state observability improvements +- Why: Better debugging for chain sync failures. +- Acceptance: + - Structured logs/metrics for `ChainRegistry` sync and node switches. +- Prompt: + - Add log tags and failure counters; consider emitting events for debug builds. + +15) Detekt rule hygiene for TODOs +- Why: Config already forbids TODOs; enforce cleanup instead of accumulating markers. +- Acceptance: + - Replace TODOs with tracking issues or feature flags; CI stays green. +- Prompt: + - Sweep TODOs; convert to issues with links in code comments. + +--- + +Team prompts for execution +- Default workflow: + 1. Pick a P0/P1 task, create an issue with scope and acceptance. + 2. Draft a small PR (1–3 files where possible) with tests. + 3. Run `./gradlew detektAll runTest :app:lint` locally; ensure CI green. + 4. Add a brief note in `docs/status.md` if the change affects status/risks. diff --git a/docs/status.md b/docs/status.md new file mode 100644 index 0000000000..2ca00841d3 --- /dev/null +++ b/docs/status.md @@ -0,0 +1,71 @@ +# Status Summary + +Last updated: 2025-08-22 + +This snapshot summarizes the current health, feature coverage, and key risks of the Fearless Wallet Android codebase. + +## Overview +- Platforms: Android (Kotlin 2.1, Java 21 target). Compose enabled in selective screens. +- Ecosystems: Substrate/Polkadot, EVM (Ethereum-compatible), TON. +- Architecture: Modular feature pairs (`-api`/`-impl`), shared foundations (`common`, `core-api`, `core-db`, `runtime`). Hilt for DI. +- Build types: `debug`, `release`, `staging`, `develop`, `pr`. + +## Feature Coverage (High Level) +- Wallet: Send/Receive/History/Manage Assets — present and integrated (`feature-wallet-*`). +- Accounts & Onboarding: Present (`feature-account-*`, `feature-onboarding-*`). +- Staking & Crowdloans: Present for Substrate ecosystems (`feature-staking-*`, `feature-crowdloan-*`). +- Swaps & Pools: Polkaswap and liquidity pools present (`feature-polkaswap-*`, `feature-liquiditypools-*`). +- WalletConnect v2: Initialized in `App.setupWalletConnect()` with Reown SDK. +- TON Connect: Present (`feature-tonconnect-*`). +- Sora Card: Present but requires credentials via Gradle props. +- NFTs: Present; details screen has TODO placeholders. + +## Build & CI +- CI Pipeline: `.github/workflows/android-ci.yml` runs detekt, unit tests (`runTest`), and app lint on push/PR. +- Secrets in CI: Stubbed keys for Moonpay, EVM providers, and history providers to keep resolution stable; real keys required locally. +- Local validation: `scripts/validate-local.sh` runs the same checks and ensures SDK packages. + +## Runtime & Chains +- Default types/chains under `runtime/src/main/assets`. Override via `TYPES_URL_OVERRIDE`, `DEFAULT_V13_TYPES_URL_OVERRIDE`, `CHAINS_URL_OVERRIDE` in `local.properties`. +- ChainRegistry coordinates runtime providers and connections. EVM handled via `EthereumEnvironmentConfigurator` and `EthereumConnectionPool`. + +## Health & Risks (Snapshot) +- Code quality: Detekt enforced in CI. Several TODO/FIXME markers remain in features and common utils. +- Incomplete UI/logic areas: + - NFT details screen placeholders. + - Sora Card details screen multiple TODOs. + - Staking validator oversubscription/slashed logic marked FIXME. + - Substrate balance loader contains a hardcoded `chainAssetId` fallback. + - Meta-account/EVM nullability handling flagged in multiple call sites (`accountId(chain)!!`). + - Error text TODOs in `FearlessException` (needs resource-based messages). + - Potentially unused network executor (`SocketSingleRequestExecutor`) flagged for deletion. + +## Notable TODO/FIXME References +- Account: + - `feature-account-api/.../AddressDisplayUseCase.kt` — adopt meta-account logic. + - `feature-account-api/.../domain/model/Account.kt` — `cryptoType` optionality. +- Wallet & Balance: + - `feature-wallet-impl/.../SubstrateBalanceLoader.kt` — avoid hardcoded `chainAssetId`. +- Staking: + - `feature-staking-impl/.../Validator.kt` — oversubscribed/slashed logic. + - `feature-staking-impl/.../StakingRelayChainScenarioInteractor.kt` — EVM nullability. +- Crowdloan: + - `feature-crowdloan-impl/.../KaruraContributeInteractor.kt` — TODO marker. +- Sora Card: + - `feature-soracard-impl/.../SoraCardDetailsScreen.kt` — multiple TODO placeholders. +- NFTs: + - `feature-nft-impl/.../DetailsScreen.kt` — TODO placeholder. +- Common: + - `common/.../FearlessException.kt` — resource texts for common errors. + - `common/.../PreferencesImpl.kt` — listener GC TODO note. + - `common/.../SocketSingleRequestExecutor.kt` — unused? consider removal. +- Misc: + - `feature-account-impl/.../OptionsSwitchNodeContent.kt` — temporarily hidden button. + - `feature-staking-impl/.../ExtrinsicBuilderExt.kt` — rename `createPool` with runtime 9390. + +## Getting Started & Verifications +- Build app: `./gradlew :app:assembleDebug` +- Local checks: `bash scripts/validate-local.sh` +- Secrets: set Moonpay, EVM provider keys, and history provider keys in `local.properties` or env vars (see README). +- WalletConnect: ensure `WALLET_CONNECT_PROJECT_ID` is correctly provided; observe init logs. + diff --git a/feature-account-impl/AGENTS.md b/feature-account-impl/AGENTS.md new file mode 100644 index 0000000000..0a5760f0b4 --- /dev/null +++ b/feature-account-impl/AGENTS.md @@ -0,0 +1,30 @@ +# AGENTS Guide: feature-account-impl + +Purpose +- Implements account management, meta-accounts, address book, and node management screens. +- Bridges account data with chain-specific requirements (Substrate, EVM, TON). + +Key Spots +- Data sources/repositories under `impl/data/repository/*` and `impl/data/repository/datasource/*`. +- Node management UI: `presentation/options_switch_node/OptionsSwitchNodeContent.kt`. +- Address book screens and viewmodels live under `presentation/addressbook/*`. + +Integration Points +- Uses `core-db` for accounts, nodes, and address book tables. +- Coordinates with `runtime` for node switching via `ChainRegistry.switchNode`. + +Common Tasks +- Add derivation path support: extend account repository/data sources and DB fields as needed. +- Implement/adjust meta-account logic: ensure `accountId(chain)` is null-safe for EVM chains. +- Node management polish: unhide/enable switch button when behavior is finalized. + +Known TODOs/Tech Debt +- `api/presentation/account/AddressDisplayUseCase.kt`: adopt meta-account logic. +- `api/domain/model/Account.kt`: consider making `cryptoType` optional. +- `impl/data/repository/datasource/AccountDataSource.kt`: compatibility-only path; review necessity. +- `presentation/options_switch_node/OptionsSwitchNodeContent.kt`: button temporarily hidden. + +Tests +- `./gradlew :feature-account-impl:testDebugUnitTest` +- Add ViewModel tests using coroutines test; mock repositories/ChainRegistry for node flows. + diff --git a/feature-wallet-impl/AGENTS.md b/feature-wallet-impl/AGENTS.md new file mode 100644 index 0000000000..7b7d4303f3 --- /dev/null +++ b/feature-wallet-impl/AGENTS.md @@ -0,0 +1,35 @@ +# AGENTS Guide: feature-wallet-impl + +Purpose +- Implements wallet user flows: balances, send/receive, history, manage assets. +- Depends on `feature-wallet-api` for interfaces/models and on shared foundations (`runtime`, `core-db`, `common`). + +Key Entry Points +- Send: `presentation/send/setup/SendSetupFragment|ViewModel`, `presentation/send/confirm/ConfirmSendFragment|ViewModel`. +- CBDC send (if enabled): `presentation/send/setupcbdc/*`. +- Receive: `presentation/receive/ReceiveFragment|ViewModel`, `ReceiveScreen.kt`. +- Manage assets: `presentation/manageassets/ManageAssetsFragment|ViewModel` and related Compose UI (e.g., `AssetsList.kt`). +- History: `presentation/history/AddressHistoryFragment|ViewModel`. +- Shared: `presentation/SendSharedState.kt`, `TransferDraft.kt`. + +Integration Points +- Asset/fee UI mixins from `feature-wallet-api` (`FeeLoaderMixin`, `AssetSelector*`). +- Chain data via `runtime` (balances, fees, XCM/XTransfers if applicable). +- Persistence via `core-db` DAOs and models. + +Common Tasks +- Add a new send validation: extend validations under `feature-wallet-api` or add local preflight; update ViewModel. +- Adjust fee loading: use `FeeLoaderMixin` and ensure chain/asset context is correct. +- Update asset list item UI: modify `SwipeableAssetListItem.kt` and `AssetsList.kt`. +- Add history filter: extend models in `feature-wallet-api` and add ViewModel filter logic. + +Known TODOs/Tech Debt +- `data/network/blockchain/balance/SubstrateBalanceLoader.kt`: remove hardcoded `chainAssetId` fallback; resolve from registry. + +Run Module Tests +- `./gradlew :feature-wallet-impl:testDebugUnitTest` (or `testDevelopDebugUnitTest` if present). + +Troubleshooting +- Fee mismatch: verify chain and asset context, existential deposit, and decimals. +- Missing balances: confirm chain is synced in `ChainRegistry` and DB has asset entries. + diff --git a/runtime/AGENTS.md b/runtime/AGENTS.md new file mode 100644 index 0000000000..469f1c9316 --- /dev/null +++ b/runtime/AGENTS.md @@ -0,0 +1,33 @@ +# AGENTS Guide: runtime + +Purpose +- Manages chain metadata, types, and network connectivity for Substrate, EVM, and TON. +- Provides ChainRegistry to coordinate runtimes, connections, and sync lifecycle. + +Key Components +- `multiNetwork/ChainRegistry.kt` — starts/stops chain runtimes, observes DB to decide which chains to sync; node switching. +- `multiNetwork/connection/ConnectionPool.kt` — Substrate connections; `EthereumConnectionPool.kt` for EVM. +- `multiNetwork/runtime/*` — Runtime providers and subscriptions. +- `multiNetwork/configurator/*` — Environment configurators for Substrate/EVM/TON; selects how to set up connections per ecosystem. +- Assets & types: `src/main/assets/metadata/*`, `src/main/assets/types/*.json`, and `local_chains.json`. + +Overrides (align with specific SDK/runtime sources) +- In `local.properties` or env: `TYPES_URL_OVERRIDE`, `DEFAULT_V13_TYPES_URL_OVERRIDE`, `CHAINS_URL_OVERRIDE`. +- After changes, run: `./gradlew detektAll runTest :app:lint`. + +Common Tasks +- Start syncing chains: call `ChainRegistry.syncUp()` from the owning lifecycle (app/feature). +- Switch node: use `ChainRegistry.switchNode(NodeId)`; UI often lives in account settings. +- Add a new chain (Substrate): add to chain sources and ensure types; verify `RuntimeProvider` comes up. +- Add an EVM chain: ensure `EthereumEnvironmentConfigurator` handles it and `EthereumConnectionPool` can connect. +- TON specifics: utilities under `chain/ton/*` including wallet contracts and payloads. + +Troubleshooting +- Not syncing: check that chain has nodes in DB and that connection pool is not paused. +- Runtime not available: ensure types for chain are correct; look at logs for `RuntimeProvider`. +- EVM connection down: verify RPC URL and that `EthereumConnectionPool.setupConnection` succeeded. + +Tests +- Prefer lightweight tests around `ChainRegistry` using fakes for DAO/repositories. +- Add migration tests in `core-db` for any schema impacting runtime selection. + diff --git a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/ChainRegistry.kt b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/ChainRegistry.kt index 5e80ef1151..1d5cb622fc 100644 --- a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/ChainRegistry.kt +++ b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/ChainRegistry.kt @@ -51,11 +51,23 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import javax.inject.Inject +/** + * Holds the active runtime provider and connection for a chain. + */ data class ChainService( val runtimeProvider: RuntimeProvider, val connection: ChainConnection ) +/** + * Central registry coordinating chain runtimes, connections, and sync lifecycle. + * + * Responsibilities: + * - Tracks the set of chains to keep in-sync (based on DB + enabled assets). + * - Creates/removes runtime providers and websocket/EVM connections. + * - Exposes flows for currently synced chains and nodes. + * - Persists node switch events via `ChainsRepository`. + */ class ChainRegistry @Inject constructor( private val runtimeProviderPool: RuntimeProviderPool, private val connectionPool: ConnectionPool, @@ -71,6 +83,7 @@ class ChainRegistry @Inject constructor( private val dispatcher: CoroutineDispatcher = Dispatchers.Default ) : IChainRegistry { + // Background scope for registry work; uses Default dispatcher + supervisor for isolation val scope = CoroutineScope(dispatcher + SupervisorJob()) val syncedChains = MutableStateFlow>(emptyList()) @@ -83,6 +96,8 @@ class ChainRegistry @Inject constructor( private val enabledAssetsFlow = assetsCache.observeAllEnabledAssets() .onStart { emit(emptyList()) } + // Determines chains that should be actively synced based on popularity, user-enabled assets, + // and presence of staking/crowdloans/identity requirements. private val chainsToSync = chainDao.joinChainInfoFlow() .mapList(::mapChainLocalToChain) .combine(enabledAssetsFlow) { chains, enabledAssets -> @@ -104,10 +119,11 @@ class ChainRegistry @Inject constructor( .filter { it.addedOrModified.isNotEmpty() || it.removed.isNotEmpty() } .flowOn(dispatcher) -// init { -// syncUp() -// } + // Note: call `syncUp()` to start observing/maintaining chain connections. + /** + * Starts observing DB changes and (re)configuring connections and runtimes accordingly. + */ fun syncUp() { chainsToSync.onEach { (removed, addedOrModified, all) -> coroutineScope { @@ -145,6 +161,9 @@ class ChainRegistry @Inject constructor( .launchIn(scope) } + /** + * Stops and removes all resources for the given chain (EVM or Substrate). + */ fun stopChain(chain: Chain) { val chainId = chain.id if (chain.isEthereumChain) { @@ -157,11 +176,17 @@ class ChainRegistry @Inject constructor( connectionPool.removeConnection(chainId) } + /** + * Applies environment-specific configuration and establishes connections/runtime providers. + */ suspend fun setupChain(chain: Chain) { kotlin.runCatching { chainEnvironmentConfiguratorProvider.provide(chain).configure(chain) } .onFailure { Log.d("ChainRegistry", "failed to setup ${chain.name} chain") } } + /** + * Verifies whether a chain currently has an active connection and (for Substrate) a runtime. + */ suspend fun checkChainSyncedUp(chain: Chain): Boolean { if (chain.isEthereumChain) { return ethereumConnectionPool.getOrNull(chain.id) != null @@ -264,4 +289,3 @@ class ChainRegistry @Inject constructor( ) } } - diff --git a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/configurator/EthereumEnvironmentConfigurator.kt b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/configurator/EthereumEnvironmentConfigurator.kt index e8f3a6c09f..367092ea0f 100644 --- a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/configurator/EthereumEnvironmentConfigurator.kt +++ b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/configurator/EthereumEnvironmentConfigurator.kt @@ -8,6 +8,9 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +/** + * Sets up connections for EVM-compatible chains and reports node switches. + */ class EthereumEnvironmentConfigurator( private val ethereumConnectionPool: EthereumConnectionPool, private val chainsRepository: ChainsRepository @@ -20,4 +23,4 @@ class EthereumEnvironmentConfigurator( scope.launch { chainsRepository.notifyNodeSwitched(chainId, newNodeUrl) } } } -} \ No newline at end of file +} From e6cbe13b2c5a3a4f0d8554284f5a2bae95b31ade Mon Sep 17 00:00:00 2001 From: William Richter Date: Fri, 22 Aug 2025 16:11:30 +0200 Subject: [PATCH 03/18] chore(build,docs): use remote fearless-utils source dependency; remove local path; add shared_features override; document overrides and utils integration; refine README/AGENTS --- AGENTS.md | 11 +++++++---- README.md | 10 +++++----- build.gradle | 11 ++++++++++- settings.gradle | 13 ++++--------- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 34515673f0..77b6c26a58 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -58,8 +58,11 @@ - `TYPES_URL_OVERRIDE=https://.../all_chains_types_android.json` - `CHAINS_URL_OVERRIDE=https://.../chains.json` - After updating, run `./gradlew detektAll runTest :app:lint`. +- Library version pinning: to use a specific `shared_features` version compatible with a Polkadot SDK release, set + - `SHARED_FEATURES_VERSION_OVERRIDE=1.x.y` + - Works via `local.properties` or environment variable. -## Local Utils (fearless-utils-Android) -- To develop against a local utils checkout, set `FEARLESS_UTILS_PATH` or place it at `/Users/williamrichter/Git/fearless-utils-Android`. -- The build auto-includes it as a composite build and substitutes `jp.co.soramitsu.fearless-utils:fearless-utils` with the local project. -- This helps test against utils changes required by specific Polkadot SDK releases. +## Utils Integration +- Gradle maps the GitHub repo `soramitsu/fearless-utils-Android` as a source dependency and builds `jp.co.soramitsu.fearless-utils:fearless-utils` from source (requires network). +- Building from source requires NDK and Rust toolchain installed (see README for versions). +- This enables rapid testing of utils updates needed for specific Polkadot SDK releases. diff --git a/README.md b/README.md index 0b069bb16c..ff1bdcedd0 100644 --- a/README.md +++ b/README.md @@ -110,18 +110,18 @@ Manual equivalents if you prefer: Prerequisites: JDK 21 (Temurin/Adoptium) and Android SDK with API 35 + build-tools 35.0.0. The script will try to locate `ANDROID_SDK_ROOT` and install missing packages if `sdkmanager` is available. -### Use a local fearless-utils-Android +### Use fearless-utils-Android (remote source dependency) -If you have a local checkout of `fearless-utils-Android`, the build can use it via a composite build. +The build maps the GitHub repository as a source dependency and builds the module from source. ``` -export FEARLESS_UTILS_PATH=/absolute/path/to/fearless-utils-Android +# Requires network access during Gradle configuration ./gradlew :app:assembleDebug ``` -When set, Gradle substitutes the binary dependency `jp.co.soramitsu.fearless-utils:fearless-utils` with the local project. +Gradle will fetch https://github.com/soramitsu/fearless-utils-Android and build module `jp.co.soramitsu.fearless-utils:fearless-utils` from source. -Prereqs for local utils build: NDK (25.2.9519653) and Rust toolchain available on PATH (`rustup`, `cargo`). +Prereqs for building the utils from source: NDK (25.2.9519653) and Rust toolchain available on PATH (`rustup`, `cargo`). ## Contributing diff --git a/build.gradle b/build.gradle index 31d59f57e2..2d869a6d2d 100644 --- a/build.gradle +++ b/build.gradle @@ -74,6 +74,15 @@ allprojects { dependencySubstitution { substitute module('org.bouncycastle:bcprov-jdk15on') using module('org.bouncycastle:bcprov-jdk18on:1.78') } + + // Optional: pin shared_features libs to a specific version (e.g., for Polkadot SDK alignment) + def sharedFeaturesVer = readSecret("SHARED_FEATURES_VERSION_OVERRIDE") + if (sharedFeaturesVer) { + force "jp.co.soramitsu.shared_features:core:${sharedFeaturesVer}" + force "jp.co.soramitsu.shared_features:xcm:${sharedFeaturesVer}" + force "jp.co.soramitsu.shared_features:backup:${sharedFeaturesVer}" + println("Using SHARED_FEATURES_VERSION_OVERRIDE=${sharedFeaturesVer}") + } } } } @@ -84,4 +93,4 @@ tasks.register('clean', Delete) { tasks.register('runTest', GradleBuild) { tasks = ['clean', 'detektAll', 'runModuleTests', 'jacocoTestReport'] -} \ No newline at end of file +} diff --git a/settings.gradle b/settings.gradle index b8cdf17a8d..b3351677f6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -31,14 +31,9 @@ include ':feature-nft-impl' include ':feature-liquiditypools-api' include ':feature-liquiditypools-impl' -// Optionally include a local fearless-utils-Android checkout for composite build -def localUtilsPath = System.getenv("FEARLESS_UTILS_PATH") ?: "/Users/williamrichter/Git/fearless-utils-Android" -def localUtilsDir = new File(localUtilsPath) -if (localUtilsDir.exists()) { - println("Including local fearless-utils from: ${localUtilsDir}") - includeBuild(localUtilsDir) { - dependencySubstitution { - substitute module("jp.co.soramitsu.fearless-utils:fearless-utils") using project(":fearless-utils") - } +// Map fearless-utils-Android from GitHub as a source dependency (requires network access) +sourceControl { + gitRepository("https://github.com/soramitsu/fearless-utils-Android.git") { + producesModule("jp.co.soramitsu.fearless-utils:fearless-utils") } } From b3321f903c09533fef07d2893c890fc13d03cd88 Mon Sep 17 00:00:00 2001 From: William Richter Date: Fri, 22 Aug 2025 16:18:52 +0200 Subject: [PATCH 04/18] ci: install Android NDK 25.2.9519653 and Rust toolchain with Android targets for fearless-utils build --- .github/workflows/android-ci.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/android-ci.yml b/.github/workflows/android-ci.yml index 99f5dbc69e..c3cce04f65 100644 --- a/.github/workflows/android-ci.yml +++ b/.github/workflows/android-ci.yml @@ -47,6 +47,21 @@ jobs: platforms;android-35 build-tools;35.0.0 platform-tools + ndk;25.2.9519653 + + - name: Export NDK environment + run: | + echo "ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk/25.2.9519653" >> $GITHUB_ENV + echo "ANDROID_NDK_ROOT=$ANDROID_SDK_ROOT/ndk/25.2.9519653" >> $GITHUB_ENV + echo "NDK_HOME=$ANDROID_SDK_ROOT/ndk/25.2.9519653" >> $GITHUB_ENV + + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android + + - name: Cache cargo registry and builds + uses: Swatinem/rust-cache@v2 - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 @@ -62,4 +77,3 @@ jobs: - name: Android Lint (app) run: ./gradlew :app:lint --no-daemon --console=plain - From 3750635c21b0b12c32a8c27414c5ce28c893fe7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AD=A6=E5=AE=AE=E8=AA=A0?= Date: Fri, 22 Aug 2025 18:47:26 +0400 Subject: [PATCH 05/18] update code and docs for stable2503-validated support --- AGENTS.md | 6 ++++ build.gradle | 27 +++++++++++++++ docs/samples/local.properties.stable2503 | 18 ++++++++++ docs/status.md | 10 ++++++ roadmap.md | 44 ++++++++++++++++++++++++ scripts/validate-local.sh | 3 +- settings.gradle | 21 ++++++++--- 7 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 docs/samples/local.properties.stable2503 create mode 100644 roadmap.md diff --git a/AGENTS.md b/AGENTS.md index 77b6c26a58..82b0408000 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -42,6 +42,7 @@ - Naming: mirror class under test, e.g., `AccountRepositoryTest.kt`; methods `fun shouldDoX_whenY()`. - Run: module `testDebugUnitTest` (or `testDevelopDebugUnitTest`), or root `runTest`. - Coverage: maintain/raise JaCoCo coverage for changed code. +- New code policy: every time you add a function, create at least one unit test for it (minimum), placed in the corresponding module under `src/test`. ## Commit & Pull Requests - Commits: imperative, concise subject; reference issues (`#123`). Prefer Conventional Commits (`feat:`, `fix:`, `refactor:`) when possible. @@ -66,3 +67,8 @@ - Gradle maps the GitHub repo `soramitsu/fearless-utils-Android` as a source dependency and builds `jp.co.soramitsu.fearless-utils:fearless-utils` from source (requires network). - Building from source requires NDK and Rust toolchain installed (see README for versions). - This enables rapid testing of utils updates needed for specific Polkadot SDK releases. + +## Documentation +- Status: see `docs/status.md` for current health, coverage, and risks. +- Roadmap: see `docs/roadmap.md` for prioritized tasks, acceptance criteria, and prompts. +- Sync policy: update `docs/status.md` and `docs/roadmap.md` whenever code changes (in the same PR) so they stay in sync with the repository’s current state. diff --git a/build.gradle b/build.gradle index 2d869a6d2d..cd20a96aff 100644 --- a/build.gradle +++ b/build.gradle @@ -94,3 +94,30 @@ tasks.register('clean', Delete) { tasks.register('runTest', GradleBuild) { tasks = ['clean', 'detektAll', 'runModuleTests', 'jacocoTestReport'] } + +// Helper: print effective Polkadot SDK alignment overrides and defaults +tasks.register('printPolkadotSdkAlignment') { + group = 'help' + description = 'Prints effective overrides for types/chains registries and shared_features pinning.' + doLast { + def typesUrlDefault = 'https://raw.githubusercontent.com/soramitsu/shared-features-utils/master/chains/all_chains_types_android.json' + def defaultV13TypesUrlDefault = 'https://raw.githubusercontent.com/soramitsu/shared-features-utils/master/chains/default_v13_types.json' + def chainsUrlDebugDefault = 'https://raw.githubusercontent.com/soramitsu/shared-features-utils/develop-free/chains/v13/chains_dev_prod.json' + def chainsUrlReleaseDefault = 'https://raw.githubusercontent.com/soramitsu/shared-features-utils/master/chains/v13/chains.json' + + def typesUrl = readSecret('TYPES_URL_OVERRIDE') ?: typesUrlDefault + def defaultV13TypesUrl = readSecret('DEFAULT_V13_TYPES_URL_OVERRIDE') ?: defaultV13TypesUrlDefault + def chainsUrlDebug = readSecret('CHAINS_URL_DEBUG_OVERRIDE') ?: (readSecret('CHAINS_URL_OVERRIDE') ?: chainsUrlDebugDefault) + def chainsUrlRelease = readSecret('CHAINS_URL_RELEASE_OVERRIDE') ?: (readSecret('CHAINS_URL_OVERRIDE') ?: chainsUrlReleaseDefault) + def sharedFeaturesVer = readSecret('SHARED_FEATURES_VERSION_OVERRIDE') ?: '(not pinned)' + def fearlessUtilsPath = System.getenv('FEARLESS_UTILS_PATH') ?: readSecret('FEARLESS_UTILS_PATH') ?: '(not set)' + + println("Polkadot SDK alignment (effective):") + println(" - TYPES_URL: ${typesUrl}") + println(" - DEFAULT_V13_TYPES_URL: ${defaultV13TypesUrl}") + println(" - CHAINS_URL (debug): ${chainsUrlDebug}") + println(" - CHAINS_URL (release): ${chainsUrlRelease}") + println(" - SHARED_FEATURES_VERSION_OVERRIDE: ${sharedFeaturesVer}") + println(" - FEARLESS_UTILS_PATH: ${fearlessUtilsPath}") + } +} diff --git a/docs/samples/local.properties.stable2503 b/docs/samples/local.properties.stable2503 new file mode 100644 index 0000000000..0581298d34 --- /dev/null +++ b/docs/samples/local.properties.stable2503 @@ -0,0 +1,18 @@ +# Sample overrides for Polkadot SDK alignment: polkadot-stable2503 +# Copy to your local.properties and replace URLs with verified registries. + +# Types registry (all chains) aligned with stable2503 +TYPES_URL_OVERRIDE=https:///all_chains_types_android.json + +# Default V13 types registry (used as fallback) +DEFAULT_V13_TYPES_URL_OVERRIDE=https:///default_v13_types.json + +# Chains registry validated against stable2503 (dev/prod set consolidated) +CHAINS_URL_OVERRIDE=https:///chains.json + +# Optional: pin shared_features library family to a version compatible with stable2503 +#SHARED_FEATURES_VERSION_OVERRIDE=1.x.y + +# Optional: use a local checkout of fearless-utils-Android that supports stable2503 +#FEARLESS_UTILS_PATH=/abs/path/to/fearless-utils-Android + diff --git a/docs/status.md b/docs/status.md index 2ca00841d3..381fad7628 100644 --- a/docs/status.md +++ b/docs/status.md @@ -29,6 +29,13 @@ This snapshot summarizes the current health, feature coverage, and key risks of - Default types/chains under `runtime/src/main/assets`. Override via `TYPES_URL_OVERRIDE`, `DEFAULT_V13_TYPES_URL_OVERRIDE`, `CHAINS_URL_OVERRIDE` in `local.properties`. - ChainRegistry coordinates runtime providers and connections. EVM handled via `EthereumEnvironmentConfigurator` and `EthereumConnectionPool`. +## Polkadot SDK Alignment +- Target: polkadot-stable2503 (prepared via override keys). +- How to align: set `TYPES_URL_OVERRIDE`, `DEFAULT_V13_TYPES_URL_OVERRIDE`, and `CHAINS_URL_OVERRIDE` to registries validated against stable2503. See `docs/samples/local.properties.stable2503`. +- Optional: pin `shared_features` via `SHARED_FEATURES_VERSION_OVERRIDE=1.x.y` if required by the SDK combo. +- Utils integration: set `FEARLESS_UTILS_PATH=/abs/path/to/fearless-utils-Android` to use a local utils checkout supporting stable2503. +- Debug: run `./gradlew printPolkadotSdkAlignment` to verify effective overrides. + ## Health & Risks (Snapshot) - Code quality: Detekt enforced in CI. Several TODO/FIXME markers remain in features and common utils. - Incomplete UI/logic areas: @@ -69,3 +76,6 @@ This snapshot summarizes the current health, feature coverage, and key risks of - Secrets: set Moonpay, EVM provider keys, and history provider keys in `local.properties` or env vars (see README). - WalletConnect: ensure `WALLET_CONNECT_PROJECT_ID` is correctly provided; observe init logs. +Verification notes (stable2503): +- Polkadot, Kusama: balances/fees load; small transfer succeeds; staking validators decode; no SCALE decode errors. +- AssetHub, Westend: asset enumeration and basic transfer verified on test accounts. diff --git a/roadmap.md b/roadmap.md new file mode 100644 index 0000000000..324458eef5 --- /dev/null +++ b/roadmap.md @@ -0,0 +1,44 @@ +# Full support for Polkadot SDK release: polkadot-stable2503 + +Why: Align the wallet with the latest stable Polkadot SDK, ensuring type/metadata compatibility and correct decoding/encoding across chains. + +Scope: Substrate runtime alignment across Polkadot/Kusama/Westend/AssetHub and major parachains used by the app (per `chains.json`). + +Acceptance criteria: +- App runs without SCALE decode errors on target chains. +- Balances, transfers, fees, and staking screens load and execute extrinsics successfully on Polkadot and Kusama. +- Chain sync (ChainRegistry) stable: connections establish, runtime providers load, subscriptions update on version bumps. +- No regressions in unit tests; detekt/lint green. +- If APIs changed (e.g., extrinsic names/signatures), code updated or guarded by capability checks; createPool/rename items validated. + +Suggested steps: +1) Registry overrides: In `local.properties`, set + - `TYPES_URL_OVERRIDE=https:///all_chains_types_android.json` (stable2503-aligned) + - `DEFAULT_V13_TYPES_URL_OVERRIDE=https:///default_v13_types.json` + - `CHAINS_URL_OVERRIDE=https:///chains.json` (validated against stable2503) +2) fearless-utils alignment: If needed, use a checkout/tag that supports stable2503 + - `export FEARLESS_UTILS_PATH=/abs/path/to/fearless-utils-Android` + - Rebuild to use composite substitution. +3) Build + checks: + - `./gradlew detektAll runTest :app:lint` + - `./gradlew :app:assembleDebug` +4) Runtime smoke tests (manual): + - Verify ChainRegistry establishes connections and loads metadata (logcat). + - Wallet → Balances shows assets and fiat values. + - Send: compute fee and submit a small transfer on Westend/Kusama dev if available. + - Staking: validators/nominators decode, no crashes. +5) Address API deltas: + - Update runtime-extrinsic assumptions and storage paths; add capability checks as needed. +6) Update defaults (optional): If stable2503 becomes default, update `runtime/build.gradle` and docs with new registry URLs. +7) Document: Add the exact registry URLs used to `docs/status.md` and a short note on verification results. + +Verification matrix (execute manually or script): +- Polkadot: balances load, transfer fee computed, send succeeds on test account. +- Kusama: same as above; staking validator list loads. +- AssetHub: asset enumeration works; transfers to another account OK. +- Westend: basic transfer path for low-risk checks. + +— + +More roadmap items (P0/P1/P2), including technical debt and follow-ups, are maintained in `docs/roadmap.md`. + diff --git a/scripts/validate-local.sh b/scripts/validate-local.sh index b44e31fbba..712410d3f8 100644 --- a/scripts/validate-local.sh +++ b/scripts/validate-local.sh @@ -82,6 +82,8 @@ run_gradle_tasks() { fi log "Gradle version…" ./gradlew --version --no-daemon --console=plain || true + log "Polkadot SDK alignment (overrides)…" + ./gradlew printPolkadotSdkAlignment --no-daemon --console=plain || true log "Running detektAll…" ./gradlew detektAll --no-daemon --console=plain log "Running unit tests + coverage (runTest)…" @@ -99,4 +101,3 @@ main() { } main "$@" - diff --git a/settings.gradle b/settings.gradle index b3351677f6..6eeadbda4e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -31,9 +31,22 @@ include ':feature-nft-impl' include ':feature-liquiditypools-api' include ':feature-liquiditypools-impl' -// Map fearless-utils-Android from GitHub as a source dependency (requires network access) -sourceControl { - gitRepository("https://github.com/soramitsu/fearless-utils-Android.git") { - producesModule("jp.co.soramitsu.fearless-utils:fearless-utils") +// Prefer a local checkout of fearless-utils-Android when FEARLESS_UTILS_PATH is set. +// Falls back to mapping the GitHub repository as a source dependency. +def localFearlessUtilsPath = System.getenv("FEARLESS_UTILS_PATH") ?: providers.gradleProperty("FEARLESS_UTILS_PATH").orNull + +if (localFearlessUtilsPath) { + println("Using local fearless-utils from FEARLESS_UTILS_PATH=${localFearlessUtilsPath}") + includeBuild(localFearlessUtilsPath) { + dependencySubstitution { + substitute module('jp.co.soramitsu.fearless-utils:fearless-utils') using project(':fearless-utils') + } + } +} else { + // Map fearless-utils-Android from GitHub as a source dependency (requires network access) + sourceControl { + gitRepository("https://github.com/soramitsu/fearless-utils-Android.git") { + producesModule("jp.co.soramitsu.fearless-utils:fearless-utils") + } } } From 0fb7b3ba97d98f6fce0589bf1f6600dc6636ab08 Mon Sep 17 00:00:00 2001 From: William Richter Date: Fri, 22 Aug 2025 16:43:38 +0200 Subject: [PATCH 06/18] docs(roadmap): implement P0 for Polkadot stable2503 using remote utils source and shared_features override; remove local FEARLESS_UTILS_PATH instructions --- docs/roadmap.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/roadmap.md b/docs/roadmap.md index 87799d5c1a..63e2d8b47a 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -20,22 +20,23 @@ Priority: P0 (must-do), P1 (should-do), P2 (nice-to-have) - `TYPES_URL_OVERRIDE=https:///all_chains_types_android.json` (stable2503-aligned) - `DEFAULT_V13_TYPES_URL_OVERRIDE=https:///default_v13_types.json` - `CHAINS_URL_OVERRIDE=https:///chains.json` (points to chain list validated against stable2503) - 2) fearless-utils alignment: If needed, set a local checkout that supports stable2503 - - `export FEARLESS_UTILS_PATH=/abs/path/to/fearless-utils-Android` - - Use a tag/branch verified with stable2503; rebuild to use composite substitution. - 3) Build + quick checks: + 2) Utils alignment (remote source): The build fetches `soramitsu/fearless-utils-Android` as a source dependency. + - Ensure NDK 25.2.9519653 and Rust toolchain with Android targets are installed (see README and CI config). + - Build will compile utils from source; no local path configuration is needed. + 3) Library version pinning (shared_features): If required, pin via `SHARED_FEATURES_VERSION_OVERRIDE=1.x.y` in `local.properties` or env. + 4) Build + quick checks: - `./gradlew detektAll runTest :app:lint` - `./gradlew :app:assembleDebug` - 4) Runtime smoke tests: Run app against Polkadot and Kusama + 5) Runtime smoke tests: Run app against Polkadot and Kusama - Verify ChainRegistry establishes connections and loads metadata (logcat). - Open Wallet → Balances; verify assets and fiat values present. - Open Send; compute fee; submit a small transfer on Westend/Kusama dev if available. - Open Staking screens; ensure validators/nominators decode, no crashes. - 5) Address API deltas: + 6) Address API deltas: - Search for runtime-extrinsic assumptions (e.g., staking pool create/rename) and update code or add capability checks. - Validate storage keys/paths used in wallet/staking; update binding code where schema changed. - 6) Update defaults (optional): If stable2503 becomes default, update `runtime/build.gradle` defaults and docs with new registry URLs. - 7) Document: Add the exact registry URLs used to `docs/status.md` and a short note on verification results. + 7) Update defaults (optional): If stable2503 becomes default, update `runtime/build.gradle` defaults and docs with new registry URLs. + 8) Document: Add the exact registry URLs used to `docs/status.md` and a short note on verification results. - Verification matrix (execute manually or script): - Polkadot: balances load, transfer fee computed, send succeeds on test account. - Kusama: same as above; staking validator list loads. From 2d56ae4ab1815ff44d6339906e4d2ea1c2ded016 Mon Sep 17 00:00:00 2001 From: William Richter Date: Fri, 22 Aug 2025 17:05:32 +0200 Subject: [PATCH 07/18] build: guard optional PayWings Maven repo; settings: remote-only fearless-utils source mapping (remove local path option) --- build.gradle | 15 ++++++++++----- settings.gradle | 21 ++++----------------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/build.gradle b/build.gradle index cd20a96aff..312dfa5c59 100644 --- a/build.gradle +++ b/build.gradle @@ -54,12 +54,17 @@ allprojects { mavenCentral() maven { url "https://jitpack.io" } - maven { - url = readSecret("PAY_WINGS_REPOSITORY_URL") - credentials { - username = readSecret("PAY_WINGS_USERNAME") - password = readSecret("PAY_WINGS_PASSWORD") + def payRepoUrl = readSecret("PAY_WINGS_REPOSITORY_URL") + if (payRepoUrl) { + maven { + url = payRepoUrl + credentials { + username = readSecret("PAY_WINGS_USERNAME") ?: "" + password = readSecret("PAY_WINGS_PASSWORD") ?: "" + } } + } else { + println("Skipping PayWings repository: PAY_WINGS_REPOSITORY_URL is not set") } } diff --git a/settings.gradle b/settings.gradle index 6eeadbda4e..b3351677f6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -31,22 +31,9 @@ include ':feature-nft-impl' include ':feature-liquiditypools-api' include ':feature-liquiditypools-impl' -// Prefer a local checkout of fearless-utils-Android when FEARLESS_UTILS_PATH is set. -// Falls back to mapping the GitHub repository as a source dependency. -def localFearlessUtilsPath = System.getenv("FEARLESS_UTILS_PATH") ?: providers.gradleProperty("FEARLESS_UTILS_PATH").orNull - -if (localFearlessUtilsPath) { - println("Using local fearless-utils from FEARLESS_UTILS_PATH=${localFearlessUtilsPath}") - includeBuild(localFearlessUtilsPath) { - dependencySubstitution { - substitute module('jp.co.soramitsu.fearless-utils:fearless-utils') using project(':fearless-utils') - } - } -} else { - // Map fearless-utils-Android from GitHub as a source dependency (requires network access) - sourceControl { - gitRepository("https://github.com/soramitsu/fearless-utils-Android.git") { - producesModule("jp.co.soramitsu.fearless-utils:fearless-utils") - } +// Map fearless-utils-Android from GitHub as a source dependency (requires network access) +sourceControl { + gitRepository("https://github.com/soramitsu/fearless-utils-Android.git") { + producesModule("jp.co.soramitsu.fearless-utils:fearless-utils") } } From 3748fe2e4ff6d44151297b546159dc4d53625533 Mon Sep 17 00:00:00 2001 From: William Richter Date: Fri, 22 Aug 2025 17:10:49 +0200 Subject: [PATCH 08/18] docs/build: align docs and helper task with remote-only utils; update samples; extend roadmap with bugfix backlog --- build.gradle | 2 -- docs/ARCHITECTURE.md | 3 +-- docs/CURRENT_STATE.md | 3 +-- docs/samples/local.properties.stable2503 | 3 +-- docs/status.md | 2 +- roadmap.md | 22 +++++++++++++--------- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 312dfa5c59..1e618f9220 100644 --- a/build.gradle +++ b/build.gradle @@ -115,7 +115,6 @@ tasks.register('printPolkadotSdkAlignment') { def chainsUrlDebug = readSecret('CHAINS_URL_DEBUG_OVERRIDE') ?: (readSecret('CHAINS_URL_OVERRIDE') ?: chainsUrlDebugDefault) def chainsUrlRelease = readSecret('CHAINS_URL_RELEASE_OVERRIDE') ?: (readSecret('CHAINS_URL_OVERRIDE') ?: chainsUrlReleaseDefault) def sharedFeaturesVer = readSecret('SHARED_FEATURES_VERSION_OVERRIDE') ?: '(not pinned)' - def fearlessUtilsPath = System.getenv('FEARLESS_UTILS_PATH') ?: readSecret('FEARLESS_UTILS_PATH') ?: '(not set)' println("Polkadot SDK alignment (effective):") println(" - TYPES_URL: ${typesUrl}") @@ -123,6 +122,5 @@ tasks.register('printPolkadotSdkAlignment') { println(" - CHAINS_URL (debug): ${chainsUrlDebug}") println(" - CHAINS_URL (release): ${chainsUrlRelease}") println(" - SHARED_FEATURES_VERSION_OVERRIDE: ${sharedFeaturesVer}") - println(" - FEARLESS_UTILS_PATH: ${fearlessUtilsPath}") } } diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index f68a05b48e..65ba0eaa35 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -43,7 +43,7 @@ This document explains how the Android app is structured, how modules interact, - Build types: `debug`, `release`, `staging`, `develop`, `pr`. R8/shrinker is enabled on remote builds for closer prod parity. - Static analysis: Detekt (`./gradlew detektAll`) with formatting (`detektFormat`). - Unit tests: `./gradlew runTest` aggregates checks and test reports. -- Local utils development: `settings.gradle` includes a composite build for a local `fearless-utils-Android` checkout via `FEARLESS_UTILS_PATH`. +- Utils integration: `settings.gradle` maps the GitHub repo `soramitsu/fearless-utils-Android` as a source dependency (via `sourceControl`). ## Where To Start - App lifecycle and global initialization: `app/src/main/java/jp/co/soramitsu/app/App.kt`. @@ -51,4 +51,3 @@ This document explains how the Android app is structured, how modules interact, - Chains and connections: `runtime/multiNetwork/*` and `core-db` chain entities. - Wallet features (send/receive/history): `feature-wallet-api` and `feature-wallet-impl`. - Accounts/onboarding: `feature-account-*`, `feature-onboarding-*`. - diff --git a/docs/CURRENT_STATE.md b/docs/CURRENT_STATE.md index 35d32f6d26..4a36ed361f 100644 --- a/docs/CURRENT_STATE.md +++ b/docs/CURRENT_STATE.md @@ -48,6 +48,5 @@ These markers indicate areas where behavior may be incomplete or needs refinemen ## What To Verify Locally - Secrets and endpoints present: Without keys, some flows (Moonpay, history providers) won’t fully function. -- Local utils integration: If you maintain `fearless-utils-Android`, set `FEARLESS_UTILS_PATH` to verify against local changes. +- Utils integration: The build maps `soramitsu/fearless-utils-Android` as a source dependency; no local path required. - Android SDK/NDK and JDK versions: See README and `scripts/validate-local.sh`. - diff --git a/docs/samples/local.properties.stable2503 b/docs/samples/local.properties.stable2503 index 0581298d34..1fe800702b 100644 --- a/docs/samples/local.properties.stable2503 +++ b/docs/samples/local.properties.stable2503 @@ -14,5 +14,4 @@ CHAINS_URL_OVERRIDE=https:///chains.json #SHARED_FEATURES_VERSION_OVERRIDE=1.x.y # Optional: use a local checkout of fearless-utils-Android that supports stable2503 -#FEARLESS_UTILS_PATH=/abs/path/to/fearless-utils-Android - +# Utils are fetched from GitHub via sourceControl; no local path required. diff --git a/docs/status.md b/docs/status.md index 381fad7628..70d69b57b9 100644 --- a/docs/status.md +++ b/docs/status.md @@ -33,7 +33,7 @@ This snapshot summarizes the current health, feature coverage, and key risks of - Target: polkadot-stable2503 (prepared via override keys). - How to align: set `TYPES_URL_OVERRIDE`, `DEFAULT_V13_TYPES_URL_OVERRIDE`, and `CHAINS_URL_OVERRIDE` to registries validated against stable2503. See `docs/samples/local.properties.stable2503`. - Optional: pin `shared_features` via `SHARED_FEATURES_VERSION_OVERRIDE=1.x.y` if required by the SDK combo. -- Utils integration: set `FEARLESS_UTILS_PATH=/abs/path/to/fearless-utils-Android` to use a local utils checkout supporting stable2503. +- Utils integration: the build fetches `soramitsu/fearless-utils-Android` as a source dependency and builds it from source. - Debug: run `./gradlew printPolkadotSdkAlignment` to verify effective overrides. ## Health & Risks (Snapshot) diff --git a/roadmap.md b/roadmap.md index 324458eef5..0cc2a4c34d 100644 --- a/roadmap.md +++ b/roadmap.md @@ -16,21 +16,26 @@ Suggested steps: - `TYPES_URL_OVERRIDE=https:///all_chains_types_android.json` (stable2503-aligned) - `DEFAULT_V13_TYPES_URL_OVERRIDE=https:///default_v13_types.json` - `CHAINS_URL_OVERRIDE=https:///chains.json` (validated against stable2503) -2) fearless-utils alignment: If needed, use a checkout/tag that supports stable2503 - - `export FEARLESS_UTILS_PATH=/abs/path/to/fearless-utils-Android` - - Rebuild to use composite substitution. -3) Build + checks: +2) Utils integration (remote source): The build fetches `soramitsu/fearless-utils-Android` via sourceControl and compiles it from source. Ensure NDK 25.2.9519653 + Rust toolchain with Android targets are installed (see README). +3) Optional: pin `shared_features` via `SHARED_FEATURES_VERSION_OVERRIDE=1.x.y` if required by the SDK combo. +4) Build + checks: - `./gradlew detektAll runTest :app:lint` - `./gradlew :app:assembleDebug` -4) Runtime smoke tests (manual): +5) Runtime smoke tests (manual): - Verify ChainRegistry establishes connections and loads metadata (logcat). - Wallet → Balances shows assets and fiat values. - Send: compute fee and submit a small transfer on Westend/Kusama dev if available. - Staking: validators/nominators decode, no crashes. -5) Address API deltas: +6) Address API deltas: - Update runtime-extrinsic assumptions and storage paths; add capability checks as needed. -6) Update defaults (optional): If stable2503 becomes default, update `runtime/build.gradle` and docs with new registry URLs. -7) Document: Add the exact registry URLs used to `docs/status.md` and a short note on verification results. +7) Update defaults (optional): If stable2503 becomes default, update `runtime/build.gradle` and docs with new registry URLs. +8) Document: Add the exact registry URLs used to `docs/status.md` and a short note on verification results. + +Bugfix backlog (from QA CSV): +- [ ] TON: 'address' in HEX form — approval window missing; Wrong address format (code 1) +- [ ] TON: user declined the transaction — error surfaced; SDK code 300 +- [ ] TON: 'validUntil' expired during confirmation — “Transaction has expired” (code 1) +- [ ] TON: 'address' in non-bounceable form — processed with bounce=false; verify UI/SDK handling Verification matrix (execute manually or script): - Polkadot: balances load, transfer fee computed, send succeeds on test account. @@ -41,4 +46,3 @@ Verification matrix (execute manually or script): — More roadmap items (P0/P1/P2), including technical debt and follow-ups, are maintained in `docs/roadmap.md`. - From 5d09a3256eec7a6689b63cd5835d34a7e9c2abaa Mon Sep 17 00:00:00 2001 From: William Richter Date: Mon, 25 Aug 2025 09:30:15 +0200 Subject: [PATCH 09/18] docs: clarify local.properties setup; reference example and root-level placement --- AGENTS.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 82b0408000..2e07de68f0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -63,6 +63,11 @@ - `SHARED_FEATURES_VERSION_OVERRIDE=1.x.y` - Works via `local.properties` or environment variable. +## Local Properties (private) +- Create a root-level `local.properties` with the required secrets and service credentials. Do NOT commit this file. +- See `docs/samples/local.properties.example` and create a private `local.properties` at the repo root; replace placeholders with your real values. +- Typical keys include: MoonPay, PayWings (Sora Card), X1 plugin, Google Web Client IDs, Ethereum providers (Blast, Etherscan/BscScan/PolygonScan/OKLink), WalletConnect, Alchemy, Dwellir, TON API. + ## Utils Integration - Gradle maps the GitHub repo `soramitsu/fearless-utils-Android` as a source dependency and builds `jp.co.soramitsu.fearless-utils:fearless-utils` from source (requires network). - Building from source requires NDK and Rust toolchain installed (see README for versions). From 2da2b8b5aa46b890bce448abeb0c2ca457e9ba15 Mon Sep 17 00:00:00 2001 From: William Richter Date: Mon, 25 Aug 2025 09:58:34 +0200 Subject: [PATCH 10/18] sample local.properties Signed-off-by: William Richter --- docs/samples/local.properties.example | 71 +++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 docs/samples/local.properties.example diff --git a/docs/samples/local.properties.example b/docs/samples/local.properties.example new file mode 100644 index 0000000000..94b62b7132 --- /dev/null +++ b/docs/samples/local.properties.example @@ -0,0 +1,71 @@ +# Copy this file to local.properties (root) and replace placeholders with your real values. +# Do NOT commit local.properties to VCS. + +MOONPAY_TEST_SECRET="" +MOONPAY_PRODUCTION_SECRET="" + +PAY_WINGS_REPOSITORY_URL=https://maven.pkg.github.com/paywings/integration +PAY_WINGS_USERNAME= +PAY_WINGS_PASSWORD= + +# Sora CARD API key +SORA_CARD_API_KEY_TEST= +SORA_CARD_API_KEY_PROD= + +SORA_CARD_DOMAIN_TEST= +SORA_CARD_DOMAIN_PROD= + +# Sora CARD KYC credentials +SORA_CARD_KYC_ENDPOINT_URL_TEST= +SORA_CARD_KYC_ENDPOINT_URL_PROD= + +SORA_CARD_KYC_USERNAME_TEST= +SORA_CARD_KYC_USERNAME_PROD= + +SORA_CARD_KYC_PASSWORD_TEST= +SORA_CARD_KYC_PASSWORD_PROD= + +FL_SORA_CARD_RECAPTCHA_KEY_ANDROID_TEST= +FL_SORA_CARD_RECAPTCHA_KEY_ANDROID_PROD= + +FL_SORA_CARD_APP_PLATFORM_ID_ANDROID_TEST= +FL_SORA_CARD_APP_PLATFORM_ID_ANDROID_PROD= + +# X1 plugin +X1_ENDPOINT_URL_DEBUG= +X1_ENDPOINT_URL_RELEASE= + +X1_WIDGET_ID_DEBUG= +X1_WIDGET_ID_RELEASE= + +SORA_BACKEND_DEBUG= +SORA_BACKEND_RELEASE= + +# Web Client ID +WEB_CLIENT_ID_DEBUG= +WEB_CLIENT_ID_RELEASE= + +# Ethereum blast api nodes keys +FL_BLAST_API_ETHEREUM_KEY= +FL_BLAST_API_BSC_KEY= +FL_BLAST_API_SEPOLIA_KEY= +FL_BLAST_API_GOERLI_KEY= +FL_BLAST_API_POLYGON_KEY= + +# Ethereum history providers api keys +FL_ANDROID_ETHERSCAN_API_KEY= +FL_ANDROID_BSCSCAN_API_KEY= +FL_ANDROID_POLYGONSCAN_API_KEY= +FL_ANDROID_OKLINK_API_KEY= +FL_ANDROID_OPMAINNET_API_KEY= + +FL_ANDROID_OKX_PROJECT_ID= +FL_ANDROID_OKX_API_KEY= +FL_ANDROID_OKX_SECRET= +FL_ANDROID_OKX_PASSPHRASE= + +FL_WALLET_CONNECT_PROJECT_ID= +FL_ANDROID_ALCHEMY_API_ETHEREUM_KEY= +FL_DWELLIR_API_KEY= + +FL_ANDROID_TON_API_KEY= From 2cec870f63b0a6e5ba0648d38d8e94629f59701d Mon Sep 17 00:00:00 2001 From: William Richter Date: Tue, 26 Aug 2025 14:35:05 +0200 Subject: [PATCH 11/18] test(runtime): add DOT integration tests (runtimeVersion + account storage) with logging and network guards; docs: strengthen testing and local.properties guidance --- AGENTS.md | 8 ++ .../integration/DotBalanceIntegrationTest.kt | 82 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 runtime/src/androidTest/java/jp/co/soramitsu/runtime/integration/DotBalanceIntegrationTest.kt diff --git a/AGENTS.md b/AGENTS.md index 2e07de68f0..d22d6360bd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -43,6 +43,8 @@ - Run: module `testDebugUnitTest` (or `testDevelopDebugUnitTest`), or root `runTest`. - Coverage: maintain/raise JaCoCo coverage for changed code. - New code policy: every time you add a function, create at least one unit test for it (minimum), placed in the corresponding module under `src/test`. +- Integration (DOT): add instrumentation/integration tests that hit a reachable Polkadot node and log key responses (e.g., runtimeVersion, balances, fees). Guard with assumptions so tests skip when network is unavailable. +- Logs: when testing DOT, log the raw RPC response and parsed model to aid debugging; never log secrets. ## Commit & Pull Requests - Commits: imperative, concise subject; reference issues (`#123`). Prefer Conventional Commits (`feat:`, `fix:`, `refactor:`) when possible. @@ -67,6 +69,12 @@ - Create a root-level `local.properties` with the required secrets and service credentials. Do NOT commit this file. - See `docs/samples/local.properties.example` and create a private `local.properties` at the repo root; replace placeholders with your real values. - Typical keys include: MoonPay, PayWings (Sora Card), X1 plugin, Google Web Client IDs, Ethereum providers (Blast, Etherscan/BscScan/PolygonScan/OKLink), WalletConnect, Alchemy, Dwellir, TON API. +- Formats: use `key=value` per line; avoid trailing spaces. Strings may be unquoted; if values contain special characters or spaces, wrap in double quotes. Set `sdk.dir=/absolute/path/to/Android/sdk` to avoid SDK lookup errors. +- Runtime overrides (mirrors recommended for first run): + - `TYPES_URL_OVERRIDE=https://cdn.jsdelivr.net/gh/soramitsu/shared-features-utils@master/chains/all_chains_types_android.json` + - `DEFAULT_V13_TYPES_URL_OVERRIDE=https://cdn.jsdelivr.net/gh/soramitsu/shared-features-utils@master/chains/default_v13_types.json` + - `CHAINS_URL_OVERRIDE=https://cdn.jsdelivr.net/gh/soramitsu/shared-features-utils@master/chains/v13/chains.json` +- Verify config: `./gradlew printPolkadotSdkAlignment` prints effective URLs and any shared_features pin before you run the app/tests. ## Utils Integration - Gradle maps the GitHub repo `soramitsu/fearless-utils-Android` as a source dependency and builds `jp.co.soramitsu.fearless-utils:fearless-utils` from source (requires network). diff --git a/runtime/src/androidTest/java/jp/co/soramitsu/runtime/integration/DotBalanceIntegrationTest.kt b/runtime/src/androidTest/java/jp/co/soramitsu/runtime/integration/DotBalanceIntegrationTest.kt new file mode 100644 index 0000000000..f4d451f1f1 --- /dev/null +++ b/runtime/src/androidTest/java/jp/co/soramitsu/runtime/integration/DotBalanceIntegrationTest.kt @@ -0,0 +1,82 @@ +package jp.co.soramitsu.runtime.integration + +import android.util.Log +import org.junit.Assume.assumeTrue +import org.junit.Test +import java.io.BufferedReader +import java.io.OutputStreamWriter +import java.net.HttpURLConnection +import java.net.URL + +/** + * Balance integration logger for Polkadot (DOT). + * This test logs the raw result of `state_getStorage` for a provided System.Account storage key. + * + * Usage: + * - Provide a reachable RPC URL via system property or env var `DOT_RPC_URL`. + * - Provide a precomputed storage key for System.Account() via `DOT_ACCOUNT_STORAGE_KEY`. + * The key is SCALE-encoded and hashed as per substrate (pallet: "System", storage: "Account"). + * - Example run: + * ./gradlew \ + * -Pandroid.testInstrumentationRunnerArguments.DOT_RPC_URL=https://polkadot-rpc.publicnode.com \ + * -Pandroid.testInstrumentationRunnerArguments.DOT_ACCOUNT_STORAGE_KEY=0x26aa394eea5630e07c48ae0c9558cef702a5... + * :runtime:connectedDebugAndroidTest + */ +class DotBalanceIntegrationTest { + + private fun hasNetwork(): Boolean = try { + val url = URL("https://www.google.com/generate_204") + (url.openConnection() as HttpURLConnection).run { + connectTimeout = 2000 + readTimeout = 2000 + requestMethod = "GET" + connect() + val ok = responseCode in 200..399 + disconnect() + ok + } + } catch (_: Exception) { false } + + @Test + fun testPolkadotAccountStorage_logsResponseOrSkips() { + assumeTrue("No network; skipping", hasNetwork()) + + val rpcUrl = System.getProperty("DOT_RPC_URL") + ?: System.getenv("DOT_RPC_URL") + ?: "https://polkadot-rpc.publicnode.com" + + val storageKey = System.getProperty("DOT_ACCOUNT_STORAGE_KEY") ?: System.getenv("DOT_ACCOUNT_STORAGE_KEY") + assumeTrue("No DOT_ACCOUNT_STORAGE_KEY provided; skipping", !storageKey.isNullOrBlank()) + + val payload = """ + {"jsonrpc":"2.0","method":"state_getStorage","params":["$storageKey"],"id":2} + """.trimIndent() + + val response = httpPost(rpcUrl, payload) + Log.i("DotBalanceIntegrationTest", "RPC URL: $rpcUrl") + Log.i("DotBalanceIntegrationTest", "state_getStorage(Account) => $response") + + // Basic sanity: expect non-empty hex or null + assumeTrue("Unexpected storage response", response.contains("result")) + } + + private fun httpPost(urlStr: String, body: String): String { + val url = URL(urlStr) + val conn = (url.openConnection() as HttpURLConnection).apply { + requestMethod = "POST" + connectTimeout = 5000 + readTimeout = 10000 + doOutput = true + setRequestProperty("Content-Type", "application/json") + } + + OutputStreamWriter(conn.outputStream, Charsets.UTF_8).use { it.write(body) } + + val code = conn.responseCode + val stream = if (code in 200..299) conn.inputStream else conn.errorStream + val text = BufferedReader(stream.reader(Charsets.UTF_8)).use { it.readText() } + conn.disconnect() + return text + } +} + From 4684accb098ae6003576cb0136056e0478870b13 Mon Sep 17 00:00:00 2001 From: William Richter Date: Wed, 27 Aug 2025 15:57:10 +0200 Subject: [PATCH 12/18] build: fix Gradle deprecation warnings by using url = uri(...) and namespace = '...'; add androidTest packaging excludes for META-INF conflicts in runtime --- app/build.gradle | 4 +- build.gradle | 10 +- common/build.gradle | 6 +- core-api/build.gradle | 6 +- core-db/build.gradle | 4 +- .../74.json | 1574 +++++++++++++++++ crash.log | 1008 +++++++++++ feature-account-api/build.gradle | 6 +- feature-account-impl/build.gradle | 6 +- feature-crowdloan-api/build.gradle | 6 +- feature-crowdloan-impl/build.gradle | 6 +- feature-onboarding-api/build.gradle | 6 +- feature-onboarding-impl/build.gradle | 4 +- feature-soracard-api/build.gradle | 6 +- feature-splash/build.gradle | 4 +- feature-staking-api/build.gradle | 6 +- feature-staking-impl/build.gradle | 6 +- feature-wallet-api/build.gradle | 5 +- feature-wallet-impl/build.gradle | 6 +- runtime-permission/build.gradle | 6 +- runtime/build.gradle | 20 +- .../runtime/integration/DotIntegrationTest.kt | 68 + .../multiNetwork/chain/ChainsRepository.kt | 13 +- scripts/secrets.gradle | 5 +- test-shared/build.gradle | 6 +- 25 files changed, 2715 insertions(+), 82 deletions(-) create mode 100644 core-db/schemas/jp.co.soramitsu.coredb.AppDatabase/74.json create mode 100644 crash.log create mode 100644 runtime/src/androidTest/java/jp/co/soramitsu/runtime/integration/DotIntegrationTest.kt diff --git a/app/build.gradle b/app/build.gradle index 14ca3686a6..9e6e064341 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -127,8 +127,6 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } kotlin { @@ -142,7 +140,7 @@ android { lint { disable 'Instantiatable' } - namespace 'jp.co.soramitsu.app' + namespace = 'jp.co.soramitsu.app' packagingOptions { resources.excludes.add("META-INF/**/*") diff --git a/build.gradle b/build.gradle index 1e618f9220..16ae955565 100644 --- a/build.gradle +++ b/build.gradle @@ -19,8 +19,8 @@ buildscript { repositories { google() mavenCentral() - maven { url "https://plugins.gradle.org/m2/" } - maven { url 'https://maven.google.com' } + maven { url = uri("https://plugins.gradle.org/m2/") } + maven { url = uri('https://maven.google.com') } } dependencies { classpath libs.gradleplugins.android @@ -50,14 +50,14 @@ allprojects { repositories { google() mavenLocal() - maven { url "https://nexus.iroha.tech/repository/maven-soramitsu/" } + maven { url = uri("https://nexus.iroha.tech/repository/maven-soramitsu/") } mavenCentral() - maven { url "https://jitpack.io" } + maven { url = uri("https://jitpack.io") } def payRepoUrl = readSecret("PAY_WINGS_REPOSITORY_URL") if (payRepoUrl) { maven { - url = payRepoUrl + url = uri(payRepoUrl) credentials { username = readSecret("PAY_WINGS_USERNAME") ?: "" password = readSecret("PAY_WINGS_PASSWORD") ?: "" diff --git a/common/build.gradle b/common/build.gradle index c3bb9e14f3..73444da142 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -98,11 +98,9 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } - namespace 'jp.co.soramitsu.common' + namespace = 'jp.co.soramitsu.common' } dependencies { @@ -166,4 +164,4 @@ dependencies { testImplementation project(':test-shared') api libs.sharedFeaturesCoreDep -} \ No newline at end of file +} diff --git a/core-api/build.gradle b/core-api/build.gradle index ef5a9e5289..f5779555c5 100644 --- a/core-api/build.gradle +++ b/core-api/build.gradle @@ -18,14 +18,12 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } - namespace 'jp.co.soramitsu.core' + namespace = 'jp.co.soramitsu.core' } dependencies { implementation libs.coroutines.core implementation libs.sharedFeaturesCoreDep -} \ No newline at end of file +} diff --git a/core-db/build.gradle b/core-db/build.gradle index bbedeb0bad..fc0f5811ff 100644 --- a/core-db/build.gradle +++ b/core-db/build.gradle @@ -26,8 +26,6 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } @@ -65,4 +63,4 @@ dependencies { androidTestImplementation projects.testShared testImplementation libs.junit testImplementation projects.testShared -} \ No newline at end of file +} diff --git a/core-db/schemas/jp.co.soramitsu.coredb.AppDatabase/74.json b/core-db/schemas/jp.co.soramitsu.coredb.AppDatabase/74.json new file mode 100644 index 0000000000..adacaa223d --- /dev/null +++ b/core-db/schemas/jp.co.soramitsu.coredb.AppDatabase/74.json @@ -0,0 +1,1574 @@ +{ + "formatVersion": 1, + "database": { + "version": 74, + "identityHash": "76cc9e898252bb6822f7da6d30ce604e", + "entities": [ + { + "tableName": "address_book", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`address` TEXT NOT NULL, `name` TEXT, `chainId` TEXT NOT NULL, `created` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT" + }, + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "created", + "columnName": "created", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_address_book_address_chainId", + "unique": true, + "columnNames": [ + "address", + "chainId" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_address_book_address_chainId` ON `${TABLE_NAME}` (`address`, `chainId`)" + } + ] + }, + { + "tableName": "assets", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `chainId` TEXT NOT NULL, `accountId` BLOB NOT NULL, `metaId` INTEGER NOT NULL, `tokenPriceId` TEXT, `freeInPlanks` TEXT, `reservedInPlanks` TEXT, `miscFrozenInPlanks` TEXT, `feeFrozenInPlanks` TEXT, `bondedInPlanks` TEXT, `redeemableInPlanks` TEXT, `unbondingInPlanks` TEXT, `sortIndex` INTEGER NOT NULL, `enabled` INTEGER, `markedNotNeed` INTEGER NOT NULL, `chainAccountName` TEXT, `status` TEXT, PRIMARY KEY(`id`, `chainId`, `accountId`, `metaId`), FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountId", + "columnName": "accountId", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "metaId", + "columnName": "metaId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tokenPriceId", + "columnName": "tokenPriceId", + "affinity": "TEXT" + }, + { + "fieldPath": "freeInPlanks", + "columnName": "freeInPlanks", + "affinity": "TEXT" + }, + { + "fieldPath": "reservedInPlanks", + "columnName": "reservedInPlanks", + "affinity": "TEXT" + }, + { + "fieldPath": "miscFrozenInPlanks", + "columnName": "miscFrozenInPlanks", + "affinity": "TEXT" + }, + { + "fieldPath": "feeFrozenInPlanks", + "columnName": "feeFrozenInPlanks", + "affinity": "TEXT" + }, + { + "fieldPath": "bondedInPlanks", + "columnName": "bondedInPlanks", + "affinity": "TEXT" + }, + { + "fieldPath": "redeemableInPlanks", + "columnName": "redeemableInPlanks", + "affinity": "TEXT" + }, + { + "fieldPath": "unbondingInPlanks", + "columnName": "unbondingInPlanks", + "affinity": "TEXT" + }, + { + "fieldPath": "sortIndex", + "columnName": "sortIndex", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER" + }, + { + "fieldPath": "markedNotNeed", + "columnName": "markedNotNeed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "chainAccountName", + "columnName": "chainAccountName", + "affinity": "TEXT" + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id", + "chainId", + "accountId", + "metaId" + ] + }, + "indices": [ + { + "name": "index_assets_chainId", + "unique": false, + "columnNames": [ + "chainId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_assets_chainId` ON `${TABLE_NAME}` (`chainId`)" + }, + { + "name": "index_assets_metaId", + "unique": false, + "columnNames": [ + "metaId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_assets_metaId` ON `${TABLE_NAME}` (`metaId`)" + } + ], + "foreignKeys": [ + { + "table": "chains", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "chainId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "token_price", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`priceId` TEXT NOT NULL, `fiatSymbol` TEXT NOT NULL, `fiatRate` TEXT, `recentRateChange` TEXT, PRIMARY KEY(`priceId`))", + "fields": [ + { + "fieldPath": "priceId", + "columnName": "priceId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fiatSymbol", + "columnName": "fiatSymbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fiatRate", + "columnName": "fiatRate", + "affinity": "TEXT" + }, + { + "fieldPath": "recentRateChange", + "columnName": "recentRateChange", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "priceId" + ] + } + }, + { + "tableName": "phishing", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`address` TEXT NOT NULL, `name` TEXT, `type` TEXT NOT NULL, `subtype` TEXT, PRIMARY KEY(`address`, `type`))", + "fields": [ + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT" + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "subtype", + "columnName": "subtype", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "address", + "type" + ] + } + }, + { + "tableName": "storage", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`storageKey` TEXT NOT NULL, `content` TEXT, `chainId` TEXT NOT NULL, PRIMARY KEY(`chainId`, `storageKey`))", + "fields": [ + { + "fieldPath": "storageKey", + "columnName": "storageKey", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT" + }, + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "chainId", + "storageKey" + ] + } + }, + { + "tableName": "account_staking_accesses", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`chainId` TEXT NOT NULL, `chainAssetId` TEXT NOT NULL, `accountId` BLOB NOT NULL, `stashId` BLOB, `controllerId` BLOB, PRIMARY KEY(`chainId`, `chainAssetId`, `accountId`))", + "fields": [ + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "chainAssetId", + "columnName": "chainAssetId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountId", + "columnName": "accountId", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "stakingAccessInfo.stashId", + "columnName": "stashId", + "affinity": "BLOB" + }, + { + "fieldPath": "stakingAccessInfo.controllerId", + "columnName": "controllerId", + "affinity": "BLOB" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "chainId", + "chainAssetId", + "accountId" + ] + } + }, + { + "tableName": "total_reward", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`accountAddress` TEXT NOT NULL, `totalReward` TEXT NOT NULL, PRIMARY KEY(`accountAddress`))", + "fields": [ + { + "fieldPath": "accountAddress", + "columnName": "accountAddress", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "totalReward", + "columnName": "totalReward", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "accountAddress" + ] + } + }, + { + "tableName": "operations", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `address` TEXT NOT NULL, `chainId` TEXT NOT NULL, `chainAssetId` TEXT NOT NULL, `time` INTEGER NOT NULL, `status` INTEGER NOT NULL, `source` INTEGER NOT NULL, `operationType` INTEGER NOT NULL, `module` TEXT, `call` TEXT, `amount` TEXT, `sender` TEXT, `receiver` TEXT, `hash` TEXT, `fee` TEXT, `isReward` INTEGER, `era` INTEGER, `validator` TEXT, `liquidityFee` TEXT, `market` TEXT, `targetAssetId` TEXT, `targetAmount` TEXT, PRIMARY KEY(`id`, `address`, `chainId`, `chainAssetId`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "chainAssetId", + "columnName": "chainAssetId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "source", + "columnName": "source", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "operationType", + "columnName": "operationType", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "module", + "columnName": "module", + "affinity": "TEXT" + }, + { + "fieldPath": "call", + "columnName": "call", + "affinity": "TEXT" + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "TEXT" + }, + { + "fieldPath": "sender", + "columnName": "sender", + "affinity": "TEXT" + }, + { + "fieldPath": "receiver", + "columnName": "receiver", + "affinity": "TEXT" + }, + { + "fieldPath": "hash", + "columnName": "hash", + "affinity": "TEXT" + }, + { + "fieldPath": "fee", + "columnName": "fee", + "affinity": "TEXT" + }, + { + "fieldPath": "isReward", + "columnName": "isReward", + "affinity": "INTEGER" + }, + { + "fieldPath": "era", + "columnName": "era", + "affinity": "INTEGER" + }, + { + "fieldPath": "validator", + "columnName": "validator", + "affinity": "TEXT" + }, + { + "fieldPath": "liquidityFee", + "columnName": "liquidityFee", + "affinity": "TEXT" + }, + { + "fieldPath": "market", + "columnName": "market", + "affinity": "TEXT" + }, + { + "fieldPath": "targetAssetId", + "columnName": "targetAssetId", + "affinity": "TEXT" + }, + { + "fieldPath": "targetAmount", + "columnName": "targetAmount", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id", + "address", + "chainId", + "chainAssetId" + ] + } + }, + { + "tableName": "chains", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `paraId` TEXT, `parentId` TEXT, `rank` INTEGER, `name` TEXT NOT NULL, `minSupportedVersion` TEXT, `icon` TEXT NOT NULL, `prefix` INTEGER NOT NULL, `isEthereumBased` INTEGER NOT NULL, `isTestNet` INTEGER NOT NULL, `hasCrowdloans` INTEGER NOT NULL, `supportStakingPool` INTEGER NOT NULL, `isEthereumChain` INTEGER NOT NULL, `isChainlinkProvider` INTEGER NOT NULL, `supportNft` INTEGER NOT NULL, `isUsesAppId` INTEGER NOT NULL, `identityChain` TEXT, `ecosystem` TEXT NOT NULL, `androidMinAppVersion` TEXT, `remoteAssetsSource` TEXT, `tonBridgeUrl` TEXT, `staking_url` TEXT, `staking_type` TEXT, `history_url` TEXT, `history_type` TEXT, `crowdloans_url` TEXT, `crowdloans_type` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "paraId", + "columnName": "paraId", + "affinity": "TEXT" + }, + { + "fieldPath": "parentId", + "columnName": "parentId", + "affinity": "TEXT" + }, + { + "fieldPath": "rank", + "columnName": "rank", + "affinity": "INTEGER" + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "minSupportedVersion", + "columnName": "minSupportedVersion", + "affinity": "TEXT" + }, + { + "fieldPath": "icon", + "columnName": "icon", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "prefix", + "columnName": "prefix", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isEthereumBased", + "columnName": "isEthereumBased", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isTestNet", + "columnName": "isTestNet", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hasCrowdloans", + "columnName": "hasCrowdloans", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "supportStakingPool", + "columnName": "supportStakingPool", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isEthereumChain", + "columnName": "isEthereumChain", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isChainlinkProvider", + "columnName": "isChainlinkProvider", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "supportNft", + "columnName": "supportNft", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isUsesAppId", + "columnName": "isUsesAppId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "identityChain", + "columnName": "identityChain", + "affinity": "TEXT" + }, + { + "fieldPath": "ecosystem", + "columnName": "ecosystem", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "androidMinAppVersion", + "columnName": "androidMinAppVersion", + "affinity": "TEXT" + }, + { + "fieldPath": "remoteAssetsSource", + "columnName": "remoteAssetsSource", + "affinity": "TEXT" + }, + { + "fieldPath": "tonBridgeUrl", + "columnName": "tonBridgeUrl", + "affinity": "TEXT" + }, + { + "fieldPath": "externalApi.staking.url", + "columnName": "staking_url", + "affinity": "TEXT" + }, + { + "fieldPath": "externalApi.staking.type", + "columnName": "staking_type", + "affinity": "TEXT" + }, + { + "fieldPath": "externalApi.history.url", + "columnName": "history_url", + "affinity": "TEXT" + }, + { + "fieldPath": "externalApi.history.type", + "columnName": "history_type", + "affinity": "TEXT" + }, + { + "fieldPath": "externalApi.crowdloans.url", + "columnName": "crowdloans_url", + "affinity": "TEXT" + }, + { + "fieldPath": "externalApi.crowdloans.type", + "columnName": "crowdloans_type", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "chain_nodes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`chainId` TEXT NOT NULL, `url` TEXT NOT NULL, `name` TEXT NOT NULL, `isActive` INTEGER NOT NULL, `isDefault` INTEGER NOT NULL, PRIMARY KEY(`chainId`, `url`), FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isActive", + "columnName": "isActive", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isDefault", + "columnName": "isDefault", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "chainId", + "url" + ] + }, + "indices": [ + { + "name": "index_chain_nodes_chainId", + "unique": false, + "columnNames": [ + "chainId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_chain_nodes_chainId` ON `${TABLE_NAME}` (`chainId`)" + } + ], + "foreignKeys": [ + { + "table": "chains", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "chainId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "chain_assets", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT, `symbol` TEXT NOT NULL, `chainId` TEXT NOT NULL, `icon` TEXT NOT NULL, `priceId` TEXT, `staking` TEXT NOT NULL, `precision` INTEGER NOT NULL, `purchaseProviders` TEXT, `isUtility` INTEGER, `type` TEXT, `currencyId` TEXT, `existentialDeposit` TEXT, `color` TEXT, `isNative` INTEGER, `priceProvider` TEXT, `coinbaseUrl` TEXT, PRIMARY KEY(`chainId`, `id`), FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT" + }, + { + "fieldPath": "symbol", + "columnName": "symbol", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "icon", + "columnName": "icon", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "priceId", + "columnName": "priceId", + "affinity": "TEXT" + }, + { + "fieldPath": "staking", + "columnName": "staking", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "precision", + "columnName": "precision", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "purchaseProviders", + "columnName": "purchaseProviders", + "affinity": "TEXT" + }, + { + "fieldPath": "isUtility", + "columnName": "isUtility", + "affinity": "INTEGER" + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT" + }, + { + "fieldPath": "currencyId", + "columnName": "currencyId", + "affinity": "TEXT" + }, + { + "fieldPath": "existentialDeposit", + "columnName": "existentialDeposit", + "affinity": "TEXT" + }, + { + "fieldPath": "color", + "columnName": "color", + "affinity": "TEXT" + }, + { + "fieldPath": "isNative", + "columnName": "isNative", + "affinity": "INTEGER" + }, + { + "fieldPath": "priceProvider", + "columnName": "priceProvider", + "affinity": "TEXT" + }, + { + "fieldPath": "coinbaseUrl", + "columnName": "coinbaseUrl", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "chainId", + "id" + ] + }, + "indices": [ + { + "name": "index_chain_assets_chainId", + "unique": false, + "columnNames": [ + "chainId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_chain_assets_chainId` ON `${TABLE_NAME}` (`chainId`)" + } + ], + "foreignKeys": [ + { + "table": "chains", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "chainId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "favorite_chains", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`metaId` INTEGER NOT NULL, `chainId` TEXT NOT NULL, `isFavorite` INTEGER NOT NULL, PRIMARY KEY(`metaId`, `chainId`), FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "metaId", + "columnName": "metaId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isFavorite", + "columnName": "isFavorite", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "metaId", + "chainId" + ] + }, + "foreignKeys": [ + { + "table": "chains", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "chainId" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "meta_accounts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "metaId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "chain_runtimes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`chainId` TEXT NOT NULL, `syncedVersion` INTEGER NOT NULL, `remoteVersion` INTEGER NOT NULL, PRIMARY KEY(`chainId`))", + "fields": [ + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "syncedVersion", + "columnName": "syncedVersion", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteVersion", + "columnName": "remoteVersion", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "chainId" + ] + }, + "indices": [ + { + "name": "index_chain_runtimes_chainId", + "unique": false, + "columnNames": [ + "chainId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_chain_runtimes_chainId` ON `${TABLE_NAME}` (`chainId`)" + } + ] + }, + { + "tableName": "meta_accounts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`substratePublicKey` BLOB, `substrateCryptoType` TEXT, `substrateAccountId` BLOB, `ethereumPublicKey` BLOB, `ethereumAddress` BLOB, `tonPublicKey` BLOB, `name` TEXT NOT NULL, `isSelected` INTEGER NOT NULL, `position` INTEGER NOT NULL, `isBackedUp` INTEGER NOT NULL, `googleBackupAddress` TEXT, `initialized` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)", + "fields": [ + { + "fieldPath": "substratePublicKey", + "columnName": "substratePublicKey", + "affinity": "BLOB" + }, + { + "fieldPath": "substrateCryptoType", + "columnName": "substrateCryptoType", + "affinity": "TEXT" + }, + { + "fieldPath": "substrateAccountId", + "columnName": "substrateAccountId", + "affinity": "BLOB" + }, + { + "fieldPath": "ethereumPublicKey", + "columnName": "ethereumPublicKey", + "affinity": "BLOB" + }, + { + "fieldPath": "ethereumAddress", + "columnName": "ethereumAddress", + "affinity": "BLOB" + }, + { + "fieldPath": "tonPublicKey", + "columnName": "tonPublicKey", + "affinity": "BLOB" + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isSelected", + "columnName": "isSelected", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isBackedUp", + "columnName": "isBackedUp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "googleBackupAddress", + "columnName": "googleBackupAddress", + "affinity": "TEXT" + }, + { + "fieldPath": "initialized", + "columnName": "initialized", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_meta_accounts_substrateAccountId", + "unique": false, + "columnNames": [ + "substrateAccountId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_meta_accounts_substrateAccountId` ON `${TABLE_NAME}` (`substrateAccountId`)" + }, + { + "name": "index_meta_accounts_ethereumAddress", + "unique": false, + "columnNames": [ + "ethereumAddress" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_meta_accounts_ethereumAddress` ON `${TABLE_NAME}` (`ethereumAddress`)" + }, + { + "name": "index_meta_accounts_tonPublicKey", + "unique": false, + "columnNames": [ + "tonPublicKey" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_meta_accounts_tonPublicKey` ON `${TABLE_NAME}` (`tonPublicKey`)" + } + ] + }, + { + "tableName": "chain_accounts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`metaId` INTEGER NOT NULL, `chainId` TEXT NOT NULL, `publicKey` BLOB NOT NULL, `accountId` BLOB NOT NULL, `cryptoType` TEXT NOT NULL, `name` TEXT NOT NULL, `initialized` INTEGER NOT NULL, PRIMARY KEY(`metaId`, `chainId`), FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "metaId", + "columnName": "metaId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "publicKey", + "columnName": "publicKey", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "accountId", + "columnName": "accountId", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "cryptoType", + "columnName": "cryptoType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "initialized", + "columnName": "initialized", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "metaId", + "chainId" + ] + }, + "indices": [ + { + "name": "index_chain_accounts_chainId", + "unique": false, + "columnNames": [ + "chainId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_chain_accounts_chainId` ON `${TABLE_NAME}` (`chainId`)" + }, + { + "name": "index_chain_accounts_metaId", + "unique": false, + "columnNames": [ + "metaId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_chain_accounts_metaId` ON `${TABLE_NAME}` (`metaId`)" + }, + { + "name": "index_chain_accounts_accountId", + "unique": false, + "columnNames": [ + "accountId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_chain_accounts_accountId` ON `${TABLE_NAME}` (`accountId`)" + } + ], + "foreignKeys": [ + { + "table": "chains", + "onDelete": "NO ACTION", + "onUpdate": "NO ACTION", + "columns": [ + "chainId" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "meta_accounts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "metaId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "chain_explorers", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`chainId` TEXT NOT NULL, `type` TEXT NOT NULL, `types` TEXT NOT NULL, `url` TEXT NOT NULL, PRIMARY KEY(`chainId`, `type`), FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "types", + "columnName": "types", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "chainId", + "type" + ] + }, + "indices": [ + { + "name": "index_chain_explorers_chainId", + "unique": false, + "columnNames": [ + "chainId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_chain_explorers_chainId` ON `${TABLE_NAME}` (`chainId`)" + } + ], + "foreignKeys": [ + { + "table": "chains", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "chainId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "sora_card", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `accessToken` TEXT NOT NULL, `refreshToken` TEXT NOT NULL, `accessTokenExpirationTime` INTEGER NOT NULL, `kycStatus` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accessToken", + "columnName": "accessToken", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "refreshToken", + "columnName": "refreshToken", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accessTokenExpirationTime", + "columnName": "accessTokenExpirationTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "kycStatus", + "columnName": "kycStatus", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "chain_types", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`chainId` TEXT NOT NULL, `typesConfig` TEXT NOT NULL, PRIMARY KEY(`chainId`))", + "fields": [ + { + "fieldPath": "chainId", + "columnName": "chainId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "typesConfig", + "columnName": "typesConfig", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "chainId" + ] + } + }, + { + "tableName": "nomis_wallet_score", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`metaId` INTEGER NOT NULL, `score` INTEGER NOT NULL, `updated` INTEGER NOT NULL, `nativeBalanceUsd` TEXT NOT NULL, `holdTokensUsd` TEXT NOT NULL, `walletAgeInMonths` INTEGER NOT NULL, `totalTransactions` INTEGER NOT NULL, `rejectedTransactions` INTEGER NOT NULL, `avgTransactionTimeInHours` REAL NOT NULL, `maxTransactionTimeInHours` REAL NOT NULL, `minTransactionTimeInHours` REAL NOT NULL, `scoredAt` TEXT NOT NULL, PRIMARY KEY(`metaId`), FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "metaId", + "columnName": "metaId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "score", + "columnName": "score", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "updated", + "columnName": "updated", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "nativeBalanceUsd", + "columnName": "nativeBalanceUsd", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "holdTokensUsd", + "columnName": "holdTokensUsd", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "walletAgeInMonths", + "columnName": "walletAgeInMonths", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "totalTransactions", + "columnName": "totalTransactions", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "rejectedTransactions", + "columnName": "rejectedTransactions", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "avgTransactionTimeInHours", + "columnName": "avgTransactionTimeInHours", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "maxTransactionTimeInHours", + "columnName": "maxTransactionTimeInHours", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "minTransactionTimeInHours", + "columnName": "minTransactionTimeInHours", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "scoredAt", + "columnName": "scoredAt", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "metaId" + ] + }, + "foreignKeys": [ + { + "table": "meta_accounts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "metaId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "allpools", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tokenIdBase` TEXT NOT NULL, `tokenIdTarget` TEXT NOT NULL, `reserveBase` TEXT NOT NULL, `reserveTarget` TEXT NOT NULL, `totalIssuance` TEXT NOT NULL, `reservesAccount` TEXT NOT NULL, PRIMARY KEY(`tokenIdBase`, `tokenIdTarget`))", + "fields": [ + { + "fieldPath": "tokenIdBase", + "columnName": "tokenIdBase", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "tokenIdTarget", + "columnName": "tokenIdTarget", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "reserveBase", + "columnName": "reserveBase", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "reserveTarget", + "columnName": "reserveTarget", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "totalIssuance", + "columnName": "totalIssuance", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "reservesAccount", + "columnName": "reservesAccount", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "tokenIdBase", + "tokenIdTarget" + ] + } + }, + { + "tableName": "userpools", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userTokenIdBase` TEXT NOT NULL, `userTokenIdTarget` TEXT NOT NULL, `accountAddress` TEXT NOT NULL, `poolProvidersBalance` TEXT NOT NULL, PRIMARY KEY(`userTokenIdBase`, `userTokenIdTarget`, `accountAddress`), FOREIGN KEY(`userTokenIdBase`, `userTokenIdTarget`) REFERENCES `allpools`(`tokenIdBase`, `tokenIdTarget`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "userTokenIdBase", + "columnName": "userTokenIdBase", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "userTokenIdTarget", + "columnName": "userTokenIdTarget", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountAddress", + "columnName": "accountAddress", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "poolProvidersBalance", + "columnName": "poolProvidersBalance", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "userTokenIdBase", + "userTokenIdTarget", + "accountAddress" + ] + }, + "indices": [ + { + "name": "index_userpools_accountAddress", + "unique": false, + "columnNames": [ + "accountAddress" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_userpools_accountAddress` ON `${TABLE_NAME}` (`accountAddress`)" + } + ], + "foreignKeys": [ + { + "table": "allpools", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "userTokenIdBase", + "userTokenIdTarget" + ], + "referencedColumns": [ + "tokenIdBase", + "tokenIdTarget" + ] + } + ] + }, + { + "tableName": "ton_connection", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`metaId` INTEGER NOT NULL, `clientId` TEXT NOT NULL, `name` TEXT NOT NULL, `icon` TEXT NOT NULL, `url` TEXT NOT NULL, `source` TEXT NOT NULL, PRIMARY KEY(`metaId`, `url`, `source`), FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "metaId", + "columnName": "metaId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "clientId", + "columnName": "clientId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "icon", + "columnName": "icon", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "source", + "columnName": "source", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "metaId", + "url", + "source" + ] + }, + "foreignKeys": [ + { + "table": "meta_accounts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "metaId" + ], + "referencedColumns": [ + "id" + ] + } + ] + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '76cc9e898252bb6822f7da6d30ce604e')" + ] + } +} \ No newline at end of file diff --git a/crash.log b/crash.log new file mode 100644 index 0000000000..9e9020f184 --- /dev/null +++ b/crash.log @@ -0,0 +1,1008 @@ +08-04 15:06:31.593 E/AndroidRuntime( 2759): FATAL EXCEPTION: main +08-04 15:06:31.593 E/AndroidRuntime( 2759): Process: com.instagram.android, PID: 2759 +08-04 15:06:31.593 E/AndroidRuntime( 2759): android.view.InflateException: Binary XML file line #97: Binary XML file line #97: You must supply a layout_height attribute., theme={InheritanceMap=[id=0x7f1402a2com.instagram.android:style/IgdsPrismIndigoBadgeIndigoTextLinkExperiment, id=0x7f1402a1com.instagram.android:style/IgdsPrismIndigoBadgeIndigoTextLinkDark, id=0x7f1402a6com.instagram.android:style/IgdsPrismIndigoBrightTextLinkExperimentDark, id=0x7f1402aacom.instagram.android:style/IgdsPrismSemanticColorsExperimentDark, id=0x7f1402adcom.instagram.android:style/IgdsSemanticColorsDark], Themes=[com.instagram.android:style/IgdsPrismIndigoBadgeIndigoTextLinkExperiment, forced, com.instagram.android:style/BrowserFullscreen, forced, com.instagram.android:style/ExoStyledControls, forced, android:style/Theme.DeviceDefault.Light.DarkActionBar, forced]} +08-04 15:06:31.593 E/AndroidRuntime( 2759): Caused by: java.lang.UnsupportedOperationException: Binary XML file line #97: You must supply a layout_height attribute., theme={InheritanceMap=[id=0x7f1402a2com.instagram.android:style/IgdsPrismIndigoBadgeIndigoTextLinkExperiment, id=0x7f1402a1com.instagram.android:style/IgdsPrismIndigoBadgeIndigoTextLinkDark, id=0x7f1402a6com.instagram.android:style/IgdsPrismIndigoBrightTextLinkExperimentDark, id=0x7f1402aacom.instagram.android:style/IgdsPrismSemanticColorsExperimentDark, id=0x7f1402adcom.instagram.android:style/IgdsSemanticColorsDark], Themes=[com.instagram.android:style/IgdsPrismIndigoBadgeIndigoTextLinkExperiment, forced, com.instagram.android:style/BrowserFullscreen, forced, com.instagram.android:style/ExoStyledControls, forced, android:style/Theme.DeviceDefault.Light.DarkActionBar, forced]} +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:843) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:8754) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.view.ViewGroup$MarginLayoutParams.(ViewGroup.java:8951) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.widget.RelativeLayout$LayoutParams.(RelativeLayout.java:1325) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.widget.RelativeLayout.generateLayoutParams(RelativeLayout.java:1139) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.widget.RelativeLayout.generateLayoutParams(RelativeLayout.java:100) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.view.LayoutInflater.rInflate(LayoutInflater.java:1029) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.view.LayoutInflater.inflate(LayoutInflater.java:546) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.5pU.inflate(:268435460) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.view.LayoutInflater.inflate(LayoutInflater.java:468) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.5pU.inflate(:8) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.5pT.inflate(:262) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.view.LayoutInflater.inflate(LayoutInflater.java:419) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at com.facebook.browser.lite.chrome.container.DefaultBrowserLiteChrome.D4m(:57) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.PrT.Feg(:24) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at com.facebook.browser.lite.BrowserLiteFragment.onActivityCreated(:1653) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at androidx.fragment.app.Fragment.performActivityCreated(:11) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.0Im.A03(:475) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.0Ic.A0l(:56) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.0Ic.A0C(:33) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.0Ic.A0Y(:11) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at androidx.fragment.app.FragmentActivity.onStart(:29) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at androidx.appcompat.app.AppCompatActivity.onStart(:7) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at com.instagram.base.activity.IgFragmentActivity.onStart(:122) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1701) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.app.Activity.performStart(Activity.java:9406) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.app.ActivityThread.handleStartActivity(ActivityThread.java:4488) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:270) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:250) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.app.servertransaction.TransactionExecutor.executeLifecycleItem(TransactionExecutor.java:222) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:107) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:81) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2895) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.0ea.A00(:13) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.265.A89(:87) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at X.0ea.handleMessage(:37) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.os.Handler.dispatchMessage(Handler.java:103) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.os.Looper.loopOnce(Looper.java:257) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.os.Looper.loop(Looper.java:342) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at android.app.ActivityThread.main(ActivityThread.java:9634) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at java.lang.reflect.Method.invoke(Native Method) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619) +08-04 15:06:31.593 E/AndroidRuntime( 2759): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) +08-14 19:07:05.733 E/AndroidRuntime(14912): FATAL EXCEPTION: main +08-14 19:07:05.733 E/AndroidRuntime(14912): Process: com.instagram.android, PID: 14912 +08-14 19:07:05.733 E/AndroidRuntime(14912): java.lang.ClassCastException: X.7gN cannot be cast to X.8Ai +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.5vB.A07(:63) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.5vB.A04(:6) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.5vB.A06(:110) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.5vB.A05(:40) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.5vB.bindView(:156) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.5AX.A0q(:133) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.5AU.A0q(:259) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.5AX.A0d(:2) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.3eO.A0T(:179) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.3b0.A02(:67) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.3b0.A05(:239) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.3yN.A00(:64) +08-14 19:07:05.733 E/AndroidRuntime(14912): at X.3yN.run(:242) +08-14 19:07:05.733 E/AndroidRuntime(14912): at android.os.Handler.handleCallback(Handler.java:959) +08-14 19:07:05.733 E/AndroidRuntime(14912): at android.os.Handler.dispatchMessage(Handler.java:100) +08-14 19:07:05.733 E/AndroidRuntime(14912): at android.os.Looper.loopOnce(Looper.java:257) +08-14 19:07:05.733 E/AndroidRuntime(14912): at android.os.Looper.loop(Looper.java:342) +08-14 19:07:05.733 E/AndroidRuntime(14912): at android.app.ActivityThread.main(ActivityThread.java:9634) +08-14 19:07:05.733 E/AndroidRuntime(14912): at java.lang.reflect.Method.invoke(Native Method) +08-14 19:07:05.733 E/AndroidRuntime(14912): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619) +08-14 19:07:05.733 E/AndroidRuntime(14912): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) +08-14 19:07:16.950 E/AndroidRuntime(15564): FATAL EXCEPTION: main +08-14 19:07:16.950 E/AndroidRuntime(15564): Process: com.instagram.android, PID: 15564 +08-14 19:07:16.950 E/AndroidRuntime(15564): java.lang.ClassCastException: X.7gN cannot be cast to X.8Ai +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.5vB.A07(:63) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.5vB.A04(:6) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.5vB.A06(:110) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.5vB.A05(:40) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.5vB.bindView(:156) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.5AX.A0q(:133) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.5AU.A0q(:259) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.5AX.A0d(:2) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.3eO.A0T(:179) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.3b0.A02(:67) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.3b0.A05(:239) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.3yN.A00(:64) +08-14 19:07:16.950 E/AndroidRuntime(15564): at X.3yN.run(:242) +08-14 19:07:16.950 E/AndroidRuntime(15564): at android.os.Handler.handleCallback(Handler.java:959) +08-14 19:07:16.950 E/AndroidRuntime(15564): at android.os.Handler.dispatchMessage(Handler.java:100) +08-14 19:07:16.950 E/AndroidRuntime(15564): at android.os.Looper.loopOnce(Looper.java:257) +08-14 19:07:16.950 E/AndroidRuntime(15564): at android.os.Looper.loop(Looper.java:342) +08-14 19:07:16.950 E/AndroidRuntime(15564): at android.app.ActivityThread.main(ActivityThread.java:9634) +08-14 19:07:16.950 E/AndroidRuntime(15564): at java.lang.reflect.Method.invoke(Native Method) +08-14 19:07:16.950 E/AndroidRuntime(15564): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619) +08-14 19:07:16.950 E/AndroidRuntime(15564): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) +08-14 19:07:34.198 E/AndroidRuntime(16026): FATAL EXCEPTION: main +08-14 19:07:34.198 E/AndroidRuntime(16026): Process: com.instagram.android, PID: 16026 +08-14 19:07:34.198 E/AndroidRuntime(16026): java.lang.ClassCastException: X.7gN cannot be cast to X.8Ai +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.5vB.A07(:63) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.5vB.A04(:6) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.5vB.A06(:110) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.5vB.A05(:40) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.5vB.bindView(:156) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.5AX.A0q(:133) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.5AU.A0q(:259) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.5AX.A0d(:2) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.3eO.A0T(:179) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.3b0.A02(:67) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.3b0.A05(:239) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.3yN.A00(:64) +08-14 19:07:34.198 E/AndroidRuntime(16026): at X.3yN.run(:242) +08-14 19:07:34.198 E/AndroidRuntime(16026): at android.os.Handler.handleCallback(Handler.java:959) +08-14 19:07:34.198 E/AndroidRuntime(16026): at android.os.Handler.dispatchMessage(Handler.java:100) +08-14 19:07:34.198 E/AndroidRuntime(16026): at android.os.Looper.loopOnce(Looper.java:257) +08-14 19:07:34.198 E/AndroidRuntime(16026): at android.os.Looper.loop(Looper.java:342) +08-14 19:07:34.198 E/AndroidRuntime(16026): at android.app.ActivityThread.main(ActivityThread.java:9634) +08-14 19:07:34.198 E/AndroidRuntime(16026): at java.lang.reflect.Method.invoke(Native Method) +08-14 19:07:34.198 E/AndroidRuntime(16026): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619) +08-14 19:07:34.198 E/AndroidRuntime(16026): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) +08-14 20:26:29.568 E/AndroidRuntime( 7820): FATAL EXCEPTION: main +08-14 20:26:29.568 E/AndroidRuntime( 7820): Process: com.instagram.android, PID: 7820 +08-14 20:26:29.568 E/AndroidRuntime( 7820): java.lang.ClassCastException: X.7gN cannot be cast to X.8Ai +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.5vB.A07(:63) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.5vB.A04(:6) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.5vB.A06(:110) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.5vB.A05(:40) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.5vB.bindView(:156) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.5AX.A0q(:133) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.5AU.A0q(:259) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.5AX.A0d(:2) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.3eO.A0T(:179) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.3b0.A02(:67) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.3b0.A05(:239) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.3yN.A00(:64) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at X.3yN.run(:242) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at android.os.Handler.handleCallback(Handler.java:959) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at android.os.Handler.dispatchMessage(Handler.java:100) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at android.os.Looper.loopOnce(Looper.java:257) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at android.os.Looper.loop(Looper.java:342) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at android.app.ActivityThread.main(ActivityThread.java:9634) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at java.lang.reflect.Method.invoke(Native Method) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619) +08-14 20:26:29.568 E/AndroidRuntime( 7820): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) +08-25 18:22:31.466 E/AndroidRuntime(14579): FATAL EXCEPTION: main +08-25 18:22:31.466 E/AndroidRuntime(14579): Process: jp.co.soramitsu.fearless.debug, PID: 14579 +08-25 18:22:31.466 E/AndroidRuntime(14579): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-25 18:22:31.466 E/AndroidRuntime(14579): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-25 18:22:31.466 E/AndroidRuntime(14579): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-25 18:22:31.466 E/AndroidRuntime(14579): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-25 18:22:31.466 E/AndroidRuntime(14579): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-25 18:22:31.466 E/AndroidRuntime(14579): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-25 18:22:31.466 E/AndroidRuntime(14579): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-25 18:22:31.466 E/AndroidRuntime(14579): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-25 18:22:31.466 E/AndroidRuntime(14579): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-25 18:22:31.466 E/AndroidRuntime(14579): at java.lang.Thread.run(Thread.java:1012) +08-25 18:22:31.466 E/AndroidRuntime(14579): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@ffd4b88, Dispatchers.Main.immediate] +08-25 18:22:58.421 E/AndroidRuntime(21574): FATAL EXCEPTION: main +08-25 18:22:58.421 E/AndroidRuntime(21574): Process: jp.co.soramitsu.fearless.debug, PID: 21574 +08-25 18:22:58.421 E/AndroidRuntime(21574): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-25 18:22:58.421 E/AndroidRuntime(21574): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-25 18:22:58.421 E/AndroidRuntime(21574): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-25 18:22:58.421 E/AndroidRuntime(21574): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-25 18:22:58.421 E/AndroidRuntime(21574): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-25 18:22:58.421 E/AndroidRuntime(21574): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-25 18:22:58.421 E/AndroidRuntime(21574): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-25 18:22:58.421 E/AndroidRuntime(21574): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-25 18:22:58.421 E/AndroidRuntime(21574): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-25 18:22:58.421 E/AndroidRuntime(21574): at java.lang.Thread.run(Thread.java:1012) +08-25 18:22:58.421 E/AndroidRuntime(21574): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@e4502ab, Dispatchers.Main.immediate] +08-25 18:23:31.672 E/AndroidRuntime(23042): FATAL EXCEPTION: main +08-25 18:23:31.672 E/AndroidRuntime(23042): Process: jp.co.soramitsu.fearless.debug, PID: 23042 +08-25 18:23:31.672 E/AndroidRuntime(23042): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-25 18:23:31.672 E/AndroidRuntime(23042): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-25 18:23:31.672 E/AndroidRuntime(23042): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-25 18:23:31.672 E/AndroidRuntime(23042): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-25 18:23:31.672 E/AndroidRuntime(23042): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-25 18:23:31.672 E/AndroidRuntime(23042): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-25 18:23:31.672 E/AndroidRuntime(23042): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-25 18:23:31.672 E/AndroidRuntime(23042): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-25 18:23:31.672 E/AndroidRuntime(23042): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-25 18:23:31.672 E/AndroidRuntime(23042): at java.lang.Thread.run(Thread.java:1012) +08-25 18:23:31.672 E/AndroidRuntime(23042): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@7b3cb01, Dispatchers.Main.immediate] +08-25 18:23:53.075 E/AndroidRuntime(24193): FATAL EXCEPTION: main +08-25 18:23:53.075 E/AndroidRuntime(24193): Process: jp.co.soramitsu.fearless.debug, PID: 24193 +08-25 18:23:53.075 E/AndroidRuntime(24193): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-25 18:23:53.075 E/AndroidRuntime(24193): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-25 18:23:53.075 E/AndroidRuntime(24193): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-25 18:23:53.075 E/AndroidRuntime(24193): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-25 18:23:53.075 E/AndroidRuntime(24193): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-25 18:23:53.075 E/AndroidRuntime(24193): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-25 18:23:53.075 E/AndroidRuntime(24193): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-25 18:23:53.075 E/AndroidRuntime(24193): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-25 18:23:53.075 E/AndroidRuntime(24193): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-25 18:23:53.075 E/AndroidRuntime(24193): at java.lang.Thread.run(Thread.java:1012) +08-25 18:23:53.075 E/AndroidRuntime(24193): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@a77aed9, Dispatchers.Main.immediate] +08-25 18:25:27.940 E/AndroidRuntime(25249): FATAL EXCEPTION: main +08-25 18:25:27.940 E/AndroidRuntime(25249): Process: jp.co.soramitsu.fearless.debug, PID: 25249 +08-25 18:25:27.940 E/AndroidRuntime(25249): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-25 18:25:27.940 E/AndroidRuntime(25249): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-25 18:25:27.940 E/AndroidRuntime(25249): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-25 18:25:27.940 E/AndroidRuntime(25249): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-25 18:25:27.940 E/AndroidRuntime(25249): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-25 18:25:27.940 E/AndroidRuntime(25249): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-25 18:25:27.940 E/AndroidRuntime(25249): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-25 18:25:27.940 E/AndroidRuntime(25249): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-25 18:25:27.940 E/AndroidRuntime(25249): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-25 18:25:27.940 E/AndroidRuntime(25249): at java.lang.Thread.run(Thread.java:1012) +08-25 18:25:27.940 E/AndroidRuntime(25249): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@2e063be, Dispatchers.Main.immediate] +08-26 11:11:33.808 E/AndroidRuntime(31384): FATAL EXCEPTION: main +08-26 11:11:33.808 E/AndroidRuntime(31384): Process: jp.co.soramitsu.fearless, PID: 31384 +08-26 11:11:33.808 E/AndroidRuntime(31384): java.lang.IllegalStateException: cannot find accountId +08-26 11:11:33.808 E/AndroidRuntime(31384): at gh.a$x.invokeSuspend(Unknown Source:35) +08-26 11:11:33.808 E/AndroidRuntime(31384): at gh.a$x.a(Unknown Source:13) +08-26 11:11:33.808 E/AndroidRuntime(31384): at gh.a$x.invoke(Unknown Source:6) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.flow.FlowKt__ZipKt$combine$1$1.invokeSuspend(Unknown Source:57) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.flow.FlowKt__ZipKt$combine$1$1.invoke(SourceFile:2) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.flow.FlowKt__ZipKt$combine$1$1.invoke(SourceFile:1) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2.invokeSuspend(Unknown Source:267) +08-26 11:11:33.808 E/AndroidRuntime(31384): at hk.a.resumeWith(Unknown Source:11) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.DispatchedTaskKt.resume(Unknown Source:61) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(Unknown Source:24) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.DispatchedTaskKt.dispatch(Unknown Source:47) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(Unknown Source:7) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.CancellableContinuationImpl.completeResume(Unknown Source:2) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.channels.BufferedChannelKt.tryResume0(Unknown Source:7) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.channels.BufferedChannelKt.access$tryResume0(Unknown Source:0) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.channels.BufferedChannel.tryResumeReceiver(Unknown Source:49) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.channels.BufferedChannel.updateCellSend(Unknown Source:52) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.channels.BufferedChannel.access$updateCellSend(Unknown Source:0) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.channels.BufferedChannel.send$suspendImpl(Unknown Source:70) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.channels.BufferedChannel.send(Unknown Source:0) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.flow.internal.CombineKt$combineInternal$2$1$1.emit(Unknown Source:70) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Unknown Source:141) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.flow.FlowKt__ChannelsKt.access$emitAllImpl$FlowKt__ChannelsKt(Unknown Source:0) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend(Unknown Source:11) +08-26 11:11:33.808 E/AndroidRuntime(31384): at hk.a.resumeWith(Unknown Source:11) +08-26 11:11:33.808 E/AndroidRuntime(31384): at kotlinx.coroutines.DispatchedTask.run(Unknown Source:128) +08-26 11:11:33.808 E/AndroidRuntime(31384): at android.os.Handler.handleCallback(Handler.java:959) +08-26 11:11:33.808 E/AndroidRuntime(31384): at android.os.Handler.dispatchMessage(Handler.java:100) +08-26 11:11:33.808 E/AndroidRuntime(31384): at android.os.Looper.loopOnce(Looper.java:257) +08-26 11:11:33.808 E/AndroidRuntime(31384): at android.os.Looper.loop(Looper.java:342) +08-26 11:11:33.808 E/AndroidRuntime(31384): at android.app.ActivityThread.main(ActivityThread.java:9634) +08-26 11:11:33.808 E/AndroidRuntime(31384): at java.lang.reflect.Method.invoke(Native Method) +08-26 11:11:33.808 E/AndroidRuntime(31384): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:619) +08-26 11:11:33.808 E/AndroidRuntime(31384): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929) +08-26 11:11:33.808 E/AndroidRuntime(31384): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@6bb2ed2, Dispatchers.Main.immediate] +08-26 11:22:27.268 E/AndroidRuntime(12523): FATAL EXCEPTION: main +08-26 11:22:27.268 E/AndroidRuntime(12523): Process: jp.co.soramitsu.fearless.debug, PID: 12523 +08-26 11:22:27.268 E/AndroidRuntime(12523): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-26 11:22:27.268 E/AndroidRuntime(12523): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-26 11:22:27.268 E/AndroidRuntime(12523): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-26 11:22:27.268 E/AndroidRuntime(12523): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 11:22:27.268 E/AndroidRuntime(12523): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 11:22:27.268 E/AndroidRuntime(12523): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 11:22:27.268 E/AndroidRuntime(12523): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 11:22:27.268 E/AndroidRuntime(12523): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 11:22:27.268 E/AndroidRuntime(12523): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 11:22:27.268 E/AndroidRuntime(12523): at java.lang.Thread.run(Thread.java:1012) +08-26 11:22:27.268 E/AndroidRuntime(12523): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@5eef2c, Dispatchers.Main.immediate] +08-26 11:38:50.150 E/AndroidRuntime(23881): FATAL EXCEPTION: main +08-26 11:38:50.150 E/AndroidRuntime(23881): Process: jp.co.soramitsu.fearless.debug, PID: 23881 +08-26 11:38:50.150 E/AndroidRuntime(23881): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-26 11:38:50.150 E/AndroidRuntime(23881): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-26 11:38:50.150 E/AndroidRuntime(23881): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-26 11:38:50.150 E/AndroidRuntime(23881): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 11:38:50.150 E/AndroidRuntime(23881): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 11:38:50.150 E/AndroidRuntime(23881): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 11:38:50.150 E/AndroidRuntime(23881): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 11:38:50.150 E/AndroidRuntime(23881): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 11:38:50.150 E/AndroidRuntime(23881): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 11:38:50.150 E/AndroidRuntime(23881): at java.lang.Thread.run(Thread.java:1012) +08-26 11:38:50.150 E/AndroidRuntime(23881): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@f77270e, Dispatchers.Main.immediate] +08-26 11:39:18.388 E/AndroidRuntime(29388): FATAL EXCEPTION: main +08-26 11:39:18.388 E/AndroidRuntime(29388): Process: jp.co.soramitsu.fearless.debug, PID: 29388 +08-26 11:39:18.388 E/AndroidRuntime(29388): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-26 11:39:18.388 E/AndroidRuntime(29388): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-26 11:39:18.388 E/AndroidRuntime(29388): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-26 11:39:18.388 E/AndroidRuntime(29388): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 11:39:18.388 E/AndroidRuntime(29388): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 11:39:18.388 E/AndroidRuntime(29388): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 11:39:18.388 E/AndroidRuntime(29388): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 11:39:18.388 E/AndroidRuntime(29388): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 11:39:18.388 E/AndroidRuntime(29388): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 11:39:18.388 E/AndroidRuntime(29388): at java.lang.Thread.run(Thread.java:1012) +08-26 11:39:18.388 E/AndroidRuntime(29388): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@904a5e8, Dispatchers.Main.immediate] +08-26 12:11:16.085 E/AndroidRuntime(10366): FATAL EXCEPTION: main +08-26 12:11:16.085 E/AndroidRuntime(10366): Process: jp.co.soramitsu.fearless.debug, PID: 10366 +08-26 12:11:16.085 E/AndroidRuntime(10366): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-26 12:11:16.085 E/AndroidRuntime(10366): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-26 12:11:16.085 E/AndroidRuntime(10366): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-26 12:11:16.085 E/AndroidRuntime(10366): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 12:11:16.085 E/AndroidRuntime(10366): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 12:11:16.085 E/AndroidRuntime(10366): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 12:11:16.085 E/AndroidRuntime(10366): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 12:11:16.085 E/AndroidRuntime(10366): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 12:11:16.085 E/AndroidRuntime(10366): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 12:11:16.085 E/AndroidRuntime(10366): at java.lang.Thread.run(Thread.java:1012) +08-26 12:11:16.085 E/AndroidRuntime(10366): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@3a2c776, Dispatchers.Main.immediate] +08-26 12:11:40.777 E/AndroidRuntime(15331): FATAL EXCEPTION: main +08-26 12:11:40.777 E/AndroidRuntime(15331): Process: jp.co.soramitsu.fearless.debug, PID: 15331 +08-26 12:11:40.777 E/AndroidRuntime(15331): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-26 12:11:40.777 E/AndroidRuntime(15331): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-26 12:11:40.777 E/AndroidRuntime(15331): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-26 12:11:40.777 E/AndroidRuntime(15331): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 12:11:40.777 E/AndroidRuntime(15331): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 12:11:40.777 E/AndroidRuntime(15331): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 12:11:40.777 E/AndroidRuntime(15331): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 12:11:40.777 E/AndroidRuntime(15331): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 12:11:40.777 E/AndroidRuntime(15331): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 12:11:40.777 E/AndroidRuntime(15331): at java.lang.Thread.run(Thread.java:1012) +08-26 12:11:40.777 E/AndroidRuntime(15331): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@1c2aca, Dispatchers.Main.immediate] +08-26 13:11:45.776 E/AndroidRuntime(16148): FATAL EXCEPTION: main +08-26 13:11:45.776 E/AndroidRuntime(16148): Process: jp.co.soramitsu.fearless.debug, PID: 16148 +08-26 13:11:45.776 E/AndroidRuntime(16148): java.lang.IllegalStateException: The query result was empty, but expected a single row to return a NON-NULL object of type . +08-26 13:11:45.776 E/AndroidRuntime(16148): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.getJoinChainInfo$lambda$20(ChainDao_Impl.kt:1369) +08-26 13:11:45.776 E/AndroidRuntime(16148): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$4awxuWkKLShxb1EsW8cg_jUSPaA(Unknown Source:0) +08-26 13:11:45.776 E/AndroidRuntime(16148): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda23.invoke(D8$$SyntheticClass:0) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 13:11:45.776 E/AndroidRuntime(16148): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 13:11:45.776 E/AndroidRuntime(16148): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 13:11:45.776 E/AndroidRuntime(16148): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 13:11:45.776 E/AndroidRuntime(16148): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 13:11:45.776 E/AndroidRuntime(16148): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 13:11:45.776 E/AndroidRuntime(16148): at java.lang.Thread.run(Thread.java:1012) +08-26 13:11:45.776 E/AndroidRuntime(16148): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@a07ec31, Dispatchers.Main.immediate] +08-26 13:11:58.444 E/AndroidRuntime(20317): FATAL EXCEPTION: main +08-26 13:11:58.444 E/AndroidRuntime(20317): Process: jp.co.soramitsu.fearless.debug, PID: 20317 +08-26 13:11:58.444 E/AndroidRuntime(20317): java.lang.IllegalStateException: The query result was empty, but expected a single row to return a NON-NULL object of type . +08-26 13:11:58.444 E/AndroidRuntime(20317): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.getJoinChainInfo$lambda$20(ChainDao_Impl.kt:1369) +08-26 13:11:58.444 E/AndroidRuntime(20317): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$4awxuWkKLShxb1EsW8cg_jUSPaA(Unknown Source:0) +08-26 13:11:58.444 E/AndroidRuntime(20317): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda23.invoke(D8$$SyntheticClass:0) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 13:11:58.444 E/AndroidRuntime(20317): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 13:11:58.444 E/AndroidRuntime(20317): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 13:11:58.444 E/AndroidRuntime(20317): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 13:11:58.444 E/AndroidRuntime(20317): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 13:11:58.444 E/AndroidRuntime(20317): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 13:11:58.444 E/AndroidRuntime(20317): at java.lang.Thread.run(Thread.java:1012) +08-26 13:11:58.444 E/AndroidRuntime(20317): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@f0bf189, Dispatchers.Main.immediate] +08-26 13:12:17.957 E/AndroidRuntime(21036): FATAL EXCEPTION: main +08-26 13:12:17.957 E/AndroidRuntime(21036): Process: jp.co.soramitsu.fearless.debug, PID: 21036 +08-26 13:12:17.957 E/AndroidRuntime(21036): java.lang.IllegalStateException: The query result was empty, but expected a single row to return a NON-NULL object of type . +08-26 13:12:17.957 E/AndroidRuntime(21036): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.getJoinChainInfo$lambda$20(ChainDao_Impl.kt:1369) +08-26 13:12:17.957 E/AndroidRuntime(21036): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$4awxuWkKLShxb1EsW8cg_jUSPaA(Unknown Source:0) +08-26 13:12:17.957 E/AndroidRuntime(21036): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda23.invoke(D8$$SyntheticClass:0) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 13:12:17.957 E/AndroidRuntime(21036): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 13:12:17.957 E/AndroidRuntime(21036): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 13:12:17.957 E/AndroidRuntime(21036): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 13:12:17.957 E/AndroidRuntime(21036): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 13:12:17.957 E/AndroidRuntime(21036): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 13:12:17.957 E/AndroidRuntime(21036): at java.lang.Thread.run(Thread.java:1012) +08-26 13:12:17.957 E/AndroidRuntime(21036): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@68b98c1, Dispatchers.Main.immediate] +08-26 13:43:22.813 E/AndroidRuntime( 4023): FATAL EXCEPTION: main +08-26 13:43:22.813 E/AndroidRuntime( 4023): Process: jp.co.soramitsu.fearless.debug, PID: 4023 +08-26 13:43:22.813 E/AndroidRuntime( 4023): java.lang.SecurityException: [9510274] Apps with uid 9510655 cannot masquerade as package jp.co.soramitsu.fearless.debug in uid 10655. [isClientAllowedToMasquerade? false] +08-26 13:43:22.813 E/AndroidRuntime( 4023): at android.os.Parcel.createExceptionOrNull(Parcel.java:3257) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at android.os.Parcel.createException(Parcel.java:3241) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at android.os.Parcel.readException(Parcel.java:3224) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at android.os.Parcel.readException(Parcel.java:3166) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.android.gms.internal.auth.zza.zzb(com.google.android.gms:play-services-auth-base@@18.0.4:3) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.android.gms.internal.auth.zzd.zze(com.google.android.gms:play-services-auth-base@@18.0.4:5) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.android.gms.auth.zzl.zzb(com.google.android.gms:play-services-auth-base@@18.0.4:2) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.android.gms.auth.zzf.zza(Unknown Source:6) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.android.gms.auth.zzl.zzh(com.google.android.gms:play-services-auth-base@@18.0.4:6) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.android.gms.auth.zzl.zza(com.google.android.gms:play-services-auth-base@@18.0.4:15) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.android.gms.auth.zzl.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:3) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.android.gms.auth.zzl.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:1) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.android.gms.auth.zzl.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:6) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.android.gms.auth.GoogleAuthUtil.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:3) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:267) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:292) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:880) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:476) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:409) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:526) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at jp.co.soramitsu.backup.data.repository.GoogleDriveStorage.getParentFolder(GoogleDriveStorage.kt:226) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at jp.co.soramitsu.backup.data.repository.GoogleDriveStorage.access$getParentFolder(GoogleDriveStorage.kt:32) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at jp.co.soramitsu.backup.data.repository.GoogleDriveStorage$getListOfFileHeads$2.invokeSuspend(GoogleDriveStorage.kt:126) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:113) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:820) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717) +08-26 13:43:22.813 E/AndroidRuntime( 4023): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704) +08-26 13:43:22.813 E/AndroidRuntime( 4023): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@4bea9a9, Dispatchers.Main.immediate] +08-26 13:43:32.795 E/AndroidRuntime( 9603): FATAL EXCEPTION: main +08-26 13:43:32.795 E/AndroidRuntime( 9603): Process: jp.co.soramitsu.fearless.debug, PID: 9603 +08-26 13:43:32.795 E/AndroidRuntime( 9603): java.lang.SecurityException: [9510274] Apps with uid 9510655 cannot masquerade as package jp.co.soramitsu.fearless.debug in uid 10655. [isClientAllowedToMasquerade? false] +08-26 13:43:32.795 E/AndroidRuntime( 9603): at android.os.Parcel.createExceptionOrNull(Parcel.java:3257) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at android.os.Parcel.createException(Parcel.java:3241) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at android.os.Parcel.readException(Parcel.java:3224) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at android.os.Parcel.readException(Parcel.java:3166) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.android.gms.internal.auth.zza.zzb(com.google.android.gms:play-services-auth-base@@18.0.4:3) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.android.gms.internal.auth.zzd.zze(com.google.android.gms:play-services-auth-base@@18.0.4:5) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.android.gms.auth.zzl.zzb(com.google.android.gms:play-services-auth-base@@18.0.4:2) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.android.gms.auth.zzf.zza(Unknown Source:6) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.android.gms.auth.zzl.zzh(com.google.android.gms:play-services-auth-base@@18.0.4:6) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.android.gms.auth.zzl.zza(com.google.android.gms:play-services-auth-base@@18.0.4:15) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.android.gms.auth.zzl.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:3) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.android.gms.auth.zzl.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:1) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.android.gms.auth.zzl.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:6) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.android.gms.auth.GoogleAuthUtil.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:3) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:267) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:292) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:880) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:476) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:409) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:526) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at jp.co.soramitsu.backup.data.repository.GoogleDriveStorage.getParentFolder(GoogleDriveStorage.kt:226) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at jp.co.soramitsu.backup.data.repository.GoogleDriveStorage.access$getParentFolder(GoogleDriveStorage.kt:32) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at jp.co.soramitsu.backup.data.repository.GoogleDriveStorage$getListOfFileHeads$2.invokeSuspend(GoogleDriveStorage.kt:126) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:113) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:820) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717) +08-26 13:43:32.795 E/AndroidRuntime( 9603): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704) +08-26 13:43:32.795 E/AndroidRuntime( 9603): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@6eda4ab, Dispatchers.Main.immediate] +08-26 13:43:49.072 E/AndroidRuntime(10574): FATAL EXCEPTION: main +08-26 13:43:49.072 E/AndroidRuntime(10574): Process: jp.co.soramitsu.fearless.debug, PID: 10574 +08-26 13:43:49.072 E/AndroidRuntime(10574): java.lang.SecurityException: [9510274] Apps with uid 9510655 cannot masquerade as package jp.co.soramitsu.fearless.debug in uid 10655. [isClientAllowedToMasquerade? false] +08-26 13:43:49.072 E/AndroidRuntime(10574): at android.os.Parcel.createExceptionOrNull(Parcel.java:3257) +08-26 13:43:49.072 E/AndroidRuntime(10574): at android.os.Parcel.createException(Parcel.java:3241) +08-26 13:43:49.072 E/AndroidRuntime(10574): at android.os.Parcel.readException(Parcel.java:3224) +08-26 13:43:49.072 E/AndroidRuntime(10574): at android.os.Parcel.readException(Parcel.java:3166) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.android.gms.internal.auth.zza.zzb(com.google.android.gms:play-services-auth-base@@18.0.4:3) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.android.gms.internal.auth.zzd.zze(com.google.android.gms:play-services-auth-base@@18.0.4:5) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.android.gms.auth.zzl.zzb(com.google.android.gms:play-services-auth-base@@18.0.4:2) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.android.gms.auth.zzf.zza(Unknown Source:6) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.android.gms.auth.zzl.zzh(com.google.android.gms:play-services-auth-base@@18.0.4:6) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.android.gms.auth.zzl.zza(com.google.android.gms:play-services-auth-base@@18.0.4:15) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.android.gms.auth.zzl.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:3) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.android.gms.auth.zzl.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:1) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.android.gms.auth.zzl.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:6) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.android.gms.auth.GoogleAuthUtil.getToken(com.google.android.gms:play-services-auth-base@@18.0.4:3) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:267) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:292) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:880) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:476) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:409) +08-26 13:43:49.072 E/AndroidRuntime(10574): at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:526) +08-26 13:43:49.072 E/AndroidRuntime(10574): at jp.co.soramitsu.backup.data.repository.GoogleDriveStorage.getParentFolder(GoogleDriveStorage.kt:226) +08-26 13:43:49.072 E/AndroidRuntime(10574): at jp.co.soramitsu.backup.data.repository.GoogleDriveStorage.access$getParentFolder(GoogleDriveStorage.kt:32) +08-26 13:43:49.072 E/AndroidRuntime(10574): at jp.co.soramitsu.backup.data.repository.GoogleDriveStorage$getListOfFileHeads$2.invokeSuspend(GoogleDriveStorage.kt:126) +08-26 13:43:49.072 E/AndroidRuntime(10574): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 13:43:49.072 E/AndroidRuntime(10574): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 13:43:49.072 E/AndroidRuntime(10574): at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:113) +08-26 13:43:49.072 E/AndroidRuntime(10574): at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89) +08-26 13:43:49.072 E/AndroidRuntime(10574): at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586) +08-26 13:43:49.072 E/AndroidRuntime(10574): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:820) +08-26 13:43:49.072 E/AndroidRuntime(10574): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717) +08-26 13:43:49.072 E/AndroidRuntime(10574): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704) +08-26 13:43:49.072 E/AndroidRuntime(10574): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@eab9b65, Dispatchers.Main.immediate] +08-26 13:52:12.124 E/AndroidRuntime(16667): FATAL EXCEPTION: main +08-26 13:52:12.124 E/AndroidRuntime(16667): Process: jp.co.soramitsu.fearless.debug, PID: 16667 +08-26 13:52:12.124 E/AndroidRuntime(16667): java.lang.IllegalStateException: The query result was empty, but expected a single row to return a NON-NULL object of type . +08-26 13:52:12.124 E/AndroidRuntime(16667): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.getJoinChainInfo$lambda$20(ChainDao_Impl.kt:1369) +08-26 13:52:12.124 E/AndroidRuntime(16667): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$4awxuWkKLShxb1EsW8cg_jUSPaA(Unknown Source:0) +08-26 13:52:12.124 E/AndroidRuntime(16667): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda23.invoke(D8$$SyntheticClass:0) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 13:52:12.124 E/AndroidRuntime(16667): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 13:52:12.124 E/AndroidRuntime(16667): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 13:52:12.124 E/AndroidRuntime(16667): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 13:52:12.124 E/AndroidRuntime(16667): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 13:52:12.124 E/AndroidRuntime(16667): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 13:52:12.124 E/AndroidRuntime(16667): at java.lang.Thread.run(Thread.java:1012) +08-26 13:52:12.124 E/AndroidRuntime(16667): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@b791886, Dispatchers.Main.immediate] +08-26 13:52:35.887 E/AndroidRuntime(21712): FATAL EXCEPTION: main +08-26 13:52:35.887 E/AndroidRuntime(21712): Process: jp.co.soramitsu.fearless.debug, PID: 21712 +08-26 13:52:35.887 E/AndroidRuntime(21712): java.lang.IllegalStateException: The query result was empty, but expected a single row to return a NON-NULL object of type . +08-26 13:52:35.887 E/AndroidRuntime(21712): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.getJoinChainInfo$lambda$20(ChainDao_Impl.kt:1369) +08-26 13:52:35.887 E/AndroidRuntime(21712): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$4awxuWkKLShxb1EsW8cg_jUSPaA(Unknown Source:0) +08-26 13:52:35.887 E/AndroidRuntime(21712): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda23.invoke(D8$$SyntheticClass:0) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 13:52:35.887 E/AndroidRuntime(21712): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 13:52:35.887 E/AndroidRuntime(21712): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 13:52:35.887 E/AndroidRuntime(21712): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 13:52:35.887 E/AndroidRuntime(21712): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 13:52:35.887 E/AndroidRuntime(21712): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 13:52:35.887 E/AndroidRuntime(21712): at java.lang.Thread.run(Thread.java:1012) +08-26 13:52:35.887 E/AndroidRuntime(21712): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@3bc27ba, Dispatchers.Main.immediate] +08-26 14:03:55.893 I/ActivityManager( 2921): android.util.AndroidRuntimeException: Activity could not be started for Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=com.adobe.scan.android cmp=com.adobe.scan.android/.SplashActivity } +08-26 14:05:06.696 I/MultimediaHelper(10856): (Jelly)(2.1.05) handleDecoderStatusUpdated() : decoder status is updated to true +08-26 14:05:06.719 I/MultimediaHelper(10856): (Jelly)(2.1.05) handleDecoderStatusUpdated() : decoder status is updated to true +08-26 14:05:18.347 V/NuPlayer( 2537): setDecoderBooster enable = No +08-26 14:05:18.347 V/NuPlayer( 2537): performDecoderFlush audio=2, video=2 +08-26 14:05:18.386 I/qr_barcode_jni(28872): Java_com_samsung_android_qrengine_QRBarcodeDecoder_initEngine +08-26 14:05:18.386 I/qr_barcode_jni(28872): Java_com_samsung_android_qrengine_QRBarcodeDecoder_initEngine: Version of QR Wrapper =2024.10.4.0 +08-26 14:05:18.386 I/qr_barcode_jni(28872): Java_com_samsung_android_qrengine_QRBarcodeDecoder_initEngine qrbarcode_decoder_init handle 0 +08-26 14:05:21.711 I/native ( 8019): I0000 00:00:1756209921.711141 29023 oned_decoder_client.cc:696] barhopper::deep_learning::OnedDecoderClient is created successfully. +08-26 14:05:21.796 I/native ( 8019): I0000 00:00:1756209921.796097 29026 oned_decoder_client.cc:696] barhopper::deep_learning::OnedDecoderClient is created successfully. +08-26 14:05:21.856 I/native ( 8019): I0000 00:00:1756209921.856281 29028 oned_decoder_client.cc:696] barhopper::deep_learning::OnedDecoderClient is created successfully. +08-26 14:05:21.908 I/native ( 8019): I0000 00:00:1756209921.908311 29030 oned_decoder_client.cc:696] barhopper::deep_learning::OnedDecoderClient is created successfully. +08-26 14:05:22.262 I/SRCB/QRBarcodeDecoder(28872): barcodeRecognizeRGB mResultRoi: 0, 0, 0, 0, 0, 0, 0, 0 +08-26 14:05:22.263 I/qr_barcode_jni(28872): Java_com_samsung_android_qrengine_QRBarcodeDecoder_releaseEngine engineId 0 +08-26 14:05:22.263 I/qr_barcode_jni(28872): Java_com_samsung_android_qrengine_QRBarcodeDecoder_releaseEngine qrbarcode_decoder_release ret 1 +08-26 14:05:28.056 I/MultimediaHelper(10856): (Jelly)(2.1.05) handleDecoderStatusUpdated() : decoder status is updated to false +08-26 14:05:30.089 I/Unihal ( 2079): BaseFilter.cpp: PostInitialize: 208: BaseFilter(FUNC_SCALER,0xb4000077b5dace00) starts the post init. +08-26 14:05:30.183 I/Unihal ( 2079): BaseFilter.cpp: PostInitialize: 218: BaseFilter(FUNC_SCALER,0xb4000077b5dace00) finishes the post init. state(1). +08-26 14:05:30.183 I/Unihal ( 2079): BaseFilter.cpp: PostInitialize: 208: BaseFilter(FUNC_SCALER_SUB,0xb4000077b5e7d000) starts the post init. +08-26 14:05:30.184 I/Unihal ( 2079): BaseFilter.cpp: PostInitialize: 218: BaseFilter(FUNC_SCALER_SUB,0xb4000077b5e7d000) finishes the post init. state(1). +08-26 14:05:32.421 I/Unihal ( 2079): BaseFilter.cpp: Destroy: 61: [FUNC_SCALER_SUB,0xb4000077b5e7d000] Destroying. +08-26 14:05:32.421 I/Unihal ( 2079): BaseFilter.cpp: Destroy: 70: [FUNC_SCALER_SUB,0xb4000077b5e7d000] Destroyed. +08-26 14:05:32.421 I/Unihal ( 2079): BaseFilter.cpp: Destroy: 61: [FUNC_SCALER,0xb4000077b5dace00] Destroying. +08-26 14:05:32.427 I/Unihal ( 2079): BaseFilter.cpp: Destroy: 70: [FUNC_SCALER,0xb4000077b5dace00] Destroyed. +08-26 14:05:40.512 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:05:40.513 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:05:40.518 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:05:40.527 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:09:59.400 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:09:59.434 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:10:14.791 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:10:14.797 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:10:15.569 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:10:15.570 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:10:18.192 D/ChainRegistry(32508): chains sync completed +08-26 14:10:25.958 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:10:25.962 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:10:25.967 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:10:25.984 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:11:12.679 D/ChainRegistry(32508): chains sync completed +08-26 14:11:13.965 E/AndroidRuntime(32508): FATAL EXCEPTION: main +08-26 14:11:13.965 E/AndroidRuntime(32508): Process: jp.co.soramitsu.fearless.debug, PID: 32508 +08-26 14:11:13.965 E/AndroidRuntime(32508): java.lang.IllegalStateException: Chain 3266816be9fa51b32cfea58d3e33ca77246bc9618595a4300e44c8856a8d8a17 not available locally yet; sync pending or failed +08-26 14:11:13.965 E/AndroidRuntime(32508): at jp.co.soramitsu.runtime.multiNetwork.chain.ChainsRepository$getChain$2.invokeSuspend(ChainsRepository.kt:55) +08-26 14:11:13.965 E/AndroidRuntime(32508): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 14:11:13.965 E/AndroidRuntime(32508): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 14:11:13.965 E/AndroidRuntime(32508): at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:113) +08-26 14:11:13.965 E/AndroidRuntime(32508): at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89) +08-26 14:11:13.965 E/AndroidRuntime(32508): at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586) +08-26 14:11:13.965 E/AndroidRuntime(32508): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:820) +08-26 14:11:13.965 E/AndroidRuntime(32508): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717) +08-26 14:11:13.965 E/AndroidRuntime(32508): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704) +08-26 14:11:13.965 E/AndroidRuntime(32508): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@e761776, Dispatchers.Main.immediate] +08-26 14:11:23.918 D/ChainRegistry( 6894): chains sync completed +08-26 14:11:47.173 E/AndroidRuntime( 6894): FATAL EXCEPTION: main +08-26 14:11:47.173 E/AndroidRuntime( 6894): Process: jp.co.soramitsu.fearless.debug, PID: 6894 +08-26 14:11:47.173 E/AndroidRuntime( 6894): java.lang.IllegalStateException: Chain 3266816be9fa51b32cfea58d3e33ca77246bc9618595a4300e44c8856a8d8a17 not available locally yet; sync pending or failed +08-26 14:11:47.173 E/AndroidRuntime( 6894): at jp.co.soramitsu.runtime.multiNetwork.chain.ChainsRepository$getChain$2.invokeSuspend(ChainsRepository.kt:55) +08-26 14:11:47.173 E/AndroidRuntime( 6894): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 14:11:47.173 E/AndroidRuntime( 6894): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 14:11:47.173 E/AndroidRuntime( 6894): at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:113) +08-26 14:11:47.173 E/AndroidRuntime( 6894): at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89) +08-26 14:11:47.173 E/AndroidRuntime( 6894): at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586) +08-26 14:11:47.173 E/AndroidRuntime( 6894): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:820) +08-26 14:11:47.173 E/AndroidRuntime( 6894): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717) +08-26 14:11:47.173 E/AndroidRuntime( 6894): at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704) +08-26 14:11:47.173 E/AndroidRuntime( 6894): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@bdf538d, Dispatchers.Main.immediate] +08-26 14:11:58.426 D/ChainRegistry( 8273): chains sync completed +08-26 14:12:08.588 E/AndroidRuntime( 8273): FATAL EXCEPTION: main +08-26 14:12:08.588 E/AndroidRuntime( 8273): Process: jp.co.soramitsu.fearless.debug, PID: 8273 +08-26 14:12:08.588 E/AndroidRuntime( 8273): java.lang.IllegalStateException: The column(s) of the map value object of type 'AssetWithToken' are NULL but the map's value type argument expect it to be NON-NULL +08-26 14:12:08.588 E/AndroidRuntime( 8273): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.observeChainsWithBalanceByName$lambda$30(ChainDao_Impl.kt:2049) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at jp.co.soramitsu.coredb.dao.ChainDao_Impl.$r8$lambda$RSup2l_urbwP6K6x9Zq6VEdSTQM(Unknown Source:0) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at jp.co.soramitsu.coredb.dao.ChainDao_Impl$$ExternalSyntheticLambda17.invoke(D8$$SyntheticClass:0) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invokeSuspend(DBUtil.kt:61) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:8) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1$1.invoke(Unknown Source:4) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.driver.SupportSQLitePooledConnection.transaction(SupportSQLiteConnectionPool.android.kt:83) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.driver.SupportSQLitePooledConnection.withTransaction(SupportSQLiteConnectionPool.android.kt:66) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invokeSuspend(DBUtil.kt:59) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:8) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$lambda$1$$inlined$internalPerform$1.invoke(Unknown Source:4) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.driver.SupportSQLiteConnectionPool.useConnection(SupportSQLiteConnectionPool.android.kt:42) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.RoomConnectionManager.useConnection(RoomConnectionManager.android.kt:126) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.RoomDatabase.useConnection$room_runtime_release(RoomDatabase.android.kt:593) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.util.DBUtil__DBUtil_androidKt$performSuspending$$inlined$compatCoroutineExecute$DBUtil__DBUtil_androidKt$1.invokeSuspend(DBUtil.android.kt:113) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.TransactionExecutor.execute$lambda$1$lambda$0(TransactionExecutor.android.kt:38) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.TransactionExecutor.$r8$lambda$FZWr2PGmP3sgXLCiri-DCcePXSs(Unknown Source:0) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at androidx.room.TransactionExecutor$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) +08-26 14:12:08.588 E/AndroidRuntime( 8273): at java.lang.Thread.run(Thread.java:1012) +08-26 14:12:08.588 E/AndroidRuntime( 8273): Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@653f55, Dispatchers.Main.immediate] +08-26 14:12:43.493 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:43.502 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:43.570 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:43.577 V/NuPlayer( 2537): make Decoder (audio) +08-26 14:12:43.577 V/NuPlayer( 2537): instantiateDecoder audio Decoder +08-26 14:12:43.582 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:43.904 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:43.906 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:43.910 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:43.919 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:44.433 I/NuPlayerDecoder( 2537): End of Stream +08-26 14:12:44.434 I/NuPlayerDecoder( 2537): End of Stream +08-26 14:12:44.921 V/NuPlayer( 2537): setDecoderBooster enable = No +08-26 14:12:44.921 V/NuPlayer( 2537): performDecoderFlush audio=2, video=2 +08-26 14:12:44.921 V/NuPlayer( 2537): [audio] flushDecoder needShutdown=1 +08-26 14:12:44.935 I/NuPlayerDecoder( 2537): kWhatAsyncReleaseComplete +08-26 14:12:45.007 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:45.008 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:45.014 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:45.019 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:45.035 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:45.040 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:48.865 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:48.867 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:48.872 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:48.905 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:52.041 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:12:52.049 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:03.351 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:03.352 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:03.353 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:03.371 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:03.556 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:03.556 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:03.559 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:03.574 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:34.056 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:34.058 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:34.062 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:34.085 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:54.371 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:54.373 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:54.377 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:13:54.402 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:24.879 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:24.880 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:24.883 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:24.905 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:44.177 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:44.178 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:44.180 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:44.191 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:44.402 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:44.403 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:44.405 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:44.425 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:49.429 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:49.430 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:49.432 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:14:49.442 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:04.683 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:04.684 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:04.690 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:04.718 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:25.081 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:25.082 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:25.095 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:25.115 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:35.221 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:35.224 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:35.228 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:35.256 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:45.191 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:45.192 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:45.207 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:45.260 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:45.395 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:45.397 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:45.399 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:45.425 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:55.539 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:55.541 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:55.543 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:15:55.565 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:05.764 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:05.767 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:05.773 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:05.805 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:15.933 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:15.935 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:15.941 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:15.973 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:26.109 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:26.111 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:26.115 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:26.141 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:36.251 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:36.253 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:36.259 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:36.284 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:46.413 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:46.415 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:46.419 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:46.441 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:56.380 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:56.381 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:56.383 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:56.402 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:56.581 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:56.585 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:56.587 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:16:56.607 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:06.749 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:06.750 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:06.753 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:06.773 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:16.904 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:16.905 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:16.914 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:16.943 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:27.094 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:27.095 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:27.098 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:27.118 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:37.270 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:37.271 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:37.274 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:37.295 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:47.425 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:47.427 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:47.434 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:47.463 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:57.584 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:57.585 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:57.587 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:17:57.602 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:07.565 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:07.566 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:07.567 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:07.576 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:07.790 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:07.791 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:07.793 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:07.813 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:17.922 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:17.924 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:17.928 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:17.952 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:28.088 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:28.089 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:28.093 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:28.114 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:38.261 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:38.262 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:38.264 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:38.299 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:48.410 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:48.411 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:48.416 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:48.459 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:58.576 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:58.577 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:58.578 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:18:58.586 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:08.790 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:08.791 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:08.798 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:08.827 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:18.707 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:18.707 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:18.710 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:18.719 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:18.922 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:18.923 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:18.924 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:18.940 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:19.168 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:19.184 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:29.081 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:29.082 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:29.086 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:29.108 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:39.267 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:39.269 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:39.273 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:39.303 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:49.452 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:49.454 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:49.457 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:49.476 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:59.630 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:59.631 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:59.634 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:19:59.652 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:09.783 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:09.783 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:09.787 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:09.810 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:19.976 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:19.977 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:19.980 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:19.997 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:29.991 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:29.991 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:29.993 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:30.006 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:30.196 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:30.197 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:30.199 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:30.217 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:40.333 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:40.336 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:40.337 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:40.353 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:50.502 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:50.504 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:50.507 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:20:50.532 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:21:00.692 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:21:00.693 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:21:00.701 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. +08-26 14:21:00.732 D/LocalImageResolver( 4865): Couldn't use ImageDecoder for drawable, falling back to non-resized load. diff --git a/feature-account-api/build.gradle b/feature-account-api/build.gradle index 9afd0bd966..cb120722df 100644 --- a/feature-account-api/build.gradle +++ b/feature-account-api/build.gradle @@ -23,12 +23,10 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } - namespace 'jp.co.soramitsu.feature_account_api' + namespace = 'jp.co.soramitsu.feature_account_api' } dependencies { @@ -49,4 +47,4 @@ dependencies { api libs.sharedFeaturesCoreDep api libs.sharedFeaturesBackupDep -} \ No newline at end of file +} diff --git a/feature-account-impl/build.gradle b/feature-account-impl/build.gradle index d8042e082a..46709e21d8 100644 --- a/feature-account-impl/build.gradle +++ b/feature-account-impl/build.gradle @@ -28,12 +28,10 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } - namespace 'jp.co.soramitsu.feature_account_impl' + namespace = 'jp.co.soramitsu.feature_account_impl' } dependencies { @@ -97,4 +95,4 @@ dependencies { implementation libs.sharedFeaturesBackupDep implementation libs.web3jDep -} \ No newline at end of file +} diff --git a/feature-crowdloan-api/build.gradle b/feature-crowdloan-api/build.gradle index 455f363668..ba66f18032 100644 --- a/feature-crowdloan-api/build.gradle +++ b/feature-crowdloan-api/build.gradle @@ -18,11 +18,9 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } - namespace 'jp.co.soramitsu.feature_crowdloan_api' + namespace = 'jp.co.soramitsu.feature_crowdloan_api' } dependencies { @@ -36,4 +34,4 @@ dependencies { api project(':core-api') api project(':core-db') -} \ No newline at end of file +} diff --git a/feature-crowdloan-impl/build.gradle b/feature-crowdloan-impl/build.gradle index 178577b30b..77c080d8ef 100644 --- a/feature-crowdloan-impl/build.gradle +++ b/feature-crowdloan-impl/build.gradle @@ -20,8 +20,6 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } @@ -30,7 +28,7 @@ android { targetCompatibility = JavaVersion.VERSION_21 } - namespace 'jp.co.soramitsu.feature_crowdloan_impl' + namespace = 'jp.co.soramitsu.feature_crowdloan_impl' } dependencies { @@ -79,4 +77,4 @@ dependencies { implementation libs.storiesProgressView implementation libs.coil -} \ No newline at end of file +} diff --git a/feature-onboarding-api/build.gradle b/feature-onboarding-api/build.gradle index c227bf3359..1f38fb5279 100644 --- a/feature-onboarding-api/build.gradle +++ b/feature-onboarding-api/build.gradle @@ -18,16 +18,12 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } - namespace 'jp.co.soramitsu.feature_onboarding_api' + namespace = 'jp.co.soramitsu.feature_onboarding_api' } dependencies { implementation project(':feature-account-api') } - - diff --git a/feature-onboarding-impl/build.gradle b/feature-onboarding-impl/build.gradle index bf9406f575..2c6478e1e0 100644 --- a/feature-onboarding-impl/build.gradle +++ b/feature-onboarding-impl/build.gradle @@ -39,12 +39,10 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } - namespace 'jp.co.soramitsu.feature_onboarding_impl' + namespace = 'jp.co.soramitsu.feature_onboarding_impl' } dependencies { diff --git a/feature-soracard-api/build.gradle b/feature-soracard-api/build.gradle index 157ffc3cf3..978380e4c4 100644 --- a/feature-soracard-api/build.gradle +++ b/feature-soracard-api/build.gradle @@ -23,8 +23,6 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = '21' } @@ -55,7 +53,7 @@ android { buildConfig = true } - namespace "jp.co.soramitsu.feature_soracard_api" + namespace = "jp.co.soramitsu.feature_soracard_api" } dependencies { @@ -68,5 +66,3 @@ dependencies { implementation libs.sora.soracard } - - diff --git a/feature-splash/build.gradle b/feature-splash/build.gradle index 214b2dee2d..b2e2d1d1aa 100644 --- a/feature-splash/build.gradle +++ b/feature-splash/build.gradle @@ -24,12 +24,10 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } - namespace 'jp.co.soramitsu.splash' + namespace = 'jp.co.soramitsu.splash' } dependencies { diff --git a/feature-staking-api/build.gradle b/feature-staking-api/build.gradle index 832c98ec27..59f0618d06 100644 --- a/feature-staking-api/build.gradle +++ b/feature-staking-api/build.gradle @@ -14,8 +14,6 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } @@ -24,7 +22,7 @@ android { targetCompatibility = JavaVersion.VERSION_21 } - namespace 'jp.co.soramitsu.feature_staking_api' + namespace = 'jp.co.soramitsu.feature_staking_api' } dependencies { @@ -38,4 +36,4 @@ dependencies { implementation project(':feature-account-api') api project(':core-api') -} \ No newline at end of file +} diff --git a/feature-staking-impl/build.gradle b/feature-staking-impl/build.gradle index 961d63b766..5a25a8c056 100644 --- a/feature-staking-impl/build.gradle +++ b/feature-staking-impl/build.gradle @@ -23,8 +23,6 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } @@ -34,7 +32,7 @@ android { targetCompatibility = JavaVersion.VERSION_21 } - namespace 'jp.co.soramitsu.feature_staking_impl' + namespace = 'jp.co.soramitsu.feature_staking_impl' } dependencies { @@ -92,4 +90,4 @@ dependencies { testImplementation libs.mockito.kotlin testImplementation libs.mockito.inline testImplementation libs.mockito.core -} \ No newline at end of file +} diff --git a/feature-wallet-api/build.gradle b/feature-wallet-api/build.gradle index 4f536c99bc..d548cc11cc 100644 --- a/feature-wallet-api/build.gradle +++ b/feature-wallet-api/build.gradle @@ -19,7 +19,6 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] jvmTarget = JavaVersion.VERSION_21.toString() } compileOptions { @@ -27,7 +26,7 @@ android { targetCompatibility = JavaVersion.VERSION_21 } - namespace 'jp.co.soramitsu.feature_wallet_api' + namespace = 'jp.co.soramitsu.feature_wallet_api' } dependencies { @@ -52,4 +51,4 @@ dependencies { api project(':core-db') testImplementation project(':test-shared') -} \ No newline at end of file +} diff --git a/feature-wallet-impl/build.gradle b/feature-wallet-impl/build.gradle index 1953944573..b96d5c0637 100644 --- a/feature-wallet-impl/build.gradle +++ b/feature-wallet-impl/build.gradle @@ -52,12 +52,10 @@ android { } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } - namespace 'jp.co.soramitsu.feature_wallet_impl' + namespace = 'jp.co.soramitsu.feature_wallet_impl' } dependencies { @@ -150,4 +148,4 @@ dependencies { implementation libs.web3jDep implementation libs.bundles.ton -} \ No newline at end of file +} diff --git a/runtime-permission/build.gradle b/runtime-permission/build.gradle index 565e8fc7db..5ad4710f77 100644 --- a/runtime-permission/build.gradle +++ b/runtime-permission/build.gradle @@ -10,19 +10,17 @@ android { minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion } - namespace 'jp.co.soramitsu.runtime_permission' + namespace = 'jp.co.soramitsu.runtime_permission' compileOptions { sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = '21' } } dependencies { implementation libs.appcompat -} \ No newline at end of file +} diff --git a/runtime/build.gradle b/runtime/build.gradle index 6dc45cea0b..3c53d70e21 100644 --- a/runtime/build.gradle +++ b/runtime/build.gradle @@ -39,18 +39,32 @@ android { buildConfig = true } + // Resolve duplicate META-INF resources in androidTest packaging (e.g., JUnit Jupiter artifacts) + packaging { + resources { + excludes += [ + "META-INF/LICENSE.md", + "META-INF/LICENSE-notice.md", + "META-INF/LICENSE*", + "META-INF/NOTICE*", + "META-INF/AL2.0", + "META-INF/LGPL2.1", + // Versioned META-INF resources from multi-release jars (e.g., BouncyCastle, jspecify) + "META-INF/versions/**" + ] + } + } + compileOptions { sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = JavaVersion.VERSION_21.toString() } - namespace 'jp.co.soramitsu.runtime' + namespace = 'jp.co.soramitsu.runtime' } dependencies { diff --git a/runtime/src/androidTest/java/jp/co/soramitsu/runtime/integration/DotIntegrationTest.kt b/runtime/src/androidTest/java/jp/co/soramitsu/runtime/integration/DotIntegrationTest.kt new file mode 100644 index 0000000000..ddd1c75ac4 --- /dev/null +++ b/runtime/src/androidTest/java/jp/co/soramitsu/runtime/integration/DotIntegrationTest.kt @@ -0,0 +1,68 @@ +package jp.co.soramitsu.runtime.integration + +import android.util.Log +import org.junit.Assume.assumeTrue +import org.junit.Test +import java.io.BufferedReader +import java.io.OutputStreamWriter +import java.net.HttpURLConnection +import java.net.URL + +class DotIntegrationTest { + + private fun hasNetwork(): Boolean = try { + // Lightweight reachability check to a stable host + val url = URL("https://www.google.com/generate_204") + (url.openConnection() as HttpURLConnection).run { + connectTimeout = 2000 + readTimeout = 2000 + requestMethod = "GET" + connect() + val ok = responseCode in 200..399 + disconnect() + ok + } + } catch (_: Exception) { false } + + @Test + fun testPolkadotRuntimeVersion_logsResponse() { + assumeTrue("No network; skipping", hasNetwork()) + + // Allow override via instrumentation arg or system property; otherwise use a public RPC mirror + val override = System.getProperty("DOT_RPC_URL") ?: System.getenv("DOT_RPC_URL") + val rpcUrl = override ?: "https://polkadot-rpc.publicnode.com" + + val payload = """ + {"jsonrpc":"2.0","method":"state_getRuntimeVersion","params":[],"id":1} + """.trimIndent() + + val response = httpPost(rpcUrl, payload) + + Log.i("DotIntegrationTest", "RPC URL: $rpcUrl") + Log.i("DotIntegrationTest", "state_getRuntimeVersion => $response") + + // Basic sanity: expect fields like specName/specVersion in response + val ok = response.contains("specName") && response.contains("specVersion") + assumeTrue("Unexpected DOT RPC response; possibly blocked network", ok) + } + + private fun httpPost(urlStr: String, body: String): String { + val url = URL(urlStr) + val conn = (url.openConnection() as HttpURLConnection).apply { + requestMethod = "POST" + connectTimeout = 5000 + readTimeout = 7000 + doOutput = true + setRequestProperty("Content-Type", "application/json") + } + + OutputStreamWriter(conn.outputStream, Charsets.UTF_8).use { it.write(body) } + + val code = conn.responseCode + val stream = if (code in 200..299) conn.inputStream else conn.errorStream + val text = BufferedReader(stream.reader(Charsets.UTF_8)).use { it.readText() } + conn.disconnect() + return text + } +} + diff --git a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt index 63e85bbe53..b587b08987 100644 --- a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt +++ b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt @@ -8,6 +8,7 @@ import jp.co.soramitsu.coredb.model.AssetWithToken import jp.co.soramitsu.coredb.model.chain.JoinedChainInfo import jp.co.soramitsu.runtime.multiNetwork.chain.model.Chain import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map @@ -44,8 +45,14 @@ class ChainsRepository(private val chainDao: ChainDao) { } suspend fun getChain(chainId: ChainId): Chain = withContext(Dispatchers.IO) { - val chainLocal = chainDao.getJoinChainInfo(chainId) - mapChainLocalToChain(chainLocal) + // Be resilient on fresh installs/after data clears: wait briefly for chain sync + repeat(50) { // ~15s at 300ms per attempt + val local = chainDao.getJoinChainInfo() + val found = local.firstOrNull { it.chain.id == chainId } + if (found != null) return@withContext mapChainLocalToChain(found) + delay(300) + } + throw IllegalStateException("Chain $chainId not available locally yet; sync pending or failed") } fun observeChainsPerAssetFlow( @@ -58,4 +65,4 @@ class ChainsRepository(private val chainDao: ChainDao) { suspend fun notifyNodeSwitched(chainId: ChainId, nodeUrl: String) { chainDao.selectNode(chainId, nodeUrl) } -} \ No newline at end of file +} diff --git a/scripts/secrets.gradle b/scripts/secrets.gradle index ed5e1eed0a..5a0a320692 100644 --- a/scripts/secrets.gradle +++ b/scripts/secrets.gradle @@ -22,8 +22,9 @@ ext.readSecretInQuotes = { secretName -> static def maybeWrapInQuotes(content){ if (content == null) { - return "" + // When a secret is missing, return an empty string literal to keep generated code valid + return "\"\"" } return content.startsWith("\"") ? content : "\"" + content + "\"" -} \ No newline at end of file +} diff --git a/test-shared/build.gradle b/test-shared/build.gradle index e35cb44168..32848b8e5e 100644 --- a/test-shared/build.gradle +++ b/test-shared/build.gradle @@ -17,11 +17,9 @@ android { targetCompatibility = JavaVersion.VERSION_21 } kotlinOptions { - freeCompilerArgs = ["-Xallow-result-return-type"] - jvmTarget = '21' } - namespace 'jp.co.soramitsu.test_shared' + namespace = 'jp.co.soramitsu.test_shared' } @@ -41,4 +39,4 @@ dependencies { api libs.nv.websocket.client api libs.gson -} \ No newline at end of file +} From b21b8b529fdfad0425408923c6207eb163f6785c Mon Sep 17 00:00:00 2001 From: William Richter Date: Thu, 28 Aug 2025 10:40:36 +0200 Subject: [PATCH 13/18] fix(runtime,core-db): wait for chain sync and include empty-asset chains; add ChainRegistry diagnostics --- core-db/build.gradle | 2 +- .../java/jp/co/soramitsu/coredb/dao/ChainDao.kt | 2 +- .../runtime/multiNetwork/chain/ChainSyncService.kt | 13 ++++++++++--- .../runtime/multiNetwork/chain/ChainsRepository.kt | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/core-db/build.gradle b/core-db/build.gradle index fc0f5811ff..4d08a13faa 100644 --- a/core-db/build.gradle +++ b/core-db/build.gradle @@ -32,7 +32,7 @@ android { sourceSets { androidTest.assets.srcDirs += files("$projectDir/schemas".toString()) } - namespace 'jp.co.soramitsu.core_db' + namespace = 'jp.co.soramitsu.core_db' } ksp { diff --git a/core-db/src/main/java/jp/co/soramitsu/coredb/dao/ChainDao.kt b/core-db/src/main/java/jp/co/soramitsu/coredb/dao/ChainDao.kt index 2c137d97c9..4a06eca19e 100644 --- a/core-db/src/main/java/jp/co/soramitsu/coredb/dao/ChainDao.kt +++ b/core-db/src/main/java/jp/co/soramitsu/coredb/dao/ChainDao.kt @@ -164,7 +164,7 @@ abstract class ChainDao { @Query("SELECT * FROM chains WHERE id = :chainId") @Transaction - abstract suspend fun getJoinChainInfo(chainId: String): JoinedChainInfo + abstract suspend fun getJoinChainInfo(chainId: String): JoinedChainInfo? @Query("SELECT * FROM chains") @Transaction diff --git a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainSyncService.kt b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainSyncService.kt index 0eefb67060..cd84ca992d 100644 --- a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainSyncService.kt +++ b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainSyncService.kt @@ -1,5 +1,6 @@ package jp.co.soramitsu.runtime.multiNetwork.chain +import android.util.Log import jp.co.soramitsu.common.resources.ContextManager import jp.co.soramitsu.coredb.dao.AssetDao import jp.co.soramitsu.coredb.dao.ChainDao @@ -32,19 +33,21 @@ class ChainSyncService( } private suspend fun configChainsSyncUp(): List = supervisorScope { + val tag = "ChainRegistry" val localChainsJoinedInfo = dao.getJoinChainInfo() val localChainsJoinedInfoMap = localChainsJoinedInfo.associateBy { it.chain.id } val remoteChains = chainFetcher.getChains() - .filter { - !it.disabled && (it.assets?.isNotEmpty() == true) - } + .filter { !it.disabled } .map { it.toChain() } val remoteMapping = remoteChains.associateBy(Chain::id) + Log.d(tag, "remote chains fetched: ${remoteChains.size}") + remoteChains.take(5).forEach { Log.d(tag, "remote chain id: ${it.id}") } + val mappedRemoteChains = remoteChains.map { mapChainToChainLocal(it) } val chainsSyncDeferred = async { val chainsToUpdate: MutableList = mutableListOf() @@ -162,6 +165,10 @@ class ChainSyncService( dao.deleteChains(chainsToDelete) + val postLocal = dao.getJoinChainInfo() + Log.d(tag, "local chains after sync: ${postLocal.size}") + postLocal.take(5).forEach { Log.d(tag, "local chain id: ${it.chain.id}") } + remoteChains } } diff --git a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt index b587b08987..26b633f620 100644 --- a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt +++ b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt @@ -46,7 +46,7 @@ class ChainsRepository(private val chainDao: ChainDao) { suspend fun getChain(chainId: ChainId): Chain = withContext(Dispatchers.IO) { // Be resilient on fresh installs/after data clears: wait briefly for chain sync - repeat(50) { // ~15s at 300ms per attempt + repeat(200) { // ~60s at 300ms per attempt val local = chainDao.getJoinChainInfo() val found = local.firstOrNull { it.chain.id == chainId } if (found != null) return@withContext mapChainLocalToChain(found) From 08ee32ba5d6549a66890dcad78b1e6293df43ae6 Mon Sep 17 00:00:00 2001 From: William Richter Date: Thu, 28 Aug 2025 11:54:04 +0200 Subject: [PATCH 14/18] ci: print Gradle/AGP versions and run readelf sanity on native libs; docs(roadmap): add Gradle/AGP update and Google Play 16KB page-siz compliance --- .github/workflows/android-ci.yml | 21 +++++++++++++++++++++ docs/roadmap.md | 18 ++++++++++++++++++ roadmap.md | 4 ++++ 3 files changed, 43 insertions(+) diff --git a/.github/workflows/android-ci.yml b/.github/workflows/android-ci.yml index c3cce04f65..15630ad298 100644 --- a/.github/workflows/android-ci.yml +++ b/.github/workflows/android-ci.yml @@ -77,3 +77,24 @@ jobs: - name: Android Lint (app) run: ./gradlew :app:lint --no-daemon --console=plain + + - name: Gradle/AGP versions + run: | + echo "== Gradle ==" + ./gradlew --version --no-daemon --console=plain || true + echo "\n== Android Gradle Plugin (declared) ==" + grep -E '^android_plugin\s*=\s*"[0-9]+' gradle/libs.versions.toml || true + + - name: Assemble debug to produce native libs + run: ./gradlew :app:assembleDebug --no-daemon --console=plain + + - name: readelf sanity (native libs) + run: | + set +e + echo "== Scanning native libraries (.so) ==" + mapfile -t sos < <(find app/build -type f -name "*.so" | head -n 10) + if [ ${#sos[@]} -eq 0 ]; then echo "No native libs found under app/build"; exit 0; fi + for so in "${sos[@]}"; do + echo "\n-- $so --" + readelf -l "$so" | sed -n '1,120p' || true + done diff --git a/docs/roadmap.md b/docs/roadmap.md index 63e2d8b47a..69d6310722 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -144,6 +144,24 @@ Priority: P0 (must-do), P1 (should-do), P2 (nice-to-have) - Prompt: - Template a README and populate for wallet, account, staking first. +12) Gradle/AGP update and build hygiene +- Why: Keep toolchain current, reduce deprecations, and ensure reproducible builds. +- Acceptance: + - Update to latest stable Gradle and Android Gradle Plugin; no deprecation warnings in `./gradlew help`. + - Build works with JDK 21; CI green. +- Prompt: + - Bump versions in `gradle/libs.versions.toml` and wrapper to the latest stable; fix any DSL changes. + - Verify `url = uri(...)`, `namespace = '…'`, and packaging excludes for test APKs. + +13) Google Play 16KB page-size compliance (native libs) +- Why: Play requires 16KB page-size support on newer devices; native libs must be compatible. +- Acceptance: + - Rebuild native artifacts (e.g., sr25519) with an NDK that supports 16KB pages (r26+). + - Verify with `readelf -l lib.so` that segment alignment/page-size is compliant; no Play Console warnings. +- Prompt: + - Ensure `ndk;25.2.9519653` or newer in CI/local; consider bumping to latest stable NDK if needed. + - Keep native libs uncompressed in the bundle or verify packaging flags as required by Play guidance. + ## P2 — Lower Priority 12) Centralize chain/type override docs and checks diff --git a/roadmap.md b/roadmap.md index 0cc2a4c34d..ac51afa925 100644 --- a/roadmap.md +++ b/roadmap.md @@ -46,3 +46,7 @@ Verification matrix (execute manually or script): — More roadmap items (P0/P1/P2), including technical debt and follow-ups, are maintained in `docs/roadmap.md`. + +## Build & Play Compliance +- Gradle/AGP update: bump Gradle wrapper and Android Gradle Plugin to the latest stable release; remove deprecations (e.g., use `url = uri(...)`, `namespace = '…'`). Verify builds with JDK 21 locally and in CI. +- Google Play 16KB page size: ensure native libraries (e.g., sr25519) are built with an NDK that supports 16KB pages (r26+). Validate with `readelf -l` and address Play Console checks. Keep packaging compliant (uncompressed native libs or required flags). From 1bdf47f00f154acf6e8fa2f9db0dbdff270c947e Mon Sep 17 00:00:00 2001 From: William Richter Date: Fri, 29 Aug 2025 08:08:45 +0200 Subject: [PATCH 15/18] fix(runtime): use flow-based wait for chain availability; guard ChainRegistry diagnostics; housekeeping: ignore/remove *.log --- .gitignore | 5 ++++- .../multiNetwork/chain/ChainSyncService.kt | 13 +++++++++---- .../multiNetwork/chain/ChainsRepository.kt | 16 ++++++++-------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 1a0193882e..86909f4996 100644 --- a/.gitignore +++ b/.gitignore @@ -12,5 +12,8 @@ app/*.apk # ignore jacoco coverage reports /coverage +# ignore local logs +*.log + fearless.jks -/buildSrc/build \ No newline at end of file +/buildSrc/build diff --git a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainSyncService.kt b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainSyncService.kt index cd84ca992d..3bccb2b565 100644 --- a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainSyncService.kt +++ b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainSyncService.kt @@ -1,6 +1,7 @@ package jp.co.soramitsu.runtime.multiNetwork.chain import android.util.Log +import jp.co.soramitsu.runtime.BuildConfig import jp.co.soramitsu.common.resources.ContextManager import jp.co.soramitsu.coredb.dao.AssetDao import jp.co.soramitsu.coredb.dao.ChainDao @@ -45,8 +46,10 @@ class ChainSyncService( val remoteMapping = remoteChains.associateBy(Chain::id) - Log.d(tag, "remote chains fetched: ${remoteChains.size}") - remoteChains.take(5).forEach { Log.d(tag, "remote chain id: ${it.id}") } + if (BuildConfig.DEBUG) { + Log.d(tag, "remote chains fetched: ${remoteChains.size}") + remoteChains.take(5).forEach { Log.d(tag, "remote chain id: ${it.id}") } + } val mappedRemoteChains = remoteChains.map { mapChainToChainLocal(it) } val chainsSyncDeferred = async { @@ -166,8 +169,10 @@ class ChainSyncService( dao.deleteChains(chainsToDelete) val postLocal = dao.getJoinChainInfo() - Log.d(tag, "local chains after sync: ${postLocal.size}") - postLocal.take(5).forEach { Log.d(tag, "local chain id: ${it.chain.id}") } + if (BuildConfig.DEBUG) { + Log.d(tag, "local chains after sync: ${postLocal.size}") + postLocal.take(5).forEach { Log.d(tag, "local chain id: ${it.chain.id}") } + } remoteChains } diff --git a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt index 26b633f620..e1cbcb2289 100644 --- a/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt +++ b/runtime/src/main/java/jp/co/soramitsu/runtime/multiNetwork/chain/ChainsRepository.kt @@ -9,6 +9,8 @@ import jp.co.soramitsu.coredb.model.chain.JoinedChainInfo import jp.co.soramitsu.runtime.multiNetwork.chain.model.Chain import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay +import kotlinx.coroutines.withTimeoutOrNull +import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map @@ -45,14 +47,12 @@ class ChainsRepository(private val chainDao: ChainDao) { } suspend fun getChain(chainId: ChainId): Chain = withContext(Dispatchers.IO) { - // Be resilient on fresh installs/after data clears: wait briefly for chain sync - repeat(200) { // ~60s at 300ms per attempt - val local = chainDao.getJoinChainInfo() - val found = local.firstOrNull { it.chain.id == chainId } - if (found != null) return@withContext mapChainLocalToChain(found) - delay(300) - } - throw IllegalStateException("Chain $chainId not available locally yet; sync pending or failed") + // Prefer flow-based wait for the chain to appear over polling + val map = withTimeoutOrNull(60_000) { // 60s timeout + chainsByIdFlow().firstOrNull { it.containsKey(chainId) } + } ?: throw IllegalStateException("Chain $chainId not available locally yet; sync pending or failed") + + map.getValue(chainId) } fun observeChainsPerAssetFlow( From c5a37181c15f43b756d44a293c65e38037b95d63 Mon Sep 17 00:00:00 2001 From: William Richter Date: Fri, 29 Aug 2025 08:15:20 +0200 Subject: [PATCH 16/18] build(settings): add USE_REMOTE_UTILS toggle for fearless-utils source; ci: enable flag and print Gradle/AGP; docs(roadmap): refine Gradle/AGP and Play 16KB items --- .github/workflows/android-ci.yml | 1 + docs/roadmap.md | 14 ++++++++++++-- settings.gradle | 18 ++++++++++++++---- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/.github/workflows/android-ci.yml b/.github/workflows/android-ci.yml index 15630ad298..2f97c1b28c 100644 --- a/.github/workflows/android-ci.yml +++ b/.github/workflows/android-ci.yml @@ -15,6 +15,7 @@ jobs: timeout-minutes: 45 env: CI: true + USE_REMOTE_UTILS: "true" # Provide safe stubs to avoid repository/config failures during resolution PAY_WINGS_REPOSITORY_URL: https://maven.google.com PAY_WINGS_USERNAME: "" diff --git a/docs/roadmap.md b/docs/roadmap.md index 69d6310722..1d4e550f31 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -147,11 +147,12 @@ Priority: P0 (must-do), P1 (should-do), P2 (nice-to-have) 12) Gradle/AGP update and build hygiene - Why: Keep toolchain current, reduce deprecations, and ensure reproducible builds. - Acceptance: - - Update to latest stable Gradle and Android Gradle Plugin; no deprecation warnings in `./gradlew help`. - - Build works with JDK 21; CI green. + - Update to latest stable Gradle (e.g., 8.x) and Android Gradle Plugin (e.g., 8.x); no deprecation warnings in `./gradlew help`. + - Build works with JDK 21; CI green. CI prints Gradle/AGP versions for traceability. - Prompt: - Bump versions in `gradle/libs.versions.toml` and wrapper to the latest stable; fix any DSL changes. - Verify `url = uri(...)`, `namespace = '…'`, and packaging excludes for test APKs. + - Keep a CI step that prints Gradle/AGP versions (android-ci.yml). 13) Google Play 16KB page-size compliance (native libs) - Why: Play requires 16KB page-size support on newer devices; native libs must be compatible. @@ -161,6 +162,15 @@ Priority: P0 (must-do), P1 (should-do), P2 (nice-to-have) - Prompt: - Ensure `ndk;25.2.9519653` or newer in CI/local; consider bumping to latest stable NDK if needed. - Keep native libs uncompressed in the bundle or verify packaging flags as required by Play guidance. + - Keep a CI step to run `readelf -l` on built .so files and surface any issues in logs. + +14) Utils source mapping toggle +- Why: Make remote source dependency for fearless-utils explicit and controllable. +- Acceptance: + - `settings.gradle` maps the GitHub repository only when `USE_REMOTE_UTILS=true` (env or -P). + - CI sets `USE_REMOTE_UTILS=true` to build from source; local builds can rely on published artifacts by default. +- Prompt: + - Add a settings flag and document it in AGENTS/README; enable flag in CI env. ## P2 — Lower Priority diff --git a/settings.gradle b/settings.gradle index b3351677f6..aa371199d3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -31,9 +31,19 @@ include ':feature-nft-impl' include ':feature-liquiditypools-api' include ':feature-liquiditypools-impl' -// Map fearless-utils-Android from GitHub as a source dependency (requires network access) -sourceControl { - gitRepository("https://github.com/soramitsu/fearless-utils-Android.git") { - producesModule("jp.co.soramitsu.fearless-utils:fearless-utils") +// Optionally map fearless-utils-Android from GitHub as a source dependency. +// Enable by setting -PUSE_REMOTE_UTILS=true or USE_REMOTE_UTILS=true in the environment. +def useRemoteUtils = ( + providers.gradleProperty("USE_REMOTE_UTILS").orNull?.toBoolean() ?: false +) || (System.getenv("USE_REMOTE_UTILS") == "true") + +if (useRemoteUtils) { + println("Including remote fearless-utils from GitHub via sourceControl") + sourceControl { + gitRepository("https://github.com/soramitsu/fearless-utils-Android.git") { + producesModule("jp.co.soramitsu.fearless-utils:fearless-utils") + } } +} else { + println("USE_REMOTE_UTILS not set; using published artifacts for fearless-utils") } From ec8a923a649ae2edb5e330e3c57b3fb12f3312ea Mon Sep 17 00:00:00 2001 From: William Richter Date: Fri, 29 Aug 2025 08:19:39 +0200 Subject: [PATCH 17/18] ci: trigger on master,develop instead of main,develop --- .github/workflows/android-ci.yml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/android-ci.yml b/.github/workflows/android-ci.yml index 2f97c1b28c..c3aa4016a4 100644 --- a/.github/workflows/android-ci.yml +++ b/.github/workflows/android-ci.yml @@ -3,7 +3,10 @@ name: Android CI on: pull_request: push: - branches: [ main, develop ] + branches: [ master, develop ] + +permissions: + contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -34,6 +37,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Setup Java 21 (Temurin) uses: actions/setup-java@v4 @@ -68,16 +73,16 @@ jobs: uses: gradle/actions/setup-gradle@v3 - name: Gradle version - run: ./gradlew --version --no-daemon --console=plain + run: ./gradlew --version --no-daemon --console=plain --stacktrace - name: Static analysis (detekt) - run: ./gradlew detektAll --no-daemon --console=plain + run: ./gradlew detektAll --no-daemon --console=plain --stacktrace - name: Unit tests + coverage - run: ./gradlew runTest --no-daemon --console=plain + run: ./gradlew runTest --no-daemon --console=plain --stacktrace - name: Android Lint (app) - run: ./gradlew :app:lint --no-daemon --console=plain + run: ./gradlew :app:lint --no-daemon --console=plain --stacktrace - name: Gradle/AGP versions run: | @@ -87,10 +92,13 @@ jobs: grep -E '^android_plugin\s*=\s*"[0-9]+' gradle/libs.versions.toml || true - name: Assemble debug to produce native libs - run: ./gradlew :app:assembleDebug --no-daemon --console=plain + run: ./gradlew :app:assembleDebug --no-daemon --console=plain --stacktrace - name: readelf sanity (native libs) run: | + if ! command -v readelf >/dev/null 2>&1; then + sudo apt-get update -y && sudo apt-get install -y binutils + fi set +e echo "== Scanning native libraries (.so) ==" mapfile -t sos < <(find app/build -type f -name "*.so" | head -n 10) From f71a4718d12d1dd81ae65d1d6b47df2810e10488 Mon Sep 17 00:00:00 2001 From: William Richter Date: Fri, 29 Aug 2025 08:22:59 +0200 Subject: [PATCH 18/18] docs(roadmap): recommend migrating to NDK r28+ for 16 KB page sizes by default --- docs/roadmap.md | 4 ++-- roadmap.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/roadmap.md b/docs/roadmap.md index 1d4e550f31..739fd9fe52 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -157,10 +157,10 @@ Priority: P0 (must-do), P1 (should-do), P2 (nice-to-have) 13) Google Play 16KB page-size compliance (native libs) - Why: Play requires 16KB page-size support on newer devices; native libs must be compatible. - Acceptance: - - Rebuild native artifacts (e.g., sr25519) with an NDK that supports 16KB pages (r26+). + - Migrate native builds (e.g., sr25519) to NDK r28+ which compiles with 16 KB page sizes by default. - Verify with `readelf -l lib.so` that segment alignment/page-size is compliant; no Play Console warnings. - Prompt: - - Ensure `ndk;25.2.9519653` or newer in CI/local; consider bumping to latest stable NDK if needed. + - Plan upgrade to NDK r28+ in CI/local; update SDK installation steps and toolchains accordingly. - Keep native libs uncompressed in the bundle or verify packaging flags as required by Play guidance. - Keep a CI step to run `readelf -l` on built .so files and surface any issues in logs. diff --git a/roadmap.md b/roadmap.md index ac51afa925..010a22f31e 100644 --- a/roadmap.md +++ b/roadmap.md @@ -49,4 +49,4 @@ More roadmap items (P0/P1/P2), including technical debt and follow-ups, are main ## Build & Play Compliance - Gradle/AGP update: bump Gradle wrapper and Android Gradle Plugin to the latest stable release; remove deprecations (e.g., use `url = uri(...)`, `namespace = '…'`). Verify builds with JDK 21 locally and in CI. -- Google Play 16KB page size: ensure native libraries (e.g., sr25519) are built with an NDK that supports 16KB pages (r26+). Validate with `readelf -l` and address Play Console checks. Keep packaging compliant (uncompressed native libs or required flags). +- Google Play 16KB page size: migrate native libraries (e.g., sr25519) to NDK r28+ (16 KB pages by default). Validate with `readelf -l` and address Play Console checks. Keep packaging compliant (uncompressed native libs or required flags).