diff --git a/packages/komodo_defi_framework/app_build/build_config.json b/packages/komodo_defi_framework/app_build/build_config.json index c6427da..c9fe353 100644 --- a/packages/komodo_defi_framework/app_build/build_config.json +++ b/packages/komodo_defi_framework/app_build/build_config.json @@ -1,7 +1,7 @@ { "api": { - "api_commit_hash": "bb749a99344fb61e92410cb64b035dba1de35779", - "branch": "main", + "api_commit_hash": "405bcb7daf316477497eb6925cba0ca9640ab383", + "branch": "dev", "fetch_at_build_enabled": true, "concurrent_downloads_enabled": true, "source_urls": [ @@ -10,16 +10,16 @@ ], "platforms": { "web": { - "matching_keyword": "wasm", + "matching_pattern": "^kdf_[a-f0-9]+-wasm\\.zip$", "valid_zip_sha256_checksums": [ - "91ac9f0e880ec49aedab21c5df130ffc9475cdbf0b6428cf6862842142176293" + "1800ab7e8682f01d9a10679475509706b0414bc178937d6db95ebf84f29df84c" ], "path": "web/kdf/bin" }, "macos": { - "matching_keyword": "mac-arm64", + "matching_pattern": "^kdf_[a-f0-9]+-mac-arm64\\.zip$", "valid_zip_sha256_checksums": [ - "1a06b4e7d9b3db9ba9623445274ac420f5522d4ee56a6a2f3b305e56b6ae26c8" + "37161ccc3022f07d5e1bedf2069f3fe609cf12a18f8ca5fd4bbc32e0ce734cf5" ], "path": "macos/bin" } @@ -28,7 +28,7 @@ "coins": { "fetch_at_build_enabled": true, "update_commit_on_build": true, - "bundled_coins_repo_commit": "642abea7172b81db24b16bffc13783b9a0e400f5", + "bundled_coins_repo_commit": "eae824b3502f9da19cce891f93e8c2f98fbf534f", "coins_repo_api_url": "https://api.github.com/repos/KomodoPlatform/coins", "coins_repo_content_url": "https://komodoplatform.github.io/coins", "coins_repo_branch": "master", diff --git a/packages/komodo_wallet_build_transformer/lib/src/steps/fetch_defi_api_build_step.dart b/packages/komodo_wallet_build_transformer/lib/src/steps/fetch_defi_api_build_step.dart index 2f39f4d..62d5450 100644 --- a/packages/komodo_wallet_build_transformer/lib/src/steps/fetch_defi_api_build_step.dart +++ b/packages/komodo_wallet_build_transformer/lib/src/steps/fetch_defi_api_build_step.dart @@ -417,14 +417,13 @@ class FetchDefiApiStep extends BuildStep { ) async { final releases = await githubApiProvider.getReleases(); final apiVersionShortHash = apiCommitHash.substring(0, 7); - final matchingKeyword = config[platform]!.matchingKeyword; + final matchingConfig = config[platform]!.matchingConfig; for (final release in releases) { for (final asset in release.assets) { final url = asset.browserDownloadUrl; - if (url.contains(matchingKeyword) && - url.contains(apiVersionShortHash)) { + if (matchingConfig.matches(url) && url.contains(apiVersionShortHash)) { final commitHash = await githubApiProvider.getLatestCommitHash( branch: release.tagName, ); @@ -454,14 +453,14 @@ class FetchDefiApiStep extends BuildStep { _checkResponseSuccess(response); final document = parser.parse(response.body); - final matchingKeyword = config[platform]!.matchingKeyword; + final matchingConfig = config[platform]!.matchingConfig; final extensions = ['.zip']; final apiVersionShortHash = apiCommitHash.substring(0, 7); for (final element in document.querySelectorAll('a')) { final href = element.attributes['href']; if (href != null && - href.contains(matchingKeyword) && + matchingConfig.matches(href) && extensions.any(href.endsWith) && href.contains(apiVersionShortHash)) { return '$sourceUrl/$apiBranch/$href'; diff --git a/packages/komodo_wallet_build_transformer/lib/src/steps/models/api/api_build_platform_config.dart b/packages/komodo_wallet_build_transformer/lib/src/steps/models/api/api_build_platform_config.dart index e2a1a4d..bd371ed 100644 --- a/packages/komodo_wallet_build_transformer/lib/src/steps/models/api/api_build_platform_config.dart +++ b/packages/komodo_wallet_build_transformer/lib/src/steps/models/api/api_build_platform_config.dart @@ -1,57 +1,88 @@ +import 'package:komodo_wallet_build_transformer/src/steps/models/api/api_file_matching_config.dart'; + +/// Configuration for a specific platform's API build settings. +/// +/// This class contains the configuration needed to download and verify API +/// binaries for a specific platform (e.g., 'web', 'macos', 'windows', etc.). class ApiBuildPlatformConfig { + /// Creates a new [ApiBuildPlatformConfig] with required parameters. + /// + /// The [matchingConfig] specifies how to identify the correct API file. + /// [validZipSha256Checksums] contains the list of valid SHA256 checksums for + /// verification. + /// [path] specifies where the API files should be stored. ApiBuildPlatformConfig({ - required this.matchingKeyword, + required this.matchingConfig, required this.validZipSha256Checksums, required this.path, - }); + }) : assert( + validZipSha256Checksums.isNotEmpty, + 'At least one valid checksum must be provided', + ); - /// Creates an instance of [ApiBuildPlatformConfig] from a JSON object. + /// Creates a [ApiBuildPlatformConfig] from a JSON map. /// - /// Throws an [ArgumentError] if the object does not match the expected - /// structure. + /// The JSON must contain either 'matching_keyword' or 'matching_pattern', + /// 'valid_zip_sha256_checksums' as a non-empty list, and a 'path' string. + /// Throws a [FormatException] if the JSON is invalid. factory ApiBuildPlatformConfig.fromJson(Map json) { - if (!json.containsKey('matching_keyword')) { - throw ArgumentError('missing matching_keyword'); - } - if (!json.containsKey('valid_zip_sha256_checksums')) { - throw ArgumentError('missing valid_zip_sha256_checksums'); + throw FormatException( + 'Missing required field: valid_zip_sha256_checksums', + json.toString(), + ); } if (!json.containsKey('path')) { - throw ArgumentError('missing path'); + throw FormatException('Missing required field: path', json.toString()); } + if (!json.containsKey('matching_keyword') && + !json.containsKey('matching_pattern')) { + throw FormatException( + 'Either matching_keyword or matching_pattern must be provided', + json.toString(), + ); + } + + final checksums = json['valid_zip_sha256_checksums']; + if (checksums is! List || checksums.isEmpty) { + throw FormatException( + 'valid_zip_sha256_checksums must be a non-empty list', + json.toString(), + ); + } + + final matchingConfig = ApiFileMatchingConfig( + matchingKeyword: json['matching_keyword'] as String?, + matchingPattern: json['matching_pattern'] as String?, + ); + return ApiBuildPlatformConfig( - matchingKeyword: json['matching_keyword'] as String, - validZipSha256Checksums: - List.from(json['valid_zip_sha256_checksums'] as List), + matchingConfig: matchingConfig, + validZipSha256Checksums: List.from(checksums), path: json['path'] as String, ); } - String matchingKeyword; - List validZipSha256Checksums; - String path; + /// Configuration for matching the correct API file + final ApiFileMatchingConfig matchingConfig; - Map toJson() { - return { - 'matching_keyword': matchingKeyword, - 'valid_zip_sha256_checksums': validZipSha256Checksums, - 'path': path, - }; - } + /// List of valid SHA256 checksums for the API zip file + /// + /// Multiple checksums can be valid at the same time to support different + /// versions or variations of the API. + final List validZipSha256Checksums; - ApiBuildPlatformConfig copyWith({ - String? matchingKeyword, - List? validZipSha256Checksums, - String? path, - }) { - return ApiBuildPlatformConfig( - matchingKeyword: matchingKeyword ?? this.matchingKeyword, - validZipSha256Checksums: - validZipSha256Checksums ?? this.validZipSha256Checksums, - path: path ?? this.path, - ); - } + /// Path where the API files should be stored + /// + /// This path is relative to the project's artifact output directory. + final String path; + + /// Converts the configuration to a JSON map. + Map toJson() => { + ...matchingConfig.toJson(), + 'valid_zip_sha256_checksums': validZipSha256Checksums, + 'path': path, + }; } diff --git a/packages/komodo_wallet_build_transformer/lib/src/steps/models/api/api_file_matching_config.dart b/packages/komodo_wallet_build_transformer/lib/src/steps/models/api/api_file_matching_config.dart new file mode 100644 index 0000000..7c3e017 --- /dev/null +++ b/packages/komodo_wallet_build_transformer/lib/src/steps/models/api/api_file_matching_config.dart @@ -0,0 +1,44 @@ +/// Configuration for matching API files using either a simple keyword or regex pattern. +class ApiFileMatchingConfig { + ApiFileMatchingConfig({ + this.matchingKeyword, + this.matchingPattern, + }) : assert( + matchingKeyword != null || matchingPattern != null, + 'Either matchingKeyword or matchingPattern must be provided', + ); + + factory ApiFileMatchingConfig.fromJson(Map json) { + return ApiFileMatchingConfig( + matchingKeyword: json['matching_keyword'] as String?, + matchingPattern: json['matching_pattern'] as String?, + ); + } + + /// Simple substring to match in the filename + final String? matchingKeyword; + + /// Regular expression pattern to match against the filename + final String? matchingPattern; + + /// Checks if the given input string matches either the keyword or pattern + bool matches(String input) { + if (matchingPattern != null) { + try { + final regex = RegExp(matchingPattern!); + return regex.hasMatch(input); + } catch (e) { + throw FormatException( + 'Invalid regex pattern: $matchingPattern', + e.toString(), + ); + } + } + return matchingKeyword != null && input.contains(matchingKeyword!); + } + + Map toJson() => { + if (matchingKeyword != null) 'matching_keyword': matchingKeyword, + if (matchingPattern != null) 'matching_pattern': matchingPattern, + }; +} diff --git a/packages/komodo_wallet_build_transformer/pubspec.lock b/packages/komodo_wallet_build_transformer/pubspec.lock index 0c37276..fc9d8f9 100644 --- a/packages/komodo_wallet_build_transformer/pubspec.lock +++ b/packages/komodo_wallet_build_transformer/pubspec.lock @@ -5,23 +5,23 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "45cfa8471b89fb6643fe9bf51bd7931a76b8f5ec2d65de4fb176dba8d4f22c77" + sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" url: "https://pub.dev" source: hosted - version: "73.0.0" + version: "76.0.0" _macros: dependency: transitive description: dart source: sdk - version: "0.3.2" + version: "0.3.3" analyzer: dependency: transitive description: name: analyzer - sha256: "4959fec185fe70cce007c57e9ab6983101dbe593d2bf8bbfb4453aaec0cf470a" + sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" url: "https://pub.dev" source: hosted - version: "6.8.0" + version: "6.11.0" args: dependency: "direct main" description: @@ -186,10 +186,10 @@ packages: dependency: transitive description: name: macros - sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" url: "https://pub.dev" source: hosted - version: "0.1.2-main.4" + version: "0.1.3-main.0" matcher: dependency: transitive description: