feat(runtime): start a first install from the chain list the APK was built with

A first install has no chains until chains.json is fetched, and the fetch
retries forever: with GitHub and its mirrors unreachable the wallet stays
empty.

The runtime module now bundles the live chains.json at build time
(bundleChainsConfig, run before preBuild, falling back to jsDelivr and
refusing anything that is not a non-empty JSON array). When the local
database is empty, ChainSyncService tries the network once and, if that
fails, applies the bundled list so the wallet opens; the fetched list then
replaces it through the usual diff as soon as it arrives.
This commit is contained in:
Satoshi Qazi Muhammed committed 2026-10-31 00:39:50 +04:00
1 parent 0b1319c866
commit ec9a2cf307
5 files changed
+167 -10

No files matched your search

+45 -3
View File
@@ -1,11 +1,14 @@
apply from: '../scripts/secrets.gradle'
apply plugin: 'kotlin-parcelize'
def chainsUrl = "https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/master/chains/v22/android/chains.json"
def bundledConfigDir = "$buildDir/generated/bundledConfig"
android {
defaultConfig {
buildConfigField "String", "CHAINS_URL", "\"https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/master/chains/v22/android/chains.json\""
buildConfigField "String", "CHAINS_URL", "\"$chainsUrl\""
buildConfigField "String", "EVM_ASSETS_URL", "\"https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/master/assets/evm/v3/assets.json\""
buildConfigField "String", "PRE_CONFIGURED_CHAINS_URL", "\"https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/master/chains/v22/preConfigured/chains.json\""
buildConfigField "String", "PRE_CONFIGURED_CHAIN_DETAILS_URL", "\"https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/master/chains/v22/preConfigured/details\""
@@ -27,7 +30,7 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "String", "CHAINS_URL", "\"https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/master/chains/v22/android/chains.json\""
buildConfigField "String", "CHAINS_URL", "\"$chainsUrl\""
buildConfigField "String", "EVM_ASSETS_URL", "\"https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/master/assets/evm/v3/assets.json\""
buildConfigField "String", "PRE_CONFIGURED_CHAINS_URL", "\"https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/master/chains/v22/preConfigured/chains.json\""
buildConfigField "String", "PRE_CONFIGURED_CHAIN_DETAILS_URL", "\"https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/master/chains/v22/preConfigured/details\""
@@ -66,4 +69,43 @@ dependencies {
androidTestImplementation androidTestRunnerDep
androidTestImplementation androidTestRulesDep
androidTestImplementation androidJunitDep
}
}
// The chain list a first install starts from when none can be fetched (AssetBundledChains). It is the live
// list at build time, so every build carries the chains that were current when it was made.
def bundleChainsConfig = tasks.register("bundleChainsConfig") {
def target = file("$bundledConfigDir/bundled-config/chains.json")
outputs.file(target)
outputs.upToDateWhen { false }
doLast {
def sources = [
chainsUrl,
chainsUrl.replace("https://raw.githubusercontent.com/pezkuwichain/pezkuwi-wallet-utils/master/",
"https://cdn.jsdelivr.net/gh/pezkuwichain/pezkuwi-wallet-utils@master/")
]
def bytes = null
for (source in sources) {
try {
bytes = new URL(source).getBytes(connectTimeout: 20_000, readTimeout: 60_000)
break
} catch (IOException e) {
logger.warn("bundleChainsConfig: $source failed: $e")
}
}
if (bytes == null) throw new GradleException("bundleChainsConfig: no source answered")
def chains = new groovy.json.JsonSlurper().parse(bytes)
if (!(chains instanceof List) || chains.isEmpty()) {
throw new GradleException("bundleChainsConfig: the chain list is not a non-empty JSON array")
}
target.parentFile.mkdirs()
target.bytes = bytes
def sha256 = java.security.MessageDigest.getInstance("SHA-256").digest(bytes).encodeHex().toString()
logger.lifecycle("bundleChainsConfig: ${chains.size()} chains, sha256 $sha256")
}
}
android.sourceSets.main.assets.srcDir(bundledConfigDir)
preBuild.dependsOn(bundleChainsConfig)