diff --git a/.env.example b/.env.example index 05f4a13a..d4cb82dd 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -EXPLORER_ADDRESS = 'witnet.network' +EXPLORER_ADDRESS = 'witscan.xyz' EXPLORER_DEV_ADDRESS = '0.0.0.0' # [ Integration Test Settings ] diff --git a/integration_test/test_utils.dart b/integration_test/test_utils.dart index ec5ef2ab..3edb031c 100644 --- a/integration_test/test_utils.dart +++ b/integration_test/test_utils.dart @@ -80,7 +80,7 @@ Future tapButton( case String: finder = widgetByText(value); break; - case IconDataSolid: + case IconData: finder = widgetByIcon(value); break; case PaddedButton: diff --git a/ios/Gemfile.lock b/ios/Gemfile.lock index a741ce56..e8b0a563 100644 --- a/ios/Gemfile.lock +++ b/ios/Gemfile.lock @@ -1,9 +1,11 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.6) + CFPropertyList (3.0.7) + base64 + nkf rexml - activesupport (7.1.2) + activesupport (7.1.3.2) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -13,7 +15,7 @@ GEM minitest (>= 5.1) mutex_m tzinfo (~> 2.0) - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) @@ -21,29 +23,29 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.862.0) - aws-sdk-core (3.190.0) + aws-partitions (1.894.0) + aws-sdk-core (3.191.3) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.74.0) - aws-sdk-core (~> 3, >= 3.188.0) + aws-sdk-kms (1.77.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.141.0) - aws-sdk-core (~> 3, >= 3.189.0) + aws-sdk-s3 (1.143.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) base64 (0.2.0) - bigdecimal (3.1.4) + bigdecimal (3.1.6) claide (1.1.0) - cocoapods (1.14.3) + cocoapods (1.15.2) addressable (~> 2.8) claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.14.3) + cocoapods-core (= 1.15.2) cocoapods-deintegrate (>= 1.0.3, < 2.0) cocoapods-downloader (>= 2.1, < 3.0) cocoapods-plugins (>= 1.0.0, < 2.0) @@ -58,7 +60,7 @@ GEM nap (~> 1.0) ruby-macho (>= 2.3.0, < 3.0) xcodeproj (>= 1.23.0, < 2.0) - cocoapods-core (1.14.3) + cocoapods-core (1.15.2) activesupport (>= 5.0, < 8) addressable (~> 2.8) algoliasearch (~> 1.0) @@ -81,12 +83,12 @@ GEM colored2 (3.1.2) commander (4.6.0) highline (~> 2.0.0) - concurrent-ruby (1.2.2) + concurrent-ruby (1.2.3) connection_pool (2.4.1) declarative (0.0.20) digest-crc (0.6.5) rake (>= 12.0.0, < 14.0.0) - domain_name (0.6.20231109) + domain_name (0.6.20240107) dotenv (2.8.1) drb (2.2.0) ruby2_keywords @@ -94,7 +96,7 @@ GEM escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) - excon (0.105.0) + excon (0.109.0) faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) @@ -123,8 +125,8 @@ GEM faraday-retry (1.0.3) faraday_middleware (1.2.0) faraday (~> 1.0) - fastimage (2.2.7) - fastlane (2.217.0) + fastimage (2.3.0) + fastlane (2.219.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -143,6 +145,7 @@ GEM gh_inspector (>= 1.1.2, < 2.0.0) google-apis-androidpublisher_v3 (~> 0.3) google-apis-playcustomapp_v1 (~> 0.1) + google-cloud-env (>= 1.6.0, < 2.0.0) google-cloud-storage (~> 1.31) highline (~> 2.0) http-cookie (~> 1.0.5) @@ -151,7 +154,7 @@ GEM mini_magick (>= 4.9.4, < 5.0.0) multipart-post (>= 2.0.0, < 3.0.0) naturally (~> 2.2) - optparse (~> 0.1.1) + optparse (>= 0.1.1) plist (>= 3.1.0, < 4.0.0) rubyzip (>= 2.0.0, < 3.0.0) security (= 0.1.3) @@ -168,9 +171,9 @@ GEM fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.53.0) + google-apis-androidpublisher_v3 (0.54.0) google-apis-core (>= 0.11.0, < 2.a) - google-apis-core (0.11.2) + google-apis-core (0.11.3) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -178,24 +181,23 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.a) rexml - webrick google-apis-iamcredentials_v1 (0.17.0) google-apis-core (>= 0.11.0, < 2.a) google-apis-playcustomapp_v1 (0.13.0) google-apis-core (>= 0.11.0, < 2.a) - google-apis-storage_v1 (0.29.0) + google-apis-storage_v1 (0.31.0) google-apis-core (>= 0.11.0, < 2.a) - google-cloud-core (1.6.0) - google-cloud-env (~> 1.0) + google-cloud-core (1.6.1) + google-cloud-env (>= 1.0, < 3.a) google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) google-cloud-errors (1.3.1) - google-cloud-storage (1.45.0) + google-cloud-storage (1.47.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.29.0) + google-apis-storage_v1 (~> 0.31.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) @@ -212,22 +214,24 @@ GEM i18n (1.14.1) concurrent-ruby (~> 1.0) jmespath (1.6.2) - json (2.6.3) - jwt (2.7.1) + json (2.7.1) + jwt (2.8.0) + base64 mini_magick (4.12.0) mini_mime (1.1.5) - minitest (5.20.0) + minitest (5.22.2) molinillo (0.8.0) multi_json (1.15.0) - multipart-post (2.3.0) + multipart-post (2.4.0) mutex_m (0.2.0) nanaimo (0.3.0) nap (1.1.0) naturally (2.2.1) netrc (0.11.0) - optparse (0.1.1) + nkf (0.2.0) + optparse (0.4.0) os (1.1.4) - plist (3.7.0) + plist (3.7.1) public_suffix (4.0.7) rake (13.1.0) representable (3.2.0) @@ -241,7 +245,7 @@ GEM ruby2_keywords (0.0.5) rubyzip (2.3.2) security (0.1.3) - signet (0.18.0) + signet (0.19.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) @@ -254,7 +258,7 @@ GEM unicode-display_width (>= 1.1.1, < 3) trailblazer-option (0.1.2) tty-cursor (0.7.1) - tty-screen (0.8.1) + tty-screen (0.8.2) tty-spinner (0.9.3) tty-cursor (~> 0.7) typhoeus (1.4.1) @@ -263,9 +267,8 @@ GEM concurrent-ruby (~> 1.0) uber (0.1.0) unicode-display_width (2.5.0) - webrick (1.8.1) word_wrap (1.0.0) - xcodeproj (1.23.0) + xcodeproj (1.24.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) @@ -278,12 +281,12 @@ GEM xcpretty (~> 0.2, >= 0.0.7) PLATFORMS - x86_64-darwin-20 - x86_64-darwin-21 + arm64-darwin-23 + ruby DEPENDENCIES cocoapods (~> 1.11) fastlane BUNDLED WITH - 2.4.10 + 2.5.3 diff --git a/ios/Podfile b/ios/Podfile index 60b1dca8..ca670f00 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -34,10 +34,22 @@ target 'Runner' do end post_install do |installer| + # fix xcode 15 DT_TOOLCHAIN_DIR - remove after fix oficially - https://github.com/CocoaPods/CocoaPods/issues/12065 + installer.aggregate_targets.each do |target| + target.xcconfigs.each do |variant, xcconfig| + xcconfig_path = target.client_root + target.xcconfig_relative_path(variant) + IO.write(xcconfig_path, IO.read(xcconfig_path).gsub("DT_TOOLCHAIN_DIR", "TOOLCHAIN_DIR")) + end + end + installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' + if config.base_configuration_reference.is_a? Xcodeproj::Project::Object::PBXFileReference + xcconfig_path = config.base_configuration_reference.real_path + IO.write(xcconfig_path, IO.read(xcconfig_path).gsub("DT_TOOLCHAIN_DIR", "TOOLCHAIN_DIR")) + end end end end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 202c9bb0..988aa2e8 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -153,6 +153,6 @@ SPEC CHECKSUMS: shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b -PODFILE CHECKSUM: 3118be2ea3b7322e964cfa22fa42faa4e39f6c5c +PODFILE CHECKSUM: eb775b146a9efb4c1f1c55cba9689f227523a140 -COCOAPODS: 1.12.1 +COCOAPODS: 1.15.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index c751885a..d3bfe33c 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -9,11 +9,11 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 57712459E87A24121377D7A0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2485BAA89896304F8F81EA7 /* Pods_Runner.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - E462606D4212DDDFB58355AD /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F8AB81A31946B4CA55C093 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -30,15 +30,14 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 07DDDEFB8BEB545C96D28C7B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 11B13D8074A685345B1CD9C7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 26F8AB81A31946B4CA55C093 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 28BE900C448E3A4E51306AE7 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 57B3355B057BAE30BDDD5E3A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 67E8A092530DE5EA70E845AD /* Pods-Runner.debug-e2e.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-e2e.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-e2e.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 77A45E63F8E993C45BB74E49 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; @@ -47,7 +46,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - B77918AB0DC0CB4B83C5188B /* Pods-Runner.debug-e2e.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-e2e.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-e2e.xcconfig"; sourceTree = ""; }; + B2485BAA89896304F8F81EA7 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E7A86D7B2E3942504DC0050C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -55,30 +55,30 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E462606D4212DDDFB58355AD /* Pods_Runner.framework in Frameworks */, + 57712459E87A24121377D7A0 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 380CAFE863EF9675C83D9D3F /* Pods */ = { + 2C29AB87111E84422AF497AA /* Frameworks */ = { isa = PBXGroup; children = ( - 11B13D8074A685345B1CD9C7 /* Pods-Runner.debug.xcconfig */, - 07DDDEFB8BEB545C96D28C7B /* Pods-Runner.release.xcconfig */, - 57B3355B057BAE30BDDD5E3A /* Pods-Runner.profile.xcconfig */, - B77918AB0DC0CB4B83C5188B /* Pods-Runner.debug-e2e.xcconfig */, + B2485BAA89896304F8F81EA7 /* Pods_Runner.framework */, ); - path = Pods; + name = Frameworks; sourceTree = ""; }; - 6729B53F71FC9EF68B1D676B /* Frameworks */ = { + 380CAFE863EF9675C83D9D3F /* Pods */ = { isa = PBXGroup; children = ( - 26F8AB81A31946B4CA55C093 /* Pods_Runner.framework */, + 77A45E63F8E993C45BB74E49 /* Pods-Runner.debug.xcconfig */, + 67E8A092530DE5EA70E845AD /* Pods-Runner.debug-e2e.xcconfig */, + 28BE900C448E3A4E51306AE7 /* Pods-Runner.release.xcconfig */, + E7A86D7B2E3942504DC0050C /* Pods-Runner.profile.xcconfig */, ); - name = Frameworks; + path = Pods; sourceTree = ""; }; 9740EEB11CF90186004384FC /* Flutter */ = { @@ -99,7 +99,7 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, 380CAFE863EF9675C83D9D3F /* Pods */, - 6729B53F71FC9EF68B1D676B /* Frameworks */, + 2C29AB87111E84422AF497AA /* Frameworks */, ); sourceTree = ""; }; @@ -133,14 +133,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - D349F51D1E533249A81E08F5 /* [CP] Check Pods Manifest.lock */, + 7D32B05510DCFC07CA6E8F16 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 2B8A8EA77A13CB47D01AE23F /* [CP] Embed Pods Frameworks */, + 446788008C4190259B99F04B /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -199,23 +199,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 2B8A8EA77A13CB47D01AE23F /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -232,22 +215,24 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 9740EEB61CF901F6004384FC /* Run Script */ = { + 446788008C4190259B99F04B /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); - inputPaths = ( + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "Run Script"; - outputPaths = ( + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; }; - D349F51D1E533249A81E08F5 /* [CP] Check Pods Manifest.lock */ = { + 7D32B05510DCFC07CA6E8F16 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -269,6 +254,21 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -439,7 +439,7 @@ }; 5F5490232A84DBB8003C5F01 /* Debug-e2e */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B77918AB0DC0CB4B83C5188B /* Pods-Runner.debug-e2e.xcconfig */; + baseConfigurationReference = 67E8A092530DE5EA70E845AD /* Pods-Runner.debug-e2e.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; diff --git a/lib/bloc/crypto/crypto_bloc.dart b/lib/bloc/crypto/crypto_bloc.dart index 48591c06..d67ba4f6 100644 --- a/lib/bloc/crypto/crypto_bloc.dart +++ b/lib/bloc/crypto/crypto_bloc.dart @@ -6,7 +6,7 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:my_wit_wallet/util/storage/cache/implementations/vtt_get_through_block_explorer.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:witnet/data_structures.dart'; import 'package:witnet/constants.dart'; import 'package:witnet/crypto.dart'; @@ -299,7 +299,7 @@ class CryptoBloc extends Bloc { await _vttGetThroughBlockExplorer.get(_hash); if (valueTransferInfo != null) { account.vtts.add(valueTransferInfo); - Hash txnHash = Hash.fromString(valueTransferInfo.txnHash); + Hash txnHash = Hash.fromString(valueTransferInfo.hash); if (account.utxosByTransactionId.containsKey(txnHash)) { balance += BalanceInfo.fromUtxoList( account.utxosByTransactionId[txnHash]!, @@ -325,23 +325,25 @@ class CryptoBloc extends Bloc { try { /// retrieve any Block Hashes final addressBlocks = await apiExplorer.address( - value: account.address, tab: 'blocks') as AddressBlocks; - - /// retrieve each block - for (int i = 0; i < addressBlocks.blocks.length; i++) { - BlockInfo blockInfo = addressBlocks.blocks.elementAt(i); - String _hash = blockInfo.blockID; - var result = await apiExplorer.hash(_hash); - - /// create a MintEntry from the BlockInfo and MintInfo - BlockDetails blockDetails = result as BlockDetails; - MintEntry mintEntry = MintEntry.fromBlockMintInfo( - blockInfo, - blockDetails.mintInfo, - ); - account.mintHashes.add(mintEntry.blockHash); - account.mints.add(mintEntry); - await db.addMint(mintEntry); + value: account.address, + tab: 'blocks') as PaginatedRequest; + if (addressBlocks.data != null) { + /// retrieve each block + for (int i = 0; i < addressBlocks.data!.blocks.length; i++) { + BlockInfo blockInfo = addressBlocks.data!.blocks.elementAt(i); + String _hash = blockInfo.hash; + + /// Creates a MintEntry from the BlockInfo and MintInfo + BlockDetails blockDetails = + await apiExplorer.hash(_hash) as BlockDetails; + MintEntry mintEntry = MintEntry.fromBlockMintInfo( + blockInfo, + blockDetails, + ); + account.mintHashes.add(mintEntry.blockHash); + account.mints.add(mintEntry); + await db.addMint(mintEntry); + } } return account; } catch (e) { @@ -354,9 +356,9 @@ class CryptoBloc extends Bloc { try { final addressValueTransfers = await apiExplorer.address( value: account.address, - tab: 'value_transfers') as AddressValueTransfers; + tab: 'value_transfers') as PaginatedRequest; account.vttHashes = List.from( - addressValueTransfers.transactionHashes.map((e) => e)); + addressValueTransfers.data.addressValueTransfers.map((e) => e.hash)); final List _utxos = await apiExplorer.utxos(address: account.address); account.updateUtxos(_utxos); diff --git a/lib/bloc/explorer/api_explorer.dart b/lib/bloc/explorer/api_explorer.dart index 841e2d04..c0441570 100644 --- a/lib/bloc/explorer/api_explorer.dart +++ b/lib/bloc/explorer/api_explorer.dart @@ -1,4 +1,4 @@ -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:witnet/data_structures.dart'; import 'package:witnet/explorer.dart'; import 'package:witnet/schema.dart'; @@ -37,7 +37,7 @@ class ApiExplorer { Future hash(String value, [bool simple = true]) async { try { await delay(); - return await client.hash(value, simple); + return await client.hash(value: value, simple: simple, findAll: true); } on ExplorerException { rethrow; } @@ -52,15 +52,6 @@ class ApiExplorer { } } - Future network() async { - try { - await delay(); - return await client.network(); - } on ExplorerException { - rethrow; - } - } - Future getStatus() async { try { await delay(); @@ -71,37 +62,12 @@ class ApiExplorer { } } - Future pending() async { - try { - await delay(); - return await client.mempool(); - } on ExplorerException { - rethrow; - } - } - - Future richList({int start = 0, int stop = 1000}) async { - try { - await delay(); - return await client.richList(start: start, stop: stop); - } on ExplorerException { - rethrow; - } - } - - Future address({required String value, required String tab}) async { - try { - await delay(); - return await client.address(value: value, tab: tab); - } on ExplorerException { - rethrow; - } - } - - Future blockchain({int block = -100}) async { + Future> address( + {required String value, required String tab}) async { try { await delay(); - return await client.blockchain(block: block); + return await client.address(value: value, tab: tab, findAll: true) + as PaginatedRequest; } on ExplorerException { rethrow; } @@ -164,7 +130,7 @@ class ApiExplorer { AddressValueTransfers vtts = await getValueTransferHashes(account); List vttsToUpdate = []; - vttsToUpdate.addAll(vtts.transactionHashes); + vttsToUpdate.addAll(vtts.addressValueTransfers.map((e) => e.hash)); List vttsInDb = []; @@ -172,8 +138,8 @@ class ApiExplorer { for (int i = 0; i < vttsToUpdate.length; i++) { try { - ValueTransferInfo vtt = await getVtt(vttsToUpdate[i]); - await db.addVtt(vtt); + ValueTransferInfo? vtt = await getVtt(vttsToUpdate[i]); + if (vtt != null) await db.addVtt(vtt); } catch (e) { print('Error adding vtt to database $e'); rethrow; @@ -223,25 +189,24 @@ class ApiExplorer { /// get the list of value transfer hashes from the explorer for a given address. Future getValueTransferHashes(Account account) async { AddressValueTransfers vtts = - await address(value: account.address, tab: 'value_transfers'); + (await address(value: account.address, tab: 'value_transfers')).data; return vtts; } /// get the ValueTransferInfo from the explorer for a given transaction ID. - Future getVtt(String transactionId) async { - var result = await hash(transactionId); - return result as ValueTransferInfo; + Future getVtt(String transactionId) async { + return await hash(transactionId) as ValueTransferInfo?; } Future getMint(BlockInfo blockInfo) async { - String _hash = blockInfo.blockID; + String _hash = blockInfo.hash; var result = await Locator.instance.get().hash(_hash); /// create a MintEntry from the BlockInfo and MintInfo BlockDetails blockDetails = result as BlockDetails; MintEntry mintEntry = MintEntry.fromBlockMintInfo( blockInfo, - blockDetails.mintInfo, + blockDetails, ); return mintEntry; } diff --git a/lib/bloc/explorer/explorer_bloc.dart b/lib/bloc/explorer/explorer_bloc.dart index 80d4c92e..d2082aa2 100644 --- a/lib/bloc/explorer/explorer_bloc.dart +++ b/lib/bloc/explorer/explorer_bloc.dart @@ -7,7 +7,7 @@ import 'package:my_wit_wallet/shared/api_database.dart'; import 'package:my_wit_wallet/shared/locator.dart'; import 'package:my_wit_wallet/util/storage/database/account.dart'; import 'package:my_wit_wallet/util/storage/database/stats.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/util/storage/database/wallet.dart'; import 'package:my_wit_wallet/util/storage/database/wallet_storage.dart'; import 'package:witnet/data_structures.dart'; @@ -88,7 +88,7 @@ class ExplorerBloc extends Bloc { .get() .address(value: event.address, tab: event.tab); emit(ExplorerState.dataLoaded( - data: resp.jsonMap(), query: ExplorerQuery.address)); + data: resp.data.jsonMap(), query: ExplorerQuery.address)); } catch (err) { emit(ExplorerState.error()); rethrow; @@ -207,7 +207,8 @@ class ExplorerBloc extends Bloc { emit(ExplorerState.synced(database.walletStorage)); } - Future _getStatsByAddress(String address, String tab) async { + Future> _getStatsByAddress( + String address, String tab) async { try { return await Locator.instance .get() @@ -243,8 +244,8 @@ class ExplorerBloc extends Bloc { try { final result = await _getStatsByAddress(address, MasterAccountStats.blocks.name); - if (result.runtimeType != AddressBlocks && result['error'] != null) { - print('Error getting address blocks: ${result['error']}'); + if (result.runtimeType != AddressBlocks && result.data['error'] != null) { + print('Error getting address blocks: ${result.data['error']}'); return null; } return result as AddressBlocks?; @@ -259,12 +260,12 @@ class ExplorerBloc extends Bloc { try { final result = await _getStatsByAddress( address, MasterAccountStats.data_requests_solved.name); - if (result.runtimeType != AddressDataRequestsSolved && - result['error'] != null) { - print('Error getting data requests solved: ${result['error']}'); + if (result.data.runtimeType != AddressDataRequestsSolved) { + print( + 'Error getting data requests solved for address: ${result.data.address}'); return null; } - return result as AddressDataRequestsSolved?; + return result.data as AddressDataRequestsSolved?; } catch (err) { print('Error getting data requests solved: $err'); rethrow; @@ -292,7 +293,7 @@ class ExplorerBloc extends Bloc { totalBlocksMined: blocks.length, totalFeesPayed: feesPayed ?? 0, totalRewards: totalRewards ?? 0, - totalDrSolved: dataRequestsSolved?.numDataRequestsSolved ?? 0); + totalDrSolved: dataRequestsSolved?.dataRequestsSolved.length ?? 0); } Future _updateDBStatsFromExplorer( @@ -327,30 +328,32 @@ class ExplorerBloc extends Bloc { Future _syncAccountVtts(Account account) async { try { - AddressValueTransfers vtts = await explorer.address( - value: account.address, tab: 'value_transfers'); + AddressValueTransfers vtts = (await explorer.address( + value: account.address, tab: 'value_transfers')) + .data; WalletStorage walletStorage = database.walletStorage; - - for (int i = 0; i < vtts.transactionHashes.length; i++) { - String transactionId = vtts.transactionHashes[i]; - ValueTransferInfo? vtt = walletStorage.getVtt(transactionId); - + for (int i = 0; i < vtts.addressValueTransfers.length; i++) { + AddressValueTransferInfo newVtt = vtts.addressValueTransfers[i]; + ValueTransferInfo? vtt = walletStorage.getVtt(newVtt.hash); if (vtt != null) { - /// this vtt.status check for "confirmed" is in the local database - if (vtt.status != "confirmed") { - ValueTransferInfo _vtt = await explorer.getVtt(transactionId); + if (vtt.status != TxStatusLabel.confirmed) { + ValueTransferInfo? _vtt = await explorer.getVtt(newVtt.hash); + if (_vtt != null) { + walletStorage.setVtt( + database.walletStorage.currentWallet.id, _vtt); + database.addOrUpdateVttInDB(_vtt); + } + } + } else { + ValueTransferInfo? _vtt = await explorer.getVtt(newVtt.hash); + if (_vtt != null) { walletStorage.setVtt(database.walletStorage.currentWallet.id, _vtt); database.addOrUpdateVttInDB(_vtt); } - } else { - ValueTransferInfo _vtt = await explorer.getVtt(transactionId); - walletStorage.setVtt(database.walletStorage.currentWallet.id, _vtt); - database.addOrUpdateVttInDB(_vtt); } } - account.vttHashes.clear(); - account.vttHashes.addAll(vtts.transactionHashes); + account.vttHashes.addAll(vtts.addressValueTransfers.map((e) => e.hash)); return account; } catch (e) { print('Error updating vtts from explorer: $e'); @@ -361,31 +364,34 @@ class ExplorerBloc extends Bloc { Future _syncAccountMints(Account account) async { try { /// retrieve all Block Hashes - final addressBlocks = await explorer.address( - value: account.address, tab: 'blocks') as AddressBlocks; - - /// check if the list of transaction is already in the database - for (int i = 0; i < addressBlocks.blocks.length; i++) { - String blockHash = addressBlocks.blocks[i].blockID; - MintEntry? mintEntry = database.walletStorage.getMint(blockHash); - BlockInfo blockInfo = addressBlocks.blocks.elementAt(i); - - if (mintEntry != null) { - /// this mintEntry.status check for "confirmed" is in the local database - if (mintEntry.status != "confirmed") { + AddressBlocks? addressBlocks = (await explorer.address( + value: account.address, + tab: 'blocks') as PaginatedRequest) + .data; + + if (addressBlocks != null) { + /// check if the list of transaction is already in the database + for (int i = 0; i < addressBlocks.blocks.length; i++) { + String blockHash = addressBlocks.blocks[i].hash; + MintEntry? mintEntry = database.walletStorage.getMint(blockHash); + BlockInfo blockInfo = addressBlocks.blocks.elementAt(i); + + if (mintEntry != null) { + /// this mintEntry.status check for "confirmed" is in the local database + if (mintEntry.status != TxStatusLabel.confirmed) { + MintEntry mintEntry = await explorer.getMint(blockInfo); + await account.addMint(mintEntry); + } + } else { MintEntry mintEntry = await explorer.getMint(blockInfo); await account.addMint(mintEntry); } - } else { - MintEntry mintEntry = await explorer.getMint(blockInfo); - await account.addMint(mintEntry); } - } - - account.mintHashes.clear(); - account.mintHashes - .addAll(addressBlocks.blocks.map((block) => block.blockID)); + account.mintHashes.clear(); + account.mintHashes + .addAll(addressBlocks.blocks.map((block) => block.hash)); + } return account; } catch (e) { print('Error syncing mints $e'); @@ -442,7 +448,6 @@ class ExplorerBloc extends Bloc { /// get a list of any pending transactions List unconfirmedVtts = wallet.unconfirmedTransactions(); - if (wallet.walletType == WalletType.hd) { /// maintain gap limit for BIP39 await wallet.ensureGapLimit(); @@ -471,7 +476,6 @@ class ExplorerBloc extends Bloc { print('Error getting UTXOs from the explorer $err'); rethrow; } - await syncWalletStorage(utxos: _utxos, wallet: wallet); _updateWalletList(storage: storage, wallet: wallet); } @@ -493,8 +497,8 @@ class ExplorerBloc extends Bloc { for (int i = 0; i < unconfirmedVtts.length; i++) { ValueTransferInfo _vtt = unconfirmedVtts[i]; try { - ValueTransferInfo vtt = await explorer.getVtt(_vtt.txnHash); - if (_vtt.status != vtt.status) { + ValueTransferInfo? vtt = await explorer.getVtt(_vtt.txnHash); + if (vtt != null && _vtt.status != vtt.status) { await database.updateVtt(wallet.id, vtt); } } catch (e) { @@ -502,17 +506,16 @@ class ExplorerBloc extends Bloc { /// and the vtt has an unknown hash /// check the inputs for accounts in the wallet and remove the vtt - for (int i = 0; i < _vtt.inputs.length; i++) { - Account? account = wallet.accountByAddress(_vtt.inputs[i].address); + for (int i = 0; i < _vtt.inputAddresses.length; i++) { + Account? account = wallet.accountByAddress(_vtt.inputAddresses[i]); if (account != null) { await account.deleteVtt(_vtt); } } /// check the outputs for accounts in the wallet and remove the vtt - for (int i = 0; i < _vtt.outputs.length; i++) { - Account? account = - wallet.accountByAddress(_vtt.outputs[i].pkh.address); + for (int i = 0; i < _vtt.outputAddresses.length; i++) { + Account? account = wallet.accountByAddress(_vtt.outputAddresses[i]); if (account != null) { await account.deleteVtt(_vtt); } diff --git a/lib/bloc/transactions/value_transfer/vtt_create/vtt_create_bloc.dart b/lib/bloc/transactions/value_transfer/vtt_create/vtt_create_bloc.dart index c87f8925..14285e44 100644 --- a/lib/bloc/transactions/value_transfer/vtt_create/vtt_create_bloc.dart +++ b/lib/bloc/transactions/value_transfer/vtt_create/vtt_create_bloc.dart @@ -6,7 +6,7 @@ import 'package:my_wit_wallet/constants.dart'; import 'package:my_wit_wallet/util/allow_biometrics.dart'; import 'package:my_wit_wallet/util/filter_utxos.dart'; import 'package:my_wit_wallet/util/get_utxos_match_inputs.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:witnet/constants.dart'; import 'package:witnet/data_structures.dart'; import 'package:witnet/explorer.dart'; @@ -36,9 +36,10 @@ Future _sendTransaction(Transaction transaction) async { try { var resp = await Locator.instance.get().sendTransaction(transaction); - return resp['result']; + return resp['result'] != null ? true : false; } catch (e) { - print('Error sending transaction: $transaction $e'); + print( + 'Error sending transaction: ${transaction.toRawJson(asHex: true)} $e'); return false; } } @@ -483,7 +484,7 @@ class VTTCreateBloc extends Bloc { if (account.utxos.contains(currentUtxo)) { _inputs.add(InputUtxo( address: account.address, - input: currentUtxo.toInput(), + inputUtxo: currentUtxo.toInput().outputPointer.toString(), value: currentUtxo.value)); } }); @@ -493,7 +494,7 @@ class VTTCreateBloc extends Bloc { if (account.utxos.contains(currentUtxo)) { _inputs.add(InputUtxo( address: account.address, - input: currentUtxo.toInput(), + inputUtxo: currentUtxo.toInput().outputPointer.toString(), value: currentUtxo.value)); } }); @@ -502,7 +503,7 @@ class VTTCreateBloc extends Bloc { currentWallet.masterAccount != null) { _inputs.add(InputUtxo( address: currentWallet.masterAccount!.address, - input: currentUtxo.toInput(), + inputUtxo: currentUtxo.toInput().outputPointer.toString(), value: currentUtxo.value)); } } @@ -538,19 +539,30 @@ class VTTCreateBloc extends Bloc { bool transactionAccepted = await _sendTransaction(Transaction(valueTransfer: event.transaction)); if (transactionAccepted) { - /// add pending transaction + /// Adds pending transaction List _inputUtxoList = _buildInputUtxoList(); ValueTransferInfo vti = ValueTransferInfo( - blockHash: '', + block: '0', + confirmed: false, + reverted: false, + inputsMerged: [], + timelocks: outputs.map((e) => e.timeLock.toInt()).toList(), fee: feeNanoWit, - inputs: _inputUtxoList, + inputAddresses: _inputUtxoList.map((e) => e.address).toList(), + outputAddresses: outputs.map((e) => e.pkh.address).toList(), + inputUtxos: _inputUtxoList, outputs: outputs, + outputValues: outputs.map((e) => e.value.toInt()).toList(), priority: 1, - status: 'pending', - txnEpoch: -1, - txnHash: event.transaction.transactionID, - txnTime: DateTime.now().millisecondsSinceEpoch, - type: 'ValueTransfer', + status: TxStatusLabel.pending, + value: outputs[0].value.toInt(), + epoch: -1, + utxos: [], + utxosMerged: [], + trueOutputAddresses: [], + changeOutputAddresses: [], + hash: event.transaction.transactionID, + timestamp: DateTime.now().millisecondsSinceEpoch, weight: event.transaction.weight); /// add pending tx to database diff --git a/lib/constants.dart b/lib/constants.dart index e9d27c26..d67ec8f4 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -134,6 +134,8 @@ const Map SUPPORTED_LOCALES = { "en": const Locale("en"), // "es": const Locale("es"), }; +const int DB_VERSION = 3; +const int DB_VERSION_TO_MIGRATE = 3; const String INSUFFICIENT_FUNDS_ERROR = "Insufficient funds"; const String APP_TITLE = "myWitWallet"; const String WINDOWS_FILE_NAME = "myWitWallet-windows.zip"; diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a3faccaa..9b9f93ea 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -281,5 +281,12 @@ "updateError": "There was an issue with the update. Please try again.", "errorTryAgain": "Error. Try Again.", "insufficientFunds": "Insufficient funds", - "insufficientUtxosAvailable": "Wait untill the pending transactions are confirmed or try creating a transaction with a smaller amount." + "insufficientUtxosAvailable": "Wait untill the pending transactions are confirmed or try creating a transaction with a smaller amount.", + "dataRequestTxn": "Data Request", + "valueTransferTxn": "Value Transfer", + "mintTxn": "Mint", + "confirmed": "Confirmed", + "mined": "Mined", + "pending": "Pending", + "reverted": "Reverted" } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 11205eb4..17efb094 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -275,5 +275,12 @@ "updateError": "Hubo un problema con la actualización. Por favor, inténtalo de nuevo.", "errorTryAgain": "Error. Inténtalo de nuevo.", "insufficientFunds": "Fondos insuficientes", - "insufficientUtxosAvailable": "Espera a la confirmación de las transacciones pendientes o crea una transacción con una cantidad más pequeña." + "insufficientUtxosAvailable": "Espera a la confirmación de las transacciones pendientes o crea una transacción con una cantidad más pequeña.", + "dataRequestTxn": "Data Request", + "valueTransferTxn": "Value Transfer", + "mintTxn": "Mint", + "confirmed": "Confirmada", + "mined": "Minada", + "pending": "Pendiente", + "reverted": "Revertida" } \ No newline at end of file diff --git a/lib/screens/dashboard/bloc/dashboard_bloc.dart b/lib/screens/dashboard/bloc/dashboard_bloc.dart index d790c285..0f1dffbd 100644 --- a/lib/screens/dashboard/bloc/dashboard_bloc.dart +++ b/lib/screens/dashboard/bloc/dashboard_bloc.dart @@ -17,7 +17,7 @@ class DashboardBloc extends Bloc { DashboardState( currentWalletId: defaultWallet.id, currentAddress: defaultAccount.address, - currentVttId: defaulVtt.txnHash, + currentVttId: defaulVtt.hash, status: DashboardStatus.Ready), ) { on(_dashboardLoadEvent); @@ -29,7 +29,7 @@ class DashboardBloc extends Bloc { get initialState => DashboardState( currentWalletId: defaultWallet.id, currentAddress: defaultAccount.address, - currentVttId: defaulVtt.txnHash, + currentVttId: defaulVtt.hash, status: DashboardStatus.Ready); Future _dashboardLoadEvent( @@ -39,7 +39,7 @@ class DashboardBloc extends Bloc { emit(DashboardState( currentWalletId: event.currentWalletId ?? defaultWallet.id, currentAddress: event.currentAddress ?? defaultAccount.address, - currentVttId: event.currentVttId ?? defaulVtt.txnHash, + currentVttId: event.currentVttId ?? defaulVtt.hash, status: DashboardStatus.Ready)); } @@ -49,7 +49,7 @@ class DashboardBloc extends Bloc { emit(DashboardState( currentWalletId: event.currentWalletId ?? defaultWallet.id, currentAddress: event.currentAddress ?? defaultAccount.address, - currentVttId: event.currentVttId ?? defaulVtt.txnHash, + currentVttId: event.currentVttId ?? defaulVtt.hash, status: DashboardStatus.Ready)); } @@ -63,7 +63,7 @@ class DashboardBloc extends Bloc { emit(DashboardState( currentWalletId: event.currentWallet?.id ?? defaultWallet.id, currentAddress: event.currentAddress ?? defaultAccount.address, - currentVttId: event.currentVttId ?? defaulVtt.txnHash, + currentVttId: event.currentVttId ?? defaulVtt.hash, status: DashboardStatus.Ready)); } @@ -72,7 +72,7 @@ class DashboardBloc extends Bloc { emit(DashboardState( currentWalletId: event.currentWalletId ?? defaultWallet.id, currentAddress: event.currentAddress ?? defaultAccount.address, - currentVttId: event.currentVttId ?? defaulVtt.txnHash, + currentVttId: event.currentVttId ?? defaulVtt.hash, status: DashboardStatus.Ready)); } diff --git a/lib/screens/dashboard/view/transactions_view.dart b/lib/screens/dashboard/view/transactions_view.dart index c1059111..c18b679e 100644 --- a/lib/screens/dashboard/view/transactions_view.dart +++ b/lib/screens/dashboard/view/transactions_view.dart @@ -5,7 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:my_wit_wallet/bloc/explorer/explorer_bloc.dart'; import 'package:my_wit_wallet/screens/dashboard/view/dashboard_screen.dart'; import 'package:my_wit_wallet/theme/extended_theme.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/util/storage/database/wallet.dart'; import 'package:my_wit_wallet/widgets/transactions_list.dart'; import 'package:number_paginator/number_paginator.dart'; diff --git a/lib/shared/api_database.dart b/lib/shared/api_database.dart index b49024bd..a4016db0 100644 --- a/lib/shared/api_database.dart +++ b/lib/shared/api_database.dart @@ -11,7 +11,7 @@ import 'package:my_wit_wallet/util/storage/path_provider_interface.dart'; import 'package:my_wit_wallet/util/storage/database/account.dart'; import 'package:my_wit_wallet/util/storage/database/wallet_storage.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'locator.dart'; class DatabaseException { @@ -371,7 +371,7 @@ class ApiDatabase { } Future addOrUpdateVttInDB(ValueTransferInfo vtt) async { - if (await getVtt(vtt.txnHash) == null) { + if (await getVtt(vtt.hash) == null) { await addVtt(vtt); } else { await updateVtt(walletStorage.currentWallet.id, vtt); diff --git a/lib/util/filter_utxos.dart b/lib/util/filter_utxos.dart index 674f4b49..437df9a9 100644 --- a/lib/util/filter_utxos.dart +++ b/lib/util/filter_utxos.dart @@ -1,22 +1,21 @@ import 'package:witnet/data_structures.dart'; import 'package:witnet/explorer.dart'; -import 'package:witnet/schema.dart'; List filterUsedUtxos( {required List utxoList, required List pendingVtts}) { List filteredUtxos = []; - List outputPointers = []; + List outputPointers = []; for (int i = 0; i < pendingVtts.length; i++) { - pendingVtts[i].inputs.forEach((InputUtxo input) { - outputPointers.add(input.input.outputPointer); + pendingVtts[i].inputUtxos.forEach((InputUtxo input) { + outputPointers.add(input.inputUtxo); }); } for (int i = 0; i < utxoList.length; i++) { Utxo currentUtxo = utxoList[i]; - if (!outputPointers.contains(currentUtxo.outputPointer)) { + if (!outputPointers.contains(currentUtxo.outputPointer.toString())) { filteredUtxos.add(currentUtxo); } } diff --git a/lib/util/get_utxos_match_inputs.dart b/lib/util/get_utxos_match_inputs.dart index 36ea7b0f..3d871223 100644 --- a/lib/util/get_utxos_match_inputs.dart +++ b/lib/util/get_utxos_match_inputs.dart @@ -1,19 +1,18 @@ import 'package:witnet/data_structures.dart'; import 'package:witnet/explorer.dart'; -import 'package:witnet/schema.dart'; List getUtxosMatchInputs( {required List utxoList, required List inputs}) { List matchingUtxos = []; - List outputPointers = []; - + //TODO: check this works with new api + List outputPointers = []; inputs.forEach((InputUtxo input) { - outputPointers.add(input.input.outputPointer); + outputPointers.add(input.inputUtxo); }); for (int i = 0; i < utxoList.length; i++) { Utxo utxo = utxoList[i]; - if (outputPointers.contains(utxo.outputPointer)) { + if (outputPointers.contains(utxo.outputPointer.toString())) { matchingUtxos.add(utxo); } } diff --git a/lib/util/storage/cache/file_manager_interface.dart b/lib/util/storage/cache/file_manager_interface.dart index f577cc9b..d8153420 100644 --- a/lib/util/storage/cache/file_manager_interface.dart +++ b/lib/util/storage/cache/file_manager_interface.dart @@ -43,7 +43,7 @@ class TransactionCache { } void addVtt(ValueTransferInfo vti) { - transactions[vti.txnHash] = vti; + transactions[vti.hash] = vti; } Future> getValue(String key) async { diff --git a/lib/util/storage/cache/transaction_cache.dart b/lib/util/storage/cache/transaction_cache.dart index f577cc9b..d8153420 100644 --- a/lib/util/storage/cache/transaction_cache.dart +++ b/lib/util/storage/cache/transaction_cache.dart @@ -43,7 +43,7 @@ class TransactionCache { } void addVtt(ValueTransferInfo vti) { - transactions[vti.txnHash] = vti; + transactions[vti.hash] = vti; } Future> getValue(String key) async { diff --git a/lib/util/storage/database/account.dart b/lib/util/storage/database/account.dart index e8117c1d..8d838569 100644 --- a/lib/util/storage/database/account.dart +++ b/lib/util/storage/database/account.dart @@ -2,7 +2,7 @@ import 'dart:core'; import 'package:my_wit_wallet/shared/api_database.dart'; import 'package:my_wit_wallet/shared/locator.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/util/storage/database/wallet.dart'; import 'package:my_wit_wallet/util/utxo_list_to_string.dart'; import 'package:quiver/core.dart'; @@ -162,18 +162,18 @@ class Account extends _Account { Future addVtt(ValueTransferInfo vtt) async { ApiDatabase database = Locator.instance(); - vtt.inputs.forEach((input) { + vtt.inputUtxos.forEach((input) { if (input.address == address) { - if (!vttHashes.contains(vtt.txnHash)) { - vttHashes.add(vtt.txnHash); + if (!vttHashes.contains(vtt.hash)) { + vttHashes.add(vtt.hash); vtts.add(vtt); } } }); vtt.outputs.forEach((output) { if (output.pkh.address == address) { - if (!vttHashes.contains(vtt.txnHash)) { - vttHashes.add(vtt.txnHash); + if (!vttHashes.contains(vtt.hash)) { + vttHashes.add(vtt.hash); vtts.add(vtt); } } @@ -184,8 +184,8 @@ class Account extends _Account { Future deleteVtt(ValueTransferInfo vtt) async { ApiDatabase database = Locator.instance(); try { - vttHashes.removeWhere((hash) => hash == vtt.txnHash); - vtts.removeWhere((_vtt) => _vtt.txnHash == vtt.txnHash); + vttHashes.removeWhere((hash) => hash == vtt.hash); + vtts.removeWhere((_vtt) => _vtt.hash == vtt.hash); await database.updateAccount(this); } catch (e) { return false; diff --git a/lib/util/storage/database/adapters/transaction_adapter.dart b/lib/util/storage/database/adapters/transaction_adapter.dart new file mode 100644 index 00000000..8154973d --- /dev/null +++ b/lib/util/storage/database/adapters/transaction_adapter.dart @@ -0,0 +1,421 @@ +import 'package:witnet/explorer.dart'; +import 'package:witnet/schema.dart'; + +class MintData { + final List outputs; + final int timestamp; + final int reward; + final int valueTransferCount; + final int dataRequestCount; + final int commitCount; + final int revealCount; + final int tallyCount; + + MintData({ + required this.outputs, + required this.timestamp, + required this.reward, + required this.valueTransferCount, + required this.dataRequestCount, + required this.commitCount, + required this.revealCount, + required this.tallyCount, + }); +} + +class VttData { + final List inputs; + final List inputAddresses; + final List outputs; + final List outputAddresses; + final int weight; + final int priority; + final bool confirmed; + final bool reverted; + + VttData( + {required this.inputs, + required this.inputAddresses, + required this.outputs, + required this.outputAddresses, + required this.weight, + required this.confirmed, + required this.reverted, + required this.priority}); +} + +class GeneralTransaction extends HashInfo { + MintData? mint; + VttData? vtt; + final int fee; + final int? epoch; + + GeneralTransaction( + {required blockHash, + required this.epoch, + required this.fee, + required hash, + required status, + required time, + required type, + this.mint, + this.vtt}) + : super( + txnHash: hash, + status: status, + type: type, + txnTime: time, + blockHash: blockHash); + + factory GeneralTransaction.fromMintEntry(MintEntry mintEntry) => + GeneralTransaction( + blockHash: mintEntry.blockHash, + epoch: mintEntry.epoch, + fee: mintEntry.fees, + hash: mintEntry.blockHash, + status: mintEntry.status, + time: mintEntry.timestamp, + type: mintEntry.type, + mint: MintData( + commitCount: mintEntry.commitCount, + outputs: mintEntry.outputs, + timestamp: mintEntry.timestamp, + reward: mintEntry.reward, + valueTransferCount: mintEntry.valueTransferCount, + dataRequestCount: mintEntry.dataRequestCount, + revealCount: mintEntry.revealCount, + tallyCount: mintEntry.tallyCount), + vtt: null); + factory GeneralTransaction.fromValueTransferInfo( + ValueTransferInfo valueTransferInfo) => + GeneralTransaction( + blockHash: valueTransferInfo.blockHash, + epoch: valueTransferInfo.epoch, + fee: valueTransferInfo.fee, + hash: valueTransferInfo.hash, + status: valueTransferInfo.status, + time: valueTransferInfo.timestamp, + type: valueTransferInfo.type, + mint: null, + vtt: VttData( + inputs: valueTransferInfo.inputUtxos, + inputAddresses: valueTransferInfo.inputAddresses, + confirmed: valueTransferInfo.confirmed, + reverted: valueTransferInfo.reverted, + outputs: valueTransferInfo.outputs, + outputAddresses: valueTransferInfo.outputAddresses, + weight: valueTransferInfo.weight, + priority: valueTransferInfo.priority)); + + ValueTransferInfo toValueTransferInfo() => ValueTransferInfo( + block: blockHash ?? + '0000000000000000000000000000000000000000000000000000000000000000', + fee: fee, + inputUtxos: vtt?.inputs ?? [], + outputs: vtt?.outputs ?? [], + priority: vtt?.priority ?? 0, + status: status, + epoch: epoch ?? 0, + hash: txnHash, + timestamp: txnTime, + weight: vtt?.weight ?? 0, + confirmed: vtt?.confirmed ?? false, + reverted: vtt?.reverted ?? false, + inputAddresses: vtt?.inputAddresses ?? [], + outputAddresses: vtt?.outputAddresses ?? [], + value: 0, + inputsMerged: [], + outputValues: [], + timelocks: [], + utxos: [], + utxosMerged: [], + trueOutputAddresses: [], + changeOutputAddresses: [], + trueValue: 0, + changeValue: 0, + ); +} + +class MintEntry { + MintEntry({ + required this.blockHash, + required this.fees, + required this.epoch, + // specific to mint entry + required this.outputs, + required this.timestamp, + required this.reward, + required this.valueTransferCount, + required this.dataRequestCount, + required this.commitCount, + required this.revealCount, + required this.tallyCount, + required this.status, + required this.type, + required this.confirmed, + required this.reverted, + }); + final String blockHash; + final List outputs; + final int timestamp; + final int epoch; + final int reward; + final int fees; + final int valueTransferCount; + final int dataRequestCount; + final int commitCount; + final int revealCount; + final int tallyCount; + final TxStatusLabel status; + final TransactionType type; + final bool confirmed; + final bool reverted; + + bool containsAddress(String address) { + bool response = false; + outputs.forEach((element) { + if (element.pkh.address == address) response = true; + }); + return response; + } + + Map jsonMap() => { + "block_hash": blockHash, + "outputs": List>.from( + outputs.map((x) => x.jsonMap(asHex: true))), + "timestamp": timestamp, + "epoch": epoch, + "reward": reward, + "fees": fees, + "vtt_count": valueTransferCount, + "drt_count": dataRequestCount, + "commit_count": commitCount, + "reveal_count": revealCount, + "tally_count": tallyCount, + 'confirmed': confirmed, + 'reverted': reverted, + "status": status.toString(), + "type": type.toString(), + }; + + factory MintEntry.fromJson(Map json) { + return MintEntry( + blockHash: json["block_hash"], + outputs: List.from( + json["outputs"].map((x) => ValueTransferOutput.fromJson(x))), + timestamp: json["timestamp"], + epoch: json["epoch"], + reward: json["reward"], + fees: json["fees"], + valueTransferCount: json["vtt_count"], + dataRequestCount: json["drt_count"], + commitCount: json["commit_count"], + revealCount: json["reveal_count"], + tallyCount: json["tally_count"], + confirmed: json['confirmed'] ?? false, + reverted: json['reverted'] ?? false, + status: TransactionStatus.fromJson(json).status, + type: TransactionType.mint, + ); + } + + factory MintEntry.fromBlockMintInfo( + BlockInfo blockInfo, BlockDetails blockDetails) => + MintEntry( + blockHash: blockDetails.mintInfo.blockHash, + outputs: blockDetails.mintInfo.outputs, + timestamp: blockInfo.timestamp, + epoch: blockInfo.epoch, + reward: blockInfo.reward, + fees: blockInfo.fees, + valueTransferCount: blockInfo.valueTransferCount, + dataRequestCount: blockInfo.dataRequestCount, + commitCount: blockInfo.commitCount, + revealCount: blockInfo.revealCount, + tallyCount: blockInfo.tallyCount, + status: TransactionStatus.fromJson({ + 'confirmed': blockDetails.confirmed, + 'reverted': blockDetails.reverted + }).status, + type: TransactionType.mint, + confirmed: blockDetails.confirmed, + reverted: blockDetails.reverted, + ); +} + +extension InputUtxoAdapter on InputUtxo { + static InputUtxo fromDBJson(Map json) => InputUtxo( + address: json["pkh"], + inputUtxo: json["output_pointer"], + value: json["value"]); + + static InputUtxo fromJson(Map json) { + bool dbJson = json["pkh"] != null; + if (dbJson) { + return fromDBJson(json); + } else { + return InputUtxo.fromJson(json); + } + } +} + +// TODO: it is not used, delete if not necessary +extension AddressBlocksAdapter on AddressBlocks { + static AddressBlocks fromDBJson(List data) { + return AddressBlocks( + address: data[0]['address'], + blocks: List.from( + data.map((blockInfo) => BlockInfo.fromJson(blockInfo))), + ); + } + + static AddressBlocks fromJson(List data) { + bool dbJson = data[0]['miner'] == null; + if (dbJson) { + return fromDBJson(data); + } else { + return AddressBlocks.fromJson(data); + } + } +} + +extension ValueTransferAdapter on ValueTransferInfo { + static ValueTransferInfo fromJson(Map data) { + bool dbJson = data["epoch"] == null; + if (dbJson) { + return fromDBJson(data); + } else { + return ValueTransferInfo.fromJson(data); + } + } + + static ValueTransferInfo fromDBJson(Map data) { + List outputAddresses = getOrDefault(data).outputAddresses; + List outputValues = getOrDefault(data).outputValues; + List outputs = []; + if (data['outputs'] != null) { + data['outputs'].forEach((element) { + Address address = Address.fromAddress(element['pkh']); + + outputs.add(ValueTransferOutput( + pkh: address.publicKeyHash!, + timeLock: element['time_lock'], + value: element['value'])); + }); + } else { + for (int i = 0; i < outputValues.length; i++) { + ValueTransferOutput vto = ValueTransferOutput( + value: outputValues[i], + pkh: Address.fromAddress(outputAddresses[i]).publicKeyHash!, + timeLock: 0, + ); + outputs.add(vto); + } + } + return ValueTransferInfo( + epoch: data["txn_epoch"], + timestamp: data["txn_time"], + hash: data["txn_hash"], + block: data["block_hash"], + inputUtxos: List.from( + data["inputs"].map((x) => InputUtxoAdapter.fromJson(x))), + fee: data["fee"], + priority: data["priority"], + weight: data["weight"], + status: TransactionStatus.fromJson(data).status, + outputs: outputs, + value: getOrDefault(data).value, + confirmed: getOrDefault(data).confirmed, + reverted: getOrDefault(data).reverted, + inputAddresses: getOrDefault(data).inputAddresses, + inputsMerged: getOrDefault(data).inputsMerged, + outputAddresses: getOrDefault(data).outputAddresses, + outputValues: getOrDefault(data).outputValues, + timelocks: getOrDefault(data).timelocks, + utxos: getOrDefault(data).utxos, + utxosMerged: getOrDefault(data).utxosMerged, + trueOutputAddresses: getOrDefault(data).trueOutputAddresses, + changeOutputAddresses: getOrDefault(data).outputAddresses, + trueValue: getOrDefault(data).trueValue, + changeValue: getOrDefault(data).changeValue); + } +} + +class NullableFields { + final int? value; + final bool confirmed; + final bool reverted; + final List inputAddresses; + final List inputsMerged; + final List outputAddresses; + final List outputValues; + final List timelocks; + final List utxos; + final List utxosMerged; + final List trueOutputAddresses; + final List changeOutputAddresses; + final int? trueValue; + final int? changeValue; + NullableFields( + {required this.changeOutputAddresses, + required this.changeValue, + required this.confirmed, + required this.inputAddresses, + required this.inputsMerged, + required this.outputAddresses, + required this.outputValues, + required this.reverted, + required this.timelocks, + required this.trueOutputAddresses, + required this.trueValue, + required this.utxos, + required this.utxosMerged, + required this.value}); +} + +NullableFields getOrDefault(Map data) { + return NullableFields( + value: data["value"] ?? null, + confirmed: data["confirmed"] ?? + TransactionStatus.fromJson(data).status == TxStatusLabel.confirmed, + reverted: data["reverted"] ?? + TransactionStatus.fromJson(data).status == TxStatusLabel.reverted, + inputAddresses: data["input_addresses"] != null + ? List.from(data["input_addresses"]) + : List.from(data["inputs"].map((input) { + return input['pkh']; + }).toList()), + inputsMerged: data["inputs_merged"] != null + ? List.from( + data["inputs_merged"].map((x) => InputMerged.fromJson(x))) + : [], + outputAddresses: data["output_addresses"] != null + ? List.from(data["output_addresses"]) + : List.from( + data["outputs"].map((output) => output['pkh']).toList()), + outputValues: data["output_values"] != null + ? List.from(data["output_values"]) + : List.from( + data["outputs"].map((output) => output['value']).toList()), + timelocks: data["timelocks"] != null + ? List.from(data["timelocks"]) + : List.from( + data["outputs"].map((output) => output['time_lock']).toList()), + utxos: data["utxos"] != null + ? List.from(data["utxos"] + .map((e) => TransactionUtxo.fromJson(Map.from(e)))) + : [], + utxosMerged: data["utxos_merged"] != null + ? List.from(data["utxos_merged"] + .map((e) => TransactionUtxo.fromJson(Map.from(e)))) + : [], + trueOutputAddresses: data["true_output_addresses"] != null + ? List.from(data["true_output_addresses"]) + : [], + changeOutputAddresses: data["change_output_addresses"] != null + ? List.from(data["change_output_addresses"]) + : [], + trueValue: data["true_value"], + changeValue: data["change_value"], + ); +} diff --git a/lib/util/storage/database/database_isolate.dart b/lib/util/storage/database/database_isolate.dart index 1738ccc1..e163fcaa 100644 --- a/lib/util/storage/database/database_isolate.dart +++ b/lib/util/storage/database/database_isolate.dart @@ -3,7 +3,7 @@ import 'dart:convert'; import 'dart:isolate'; import 'package:my_wit_wallet/util/storage/database/stats.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:witnet/explorer.dart'; import 'package:my_wit_wallet/util/storage/database/wallet.dart'; @@ -146,7 +146,7 @@ Future _addRecord( break; case 'vtt': value = - await dbService.add(ValueTransferInfo.fromDbJson(params['value'])); + await dbService.add(ValueTransferAdapter.fromJson(params['value'])); break; case 'account': value = await dbService.add(Account.fromJson(params['value'])); @@ -175,8 +175,8 @@ Future _deleteRecord( value = await dbService.delete(Wallet.fromJson(params['value'])); break; case 'vtt': - value = - await dbService.delete(ValueTransferInfo.fromDbJson(params['value'])); + value = await dbService + .delete(ValueTransferAdapter.fromJson(params['value'])); break; case 'account': value = await dbService.delete(Account.fromJson(params['value'])); @@ -211,8 +211,8 @@ Future _updateRecord( value = await dbService.update(MintEntry.fromJson(params['value'])); break; case 'vtt': - value = - await dbService.update(ValueTransferInfo.fromDbJson(params['value'])); + value = await dbService + .update(ValueTransferAdapter.fromJson(params['value'])); break; case 'account': value = await dbService.update(Account.fromJson(params['value'])); diff --git a/lib/util/storage/database/database_service.dart b/lib/util/storage/database/database_service.dart index 3c001fa0..09af2727 100644 --- a/lib/util/storage/database/database_service.dart +++ b/lib/util/storage/database/database_service.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:my_wit_wallet/util/storage/database/get_account_mints_map.dart'; import 'package:my_wit_wallet/util/storage/database/get_account_vtts_map.dart'; import 'package:my_wit_wallet/util/storage/database/stats.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:sembast/sembast_io.dart'; import 'package:sembast/sembast.dart'; import 'package:witnet/explorer.dart'; @@ -91,10 +91,13 @@ class DatabaseService { mode = DatabaseMode.create; } _dbService._database = await dbFactory.openDatabase( - _dbService._dbConfig!.path, - version: 2, - mode: mode, - ); + _dbService._dbConfig!.path, + version: DB_VERSION, + mode: mode, onVersionChanged: (db, oldVersion, newVersion) async { + if (newVersion == DB_VERSION_TO_MIGRATE) { + await migrateDB(db); + } + }); } Future add(dynamic item) async { @@ -145,13 +148,13 @@ class DatabaseService { await walletRepository.deleteWallet(item.id, _database); break; case ValueTransferInfo: - await vttRepository.deleteTransaction(item.txnHash, _database); + await vttRepository.deleteTransaction(item.hash, _database); break; case Account: await accountRepository.deleteAccount(item.address, _database); break; case MintEntry: - await mintRepository.deleteTransaction(item.txnHash, _database); + await mintRepository.deleteTransaction(item.hash, _database); break; case AccountStats: await statsRepository.deleteStats(item.address, _database); @@ -238,6 +241,17 @@ class DatabaseService { } } + Future migrateDB(db) async { + /// Get all Transactions + final List transactions = + await vttRepository.getAllTransactions(db); + + for (int i = 0; i < transactions.length; i++) { + ValueTransferInfo _vtt = transactions[i]; + await vttRepository.updateTransaction(_vtt, db); + } + } + Future loadWallets() async { /// Get all Wallets @@ -305,7 +319,7 @@ class DatabaseService { accountMap[account.address] = account; }); transactions.forEach((vtt) { - vttMap[vtt.txnHash] = vtt; + vttMap[vtt.hash] = vtt; }); mints.forEach((mint) { mintMap[mint.blockHash] = mint; diff --git a/lib/util/storage/database/get_account_mints_map.dart b/lib/util/storage/database/get_account_mints_map.dart index b72c5067..91ab2594 100644 --- a/lib/util/storage/database/get_account_mints_map.dart +++ b/lib/util/storage/database/get_account_mints_map.dart @@ -1,4 +1,4 @@ -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:witnet/schema.dart'; Map> getAccountMintsMap(List vttList) { diff --git a/lib/util/storage/database/get_account_vtts_map.dart b/lib/util/storage/database/get_account_vtts_map.dart index 0f1aae3a..8d722539 100644 --- a/lib/util/storage/database/get_account_vtts_map.dart +++ b/lib/util/storage/database/get_account_vtts_map.dart @@ -1,26 +1,25 @@ import 'package:witnet/explorer.dart'; -import 'package:witnet/schema.dart'; Map> getAccountVttsMap( List vttList) { Map> accountVttMap = {}; - // Creates map to get vtts by account address for (int i = 0; i < vttList.length; i++) { - List inputs = vttList[i].inputs; - List outputs = vttList[i].outputs; - inputs.forEach((input) { - if (accountVttMap[input.address] != null) { - accountVttMap[input.address]!.add(vttList[i]); + List inputs = vttList[i].inputUtxos.map((e) => e.address).toList(); + List outputs = + vttList[i].outputs.map((e) => e.pkh.address).toList(); + inputs.forEach((inputAddress) { + if (accountVttMap[inputAddress] != null) { + accountVttMap[inputAddress]!.add(vttList[i]); } else { - accountVttMap[input.address] = [vttList[i]]; + accountVttMap[inputAddress] = [vttList[i]]; } }); - outputs.forEach((output) { - if (accountVttMap[output.pkh.address] != null) { - accountVttMap[output.pkh.address]!.add(vttList[i]); + outputs.forEach((outputAddress) { + if (accountVttMap[outputAddress] != null) { + accountVttMap[outputAddress]!.add(vttList[i]); } else { - accountVttMap[output.pkh.address] = [vttList[i]]; + accountVttMap[outputAddress] = [vttList[i]]; } }); } diff --git a/lib/util/storage/database/transaction_adapter.dart b/lib/util/storage/database/transaction_adapter.dart deleted file mode 100644 index d9ec6d7c..00000000 --- a/lib/util/storage/database/transaction_adapter.dart +++ /dev/null @@ -1,207 +0,0 @@ -import 'package:witnet/explorer.dart'; -import 'package:witnet/schema.dart'; - -enum TransactionType { mint, value_transfer } - -class MintData { - final List outputs; - final int timestamp; - final int reward; - final int valueTransferCount; - final int dataRequestCount; - final int commitCount; - final int revealCount; - final int tallyCount; - - MintData({ - required this.outputs, - required this.timestamp, - required this.reward, - required this.valueTransferCount, - required this.dataRequestCount, - required this.commitCount, - required this.revealCount, - required this.tallyCount, - }); -} - -class VttData { - final List inputs; - final List outputs; - final int weight; - final int priority; - - VttData( - {required this.inputs, - required this.outputs, - required this.weight, - required this.priority}); -} - -class GeneralTransaction extends HashInfo { - MintData? mint; - VttData? vtt; - final TransactionType txnType; - final int fee; - final int? epoch; - - GeneralTransaction( - {required blockHash, - required this.epoch, - required this.fee, - required hash, - required status, - required time, - required this.txnType, - required type, - this.mint, - this.vtt}) - : super( - txnHash: hash, - status: status, - type: type, - txnTime: time, - blockHash: blockHash); - - factory GeneralTransaction.fromMintEntry(MintEntry mintEntry) => - GeneralTransaction( - blockHash: mintEntry.blockHash, - epoch: mintEntry.epoch, - fee: mintEntry.fees, - hash: mintEntry.blockHash, - status: mintEntry.status, - time: mintEntry.timestamp, - type: mintEntry.type, - txnType: TransactionType.mint, - mint: MintData( - commitCount: mintEntry.commitCount, - outputs: mintEntry.outputs, - timestamp: mintEntry.timestamp, - reward: mintEntry.reward, - valueTransferCount: mintEntry.valueTransferCount, - dataRequestCount: mintEntry.dataRequestCount, - revealCount: mintEntry.revealCount, - tallyCount: mintEntry.tallyCount), - vtt: null); - factory GeneralTransaction.fromValueTransferInfo( - ValueTransferInfo valueTransferInfo) => - GeneralTransaction( - blockHash: valueTransferInfo.blockHash, - epoch: valueTransferInfo.txnEpoch, - fee: valueTransferInfo.fee, - hash: valueTransferInfo.txnHash, - status: valueTransferInfo.status, - time: valueTransferInfo.txnTime, - type: valueTransferInfo.type, - txnType: TransactionType.value_transfer, - mint: null, - vtt: VttData( - inputs: valueTransferInfo.inputs, - outputs: valueTransferInfo.outputs, - weight: valueTransferInfo.weight, - priority: valueTransferInfo.priority)); - - ValueTransferInfo toValueTransferInfo() => ValueTransferInfo( - blockHash: blockHash, - fee: fee, - inputs: vtt?.inputs ?? [], - outputs: vtt?.outputs ?? [], - priority: vtt?.priority ?? 0, - status: status, - txnEpoch: epoch, - txnHash: txnHash, - txnTime: txnTime, - type: type, - weight: vtt?.weight ?? 0); -} - -class MintEntry { - MintEntry({ - required this.blockHash, - required this.fees, - required this.epoch, - // specific to mint entry - required this.outputs, - required this.timestamp, - required this.reward, - required this.valueTransferCount, - required this.dataRequestCount, - required this.commitCount, - required this.revealCount, - required this.tallyCount, - required this.status, - required this.type, - }); - final String blockHash; - final List outputs; - final int timestamp; - final int epoch; - final int reward; - final int fees; - final int valueTransferCount; - final int dataRequestCount; - final int commitCount; - final int revealCount; - final int tallyCount; - final String status; - final String type; - - bool containsAddress(String address) { - bool response = false; - outputs.forEach((element) { - if (element.pkh.address == address) response = true; - }); - return response; - } - - Map jsonMap() => { - "block_hash": blockHash, - "outputs": List>.from( - outputs.map((x) => x.jsonMap(asHex: true))), - "timestamp": timestamp, - "epoch": epoch, - "reward": reward, - "fees": fees, - "vtt_count": valueTransferCount, - "drt_count": dataRequestCount, - "commit_count": commitCount, - "reveal_count": revealCount, - "tally_count": tallyCount, - "status": status, - "type": type, - }; - - factory MintEntry.fromJson(Map json) => MintEntry( - blockHash: json["block_hash"], - outputs: List.from( - json["outputs"].map((x) => ValueTransferOutput.fromJson(x))), - timestamp: json["timestamp"], - epoch: json["epoch"], - reward: json["reward"], - fees: json["fees"], - valueTransferCount: json["vtt_count"], - dataRequestCount: json["drt_count"], - commitCount: json["commit_count"], - revealCount: json["reveal_count"], - tallyCount: json["tally_count"], - status: json["status"], - type: json["type"], - ); - - factory MintEntry.fromBlockMintInfo(BlockInfo blockInfo, MintInfo mintInfo) => - MintEntry( - blockHash: mintInfo.blockHash, - outputs: mintInfo.outputs, - timestamp: blockInfo.timestamp, - epoch: blockInfo.epoch, - reward: blockInfo.reward, - fees: blockInfo.fees, - valueTransferCount: blockInfo.valueTransferCount, - dataRequestCount: blockInfo.dataRequestCount, - commitCount: blockInfo.commitCount, - revealCount: blockInfo.revealCount, - tallyCount: blockInfo.tallyCount, - status: mintInfo.status, - type: mintInfo.type, - ); -} diff --git a/lib/util/storage/database/transaction_repository.dart b/lib/util/storage/database/transaction_repository.dart index a8472dbe..c79864ff 100644 --- a/lib/util/storage/database/transaction_repository.dart +++ b/lib/util/storage/database/transaction_repository.dart @@ -1,4 +1,4 @@ -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:sembast/sembast.dart'; import 'package:witnet/explorer.dart'; import 'package:witnet/schema.dart'; @@ -42,11 +42,12 @@ class VttRepository extends _TransactionRepository { final snapshots = await _store.find(databaseClient); try { List transactions = snapshots - .map((snapshot) => ValueTransferInfo.fromDbJson( + .map((snapshot) => ValueTransferAdapter.fromJson( snapshot.value as Map)) .toList(growable: false); return transactions; } catch (e) { + print('Error getting all transactions $e'); return []; } } @@ -57,7 +58,7 @@ class VttRepository extends _TransactionRepository { try { assert(transaction.runtimeType == ValueTransferInfo); await _store - .record(transaction.txnHash) + .record(transaction.hash) .add(databaseClient, transaction.jsonMap()); return true; } catch (e) { @@ -71,11 +72,11 @@ class VttRepository extends _TransactionRepository { try { assert(transaction.runtimeType == ValueTransferInfo); await _store - .record(transaction.txnHash) + .record(transaction.hash) .update(databaseClient, transaction.jsonMap()); return true; } catch (e) { - print(e); + print('Error updating transaction $e'); return false; } } @@ -87,7 +88,7 @@ class VttRepository extends _TransactionRepository { await _store.record(txHash).get(databaseClient); ValueTransferInfo valueTransferInfo = - ValueTransferInfo.fromDbJson(valueTransferInfoDbJson); + ValueTransferAdapter.fromJson(valueTransferInfoDbJson); return valueTransferInfo; } catch (e) { @@ -184,6 +185,7 @@ class MintRepository extends _TransactionRepository { .toList(growable: false); return transactions; } catch (e) { + print('Error getting mint transactions $e'); return []; } } diff --git a/lib/util/storage/database/wallet.dart b/lib/util/storage/database/wallet.dart index 045ee310..4090af5f 100644 --- a/lib/util/storage/database/wallet.dart +++ b/lib/util/storage/database/wallet.dart @@ -7,7 +7,7 @@ import 'package:my_wit_wallet/screens/dashboard/view/dashboard_screen.dart'; import 'package:my_wit_wallet/shared/api_database.dart'; import 'package:my_wit_wallet/shared/locator.dart'; import 'package:my_wit_wallet/util/storage/database/stats.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/util/storage/database/wallet_storage.dart'; import 'package:witnet/constants.dart'; import 'package:witnet/crypto.dart'; @@ -47,8 +47,16 @@ class Wallet { required this.externalAccounts, required this.internalAccounts, this.lastSynced = -1, - this.id = "00000000", - }); + }) { + this.id = '00000000'; + this.externalAccounts.forEach((key, Account account) { + account.balance; + }); + + this.internalAccounts.forEach((key, Account account) { + account.balance; + }); + } final WalletType walletType; late String id; @@ -92,16 +100,16 @@ class Wallet { Future deleteVtt(Wallet wallet, ValueTransferInfo vtt) async { /// check the inputs for accounts in the wallet and remove the vtt - for (int i = 0; i < vtt.inputs.length; i++) { - Account? account = wallet.accountByAddress(vtt.inputs[i].address); + for (int i = 0; i < vtt.inputAddresses.length; i++) { + Account? account = wallet.accountByAddress(vtt.inputAddresses[i]); if (account != null) { await account.deleteVtt(vtt); } } /// check the outputs for accounts in the wallet and remove the vtt - for (int i = 0; i < vtt.outputs.length; i++) { - Account? account = wallet.accountByAddress(vtt.outputs[i].pkh.address); + for (int i = 0; i < vtt.outputAddresses.length; i++) { + Account? account = wallet.accountByAddress(vtt.outputAddresses[i]); if (account != null) { await account.deleteVtt(vtt); } @@ -164,7 +172,7 @@ class Wallet { List unconfirmedTransactions() { List unconfirmedVtts = []; allTransactions().forEach((vtt) { - if (vtt.status != "confirmed") { + if (vtt.status != TxStatusLabel.confirmed) { unconfirmedVtts.add(vtt); } }); @@ -174,7 +182,7 @@ class Wallet { List pendingTransactions() { List pendingVtts = []; allTransactions().forEach((vtt) { - if (vtt.status == "pending") { + if (vtt.status == TxStatusLabel.pending) { pendingVtts.add(vtt); } }); @@ -185,21 +193,20 @@ class Wallet { Map _vttMap = {}; externalAccounts.forEach((key, account) { account.vtts.forEach((vtt) { - if (vtt.status != 'unknown hash') _vttMap[vtt.txnHash] = vtt; + if (vtt.status != TxStatusLabel.reverted) _vttMap[vtt.hash] = vtt; }); }); internalAccounts.forEach((key, account) { account.vtts.forEach((vtt) { - if (vtt.status != 'unknown hash') _vttMap[vtt.txnHash] = vtt; + if (vtt.status != TxStatusLabel.reverted) _vttMap[vtt.hash] = vtt; }); }); if (walletType == WalletType.single) { masterAccount!.vtts.forEach((vtt) { - if (vtt.status != 'unknown hash') _vttMap[vtt.txnHash] = vtt; + if (vtt.status != TxStatusLabel.reverted) _vttMap[vtt.hash] = vtt; }); } - return _vttMap.values.toList() ..sort((t1, t2) => t2.txnTime.compareTo(t1.txnTime)); } @@ -512,7 +519,6 @@ class Wallet { masterAccount: null, masterAccountStats: null, ); - _wallet.id = _id; return _wallet; } diff --git a/lib/util/storage/database/wallet_storage.dart b/lib/util/storage/database/wallet_storage.dart index 71fd0738..1cbb0b78 100644 --- a/lib/util/storage/database/wallet_storage.dart +++ b/lib/util/storage/database/wallet_storage.dart @@ -1,5 +1,5 @@ import 'package:my_wit_wallet/util/storage/database/stats.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/util/storage/database/wallet.dart'; import 'package:witnet/explorer.dart'; @@ -21,18 +21,31 @@ final defaultWallet = Wallet( final defaultAccount = Account(address: '', walletName: '', path: ''); final defaulVtt = ValueTransferInfo( - blockHash: - '0000000000000000000000000000000000000000000000000000000000000000', - fee: 0, - inputs: [], - outputs: [], - priority: 0, - status: 'pending', - txnEpoch: 0, - txnHash: '0000000000000000000000000000000000000000000000000000000000000000', - txnTime: 0, - type: 'valueTransfer', - weight: 0); + confirmed: false, + reverted: false, + block: '0', + epoch: 0, + timestamp: 0, + value: 0, + hash: '0000000000000000000000000000000000000000000000000000000000000000', + fee: 0, + priority: 0, + weight: 0, + inputAddresses: [], + outputAddresses: [], + inputUtxos: [], + inputsMerged: [], + outputValues: [], + timelocks: [], + utxos: [], + utxosMerged: [], + trueOutputAddresses: [], + changeOutputAddresses: [], + status: TxStatusLabel.pending, + trueValue: 0, + changeValue: 0, + outputs: [], +); /// DbWallet formats the wallet for the database class WalletStorage { diff --git a/lib/widgets/speed_up_tx.dart b/lib/widgets/speed_up_tx.dart index c2f46ab0..9e83988d 100644 --- a/lib/widgets/speed_up_tx.dart +++ b/lib/widgets/speed_up_tx.dart @@ -5,7 +5,7 @@ import 'package:my_wit_wallet/screens/dashboard/view/dashboard_screen.dart'; import 'package:my_wit_wallet/shared/api_database.dart'; import 'package:my_wit_wallet/shared/locator.dart'; import 'package:my_wit_wallet/util/get_localization.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/widgets/PaddedButton.dart'; import 'package:my_wit_wallet/widgets/closable_view.dart'; import 'package:my_wit_wallet/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/02_select_miner_fee.dart'; diff --git a/lib/widgets/speedup_btn.dart b/lib/widgets/speedup_btn.dart index a64d5c52..204ca65b 100644 --- a/lib/widgets/speedup_btn.dart +++ b/lib/widgets/speedup_btn.dart @@ -2,7 +2,7 @@ import 'package:my_wit_wallet/shared/api_database.dart'; import 'package:my_wit_wallet/shared/locator.dart'; import 'package:flutter/material.dart'; import 'package:my_wit_wallet/util/get_localization.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/util/storage/database/wallet.dart'; import 'package:my_wit_wallet/widgets/PaddedButton.dart'; diff --git a/lib/widgets/transaction_details.dart b/lib/widgets/transaction_details.dart index 26f1259b..e201d21d 100644 --- a/lib/widgets/transaction_details.dart +++ b/lib/widgets/transaction_details.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:my_wit_wallet/util/storage/database/account.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/util/storage/database/wallet.dart'; import 'package:my_wit_wallet/util/transactions_list/get_transaction_label.dart'; import 'package:my_wit_wallet/widgets/closable_view.dart'; @@ -11,7 +11,6 @@ import 'package:my_wit_wallet/util/get_localization.dart'; import 'package:my_wit_wallet/constants.dart'; import 'package:my_wit_wallet/theme/colors.dart'; import 'package:my_wit_wallet/theme/extended_theme.dart'; -import 'package:my_wit_wallet/util/extensions/string_extensions.dart'; import 'package:my_wit_wallet/util/extensions/int_extensions.dart'; import 'package:my_wit_wallet/util/extensions/num_extensions.dart'; import 'package:my_wit_wallet/widgets/info_element.dart'; @@ -49,20 +48,47 @@ class TransactionDetails extends StatelessWidget { : null; } + String transactionType(TransactionType status) { + switch (status) { + case TransactionType.value_transfer: + return localization.valueTransferTxn; + case TransactionType.mint: + return localization.mintTxn; + case TransactionType.data_request: + return localization.dataRequestTxn; + } + } + + String transactionStatus(TxStatusLabel status) { + switch (status) { + case TxStatusLabel.confirmed: + return localization.confirmed; + case TxStatusLabel.mined: + return localization.mined; + case TxStatusLabel.pending: + return localization.pending; + case TxStatusLabel.reverted: + return localization.reverted; + case TxStatusLabel.unknown: + return 'Loading...'; + } + } + Widget _buildOutput( ThemeData theme, ValueTransferOutput output, bool isLastOutput) { final extendedTheme = theme.extension()!; Widget timelock = SizedBox(height: 0); - if (output.timeLock != 0) { - timelock = Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Text(output.timeLock.toInt().formatDate(), - style: theme.textTheme.bodySmall) - ])); - } + //TODO(#505): Support timelocks + // if (output.timeLock != 0) { + // timelock = Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.end, + // mainAxisAlignment: MainAxisAlignment.end, + // children: [ + // Text(output.timeLock.toInt().formatDate(), + // style: theme.textTheme.bodySmall) + // ])); + // } return Container( padding: EdgeInsets.only(top: 16, bottom: 16), decoration: BoxDecoration( @@ -124,8 +150,8 @@ class TransactionDetails extends StatelessWidget { )); } - bool _isPendingTransaction(String status) { - return status.toLowerCase() == "pending"; + bool _isPendingTransaction(TxStatusLabel status) { + return status == TxStatusLabel.pending; } Widget buildSpeedUpBtn() { @@ -137,12 +163,12 @@ class TransactionDetails extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); String label = ''; - if (transaction.txnType == TransactionType.value_transfer) { + if (transaction.type == TransactionType.value_transfer) { label = getTransactionLabel(externalAddresses, internalAddresses, transaction.vtt!.inputs, singleAddressAccount, context); } List outputs = - transaction.txnType == TransactionType.value_transfer + transaction.type == TransactionType.value_transfer ? transaction.vtt!.outputs : transaction.mint!.outputs; return ClosableView(closeSetting: goToList, children: [ @@ -153,7 +179,7 @@ class TransactionDetails extends StatelessWidget { SizedBox(height: 24), InfoElement( label: localization.status, - text: transaction.status.capitalize(), + text: transactionStatus(transaction.status), color: theme.textTheme.labelMedium?.color), InfoElement( label: localization.transactionId, @@ -166,10 +192,9 @@ class TransactionDetails extends StatelessWidget { ? '_' : transaction.epoch.toString()), InfoElement( - label: localization.type, - text: transaction.type.split('_').join(' ').toTitleCase()), + label: localization.type, text: transactionType(transaction.type)), InfoElement( - label: transaction.txnType == TransactionType.value_transfer + label: transaction.type == TransactionType.value_transfer ? localization.feesPayed : localization.feesCollected, text: @@ -179,7 +204,7 @@ class TransactionDetails extends StatelessWidget { text: _isPendingTransaction(transaction.status) ? '_' : transaction.txnTime.formatDate()), - transaction.txnType == TransactionType.value_transfer + transaction.type == TransactionType.value_transfer ? Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( localization.inputs, @@ -217,7 +242,7 @@ class TransactionDetails extends StatelessWidget { ), ]), SizedBox(height: 8), - transaction.status == 'pending' && label == localization.to + transaction.status == TxStatusLabel.pending && label == localization.to ? buildSpeedUpBtn() : Container(), ]); diff --git a/lib/widgets/transaction_item.dart b/lib/widgets/transaction_item.dart index 635b8119..549f3f7d 100644 --- a/lib/widgets/transaction_item.dart +++ b/lib/widgets/transaction_item.dart @@ -7,13 +7,14 @@ import 'package:my_wit_wallet/util/extensions/string_extensions.dart'; import 'package:my_wit_wallet/util/extensions/num_extensions.dart'; import 'package:flutter/material.dart'; import 'package:my_wit_wallet/util/storage/database/account.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/util/storage/database/wallet.dart'; import 'package:my_wit_wallet/util/transactions_list/get_transaction_address.dart'; import 'package:my_wit_wallet/util/transactions_list/get_transaction_label.dart'; import 'package:my_wit_wallet/theme/colors.dart'; import 'package:my_wit_wallet/theme/extended_theme.dart'; import 'package:my_wit_wallet/util/extensions/int_extensions.dart'; +import 'package:witnet/explorer.dart'; typedef void GeneralTransactionCallback(GeneralTransaction? value); @@ -65,7 +66,7 @@ class TransactionsItemState extends State { int receiveValue(GeneralTransaction vti) { int nanoWitvalue = 0; - if (vti.txnType == TransactionType.value_transfer) { + if (vti.type == TransactionType.value_transfer) { vti.vtt!.outputs.forEach((element) { if ((externalAddresses.contains(element.pkh.address) || internalAddresses.contains(element.pkh.address))) { @@ -91,15 +92,15 @@ class TransactionsItemState extends State { } int sendValue(GeneralTransaction vti) { - if (vti.txnType == TransactionType.value_transfer) { - bool isInternalTx = - externalAddresses.contains(vti.vtt!.outputs[0].pkh.address) || - internalAddresses.contains(vti.vtt!.outputs[0].pkh.address) || - singleAddressAccount?.address == vti.vtt!.outputs[0].pkh.address; - return isInternalTx ? vti.fee : vti.vtt!.outputs[0].value.toInt(); - } else { + if (vti.type != TransactionType.value_transfer || + vti.vtt!.outputs.length <= 0) { return 0; } + bool isInternalTx = + externalAddresses.contains(vti.vtt!.outputs[0].pkh.address) || + internalAddresses.contains(vti.vtt!.outputs[0].pkh.address) || + singleAddressAccount?.address == vti.vtt!.outputs[0].pkh.address; + return isInternalTx ? vti.fee : vti.vtt!.outputs[0].value.toInt(); } Widget buildTransactionValue(label, transaction) { @@ -129,15 +130,15 @@ class TransactionsItemState extends State { } Widget buildTransactionStatus(ThemeData theme) { - String transactionStatus = widget.transaction.status; - String localizedtxnStatus = localization.txnStatus(transactionStatus); + TxStatusLabel transactionStatus = widget.transaction.status; + String localizedtxnStatus = localization.txnStatus(transactionStatus.name); String txnTime = widget.transaction.txnTime.formatDuration(context); List pendingStatus = []; String transacionStatusCopy = txnTime; - if (transactionStatus != "confirmed") { + if (transactionStatus != TxStatusLabel.confirmed) { transacionStatusCopy = "$localizedtxnStatus $txnTime"; - if (transactionStatus == "pending") { + if (transactionStatus == TxStatusLabel.pending) { pendingStatus = [ Icon(FontAwesomeIcons.clock, size: 10, color: theme.textTheme.bodySmall!.color), @@ -165,9 +166,9 @@ class TransactionsItemState extends State { final extendedTheme = theme.extension()!; String label; String address; - TransactionType txnType = widget.transaction.txnType; + TransactionType type = widget.transaction.type; - if (txnType == TransactionType.value_transfer) { + if (type == TransactionType.value_transfer) { label = getTransactionLabel(externalAddresses, internalAddresses, widget.transaction.vtt!.inputs, singleAddressAccount, context); address = getTransactionAddress(label, widget.transaction.vtt!.inputs, diff --git a/lib/widgets/transactions_list.dart b/lib/widgets/transactions_list.dart index 0ba74016..912ec6f8 100644 --- a/lib/widgets/transactions_list.dart +++ b/lib/widgets/transactions_list.dart @@ -5,7 +5,7 @@ import 'package:my_wit_wallet/screens/dashboard/view/dashboard_screen.dart'; import 'package:my_wit_wallet/shared/api_database.dart'; import 'package:my_wit_wallet/shared/locator.dart'; import 'package:my_wit_wallet/util/get_localization.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/util/storage/database/wallet.dart'; import 'package:my_wit_wallet/widgets/speed_up_tx.dart'; import 'package:my_wit_wallet/widgets/transaction_details.dart'; @@ -75,6 +75,7 @@ class TransactionsListState extends State { speedUpTx: speedUpTx, filteredUtxos: false, currentWallet: currentWallet, + //TODO(#505): Support timelocks output: ValueTransferOutput.fromJson({ 'pkh': speedUpTx.vtt!.outputs.first.pkh.address, 'value': speedUpTx.vtt!.outputs.first.value.toInt(), diff --git a/lib/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/03_review_step.dart b/lib/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/03_review_step.dart index a3c363ac..90370d8c 100644 --- a/lib/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/03_review_step.dart +++ b/lib/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/03_review_step.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:my_wit_wallet/util/allow_biometrics.dart'; -import 'package:my_wit_wallet/util/storage/database/transaction_adapter.dart'; +import 'package:my_wit_wallet/util/storage/database/adapters/transaction_adapter.dart'; import 'package:my_wit_wallet/widgets/witnet/transactions/value_transfer/modals/general_error_tx_modal.dart'; import 'package:my_wit_wallet/widgets/witnet/transactions/value_transfer/modals/sending_tx_modal.dart'; import 'package:my_wit_wallet/widgets/witnet/transactions/value_transfer/modals/signing_tx_modal.dart'; diff --git a/node_modules/.yarn-integrity b/node_modules/.yarn-integrity deleted file mode 100644 index 1db5abba..00000000 --- a/node_modules/.yarn-integrity +++ /dev/null @@ -1,10 +0,0 @@ -{ - "systemParams": "darwin-x64-93", - "modulesFolders": [], - "flags": [], - "linkedModules": [], - "topLevelPatterns": [], - "lockfileEntries": {}, - "files": [], - "artifacts": {} -} \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 12ec97d0..7175f1a9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -43,7 +43,7 @@ dependencies: flutter_launcher_icons: ^0.13.1 sliding_up_panel: ^2.0.0+1 decimal: 2.3.3 - witnet: 0.3.0 + witnet: 0.4.1 path_provider: ^2.0.8 permission_handler: ^11.0.1 open_file: ^3.3.2 diff --git a/test/util/transactions_list/get_transaction_address_test.dart b/test/util/transactions_list/get_transaction_address_test.dart index 252f4a07..ef5221f0 100644 --- a/test/util/transactions_list/get_transaction_address_test.dart +++ b/test/util/transactions_list/get_transaction_address_test.dart @@ -12,23 +12,20 @@ void main() { List inputs = [ InputUtxo( address: 'wit1zl7ty0lwr7atp5fu34azkgewhtfx2fl4wv69cw', - input: Input( - outputPointer: OutputPointer.fromString( - '59e4dc54077871e71875a4b840da67c23659d89d41eaad85cdb9a5d552254b5d:9')), + inputUtxo: + '59e4dc54077871e71875a4b840da67c23659d89d41eaad85cdb9a5d552254b5d:9', value: 10180697116), ]; List severalInputs = [ InputUtxo( address: 'wit1zl7ty0lwr7atp5fu34azkgewhtfx2fl4wv69cw', - input: Input( - outputPointer: OutputPointer.fromString( - '59e4dc54077871e71875a4b840da67c23659d89d41eaad85cdb9a5d552254b5d:9')), + inputUtxo: + '59e4dc54077871e71875a4b840da67c23659d89d41eaad85cdb9a5d552254b5d:9', value: 10180697116), InputUtxo( address: 'wit2zl7ty0lwr7atp5fu34azkgewhtfx2fl4wv69cw', - input: Input( - outputPointer: OutputPointer.fromString( - '59e4dc54077871e71875a4b840da67c23659d89d41eaad85cdb9a5d552254b5d:9')), + inputUtxo: + '59e4dc54077871e71875a4b840da67c23659d89d41eaad85cdb9a5d552254b5d:9', value: 10180697116) ]; List outputs = [ diff --git a/test/util/transactions_list/get_transaction_label_test.dart b/test/util/transactions_list/get_transaction_label_test.dart index 83b6cb8c..ddd82a4b 100644 --- a/test/util/transactions_list/get_transaction_label_test.dart +++ b/test/util/transactions_list/get_transaction_label_test.dart @@ -2,7 +2,6 @@ import 'package:my_wit_wallet/util/storage/database/account.dart'; import 'package:my_wit_wallet/util/transactions_list/get_transaction_label.dart'; import 'package:test/test.dart'; import 'package:witnet/explorer.dart'; -import 'package:witnet/schema.dart'; void main() { List externalAddresses = [ @@ -22,9 +21,8 @@ void main() { List inputs = [ InputUtxo( address: 'wit1zl7ty0lwr7atp5fu34azkgewhtfx2fl4wv69cw', - input: Input( - outputPointer: OutputPointer.fromString( - '59e4dc54077871e71875a4b840da67c23659d89d41eaad85cdb9a5d552254b5d:9')), + inputUtxo: + '59e4dc54077871e71875a4b840da67c23659d89d41eaad85cdb9a5d552254b5d:9', value: 10180697116), ];