diff --git a/ios/Podfile b/ios/Podfile index cd56c2d83..6ad9d4590 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -109,5 +109,22 @@ target 'TempleWallet' do end break end + + # Xcode 26's compiler advertises consteval support that fmt 11 cannot use. + fmt_base = File.join(installer.sandbox.root, 'fmt', 'include', 'fmt', 'base.h') + + if File.exist?(fmt_base) + content = File.read(fmt_base) + unless content.include?('Xcode 26 workaround') + patched = content.gsub( + /^#elif defined\(__cpp_consteval\)\n# define FMT_USE_CONSTEVAL 1$/, + "// Xcode 26 workaround: disable consteval\n#elif defined(__cpp_consteval)\n# define FMT_USE_CONSTEVAL 0" + ) + if patched != content + File.chmod(0644, fmt_base) + File.write(fmt_base, patched) + end + end + end end end diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5edc0880e..df402b59c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -108,6 +108,36 @@ PODS: - libwebp/sharpyuv (1.5.0) - libwebp/webp (1.5.0): - libwebp/sharpyuv + - lottie-ios (4.6.0) + - lottie-react-native (7.3.8): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - lottie-ios (= 4.6.0) + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - nanopb (3.30910.0): - nanopb/decode (= 3.30910.0) - nanopb/encode (= 3.30910.0) @@ -3623,6 +3653,7 @@ DEPENDENCIES: - fmt (from `../node_modules/react-native/third-party-podspecs/fmt.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) + - lottie-react-native (from `../node_modules/lottie-react-native`) - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`) - RCTRequired (from `../node_modules/react-native/Libraries/Required`) @@ -3758,6 +3789,7 @@ SPEC REPOS: - libavif - libdav1d - libwebp + - lottie-ios - nanopb - PromisesObjC - React-Codegen @@ -3784,6 +3816,8 @@ EXTERNAL SOURCES: hermes-engine: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" :tag: hermes-v0.14.0 + lottie-react-native: + :path: "../node_modules/lottie-react-native" RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTDeprecation: @@ -4031,132 +4065,134 @@ SPEC CHECKSUMS: GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 GTMAppAuth: 217a876b249c3c585a54fd6f73e6b58c4f5c4238 GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 - hermes-engine: 14aa635b6bd5805973f70fb9acddb60e03442a22 + hermes-engine: 40ef4c6d260c452d5f1419bcfeab8cda7ad4fd76 libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 + lottie-ios: 8f959969761e9c45d70353667d00af0e5b9cadb3 + lottie-react-native: 7696ee54db539844f215c7e1f37372ae3138f37d nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 - RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f + RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: a41bbdd9af30bf2e5715796b313e44ec43eefff1 RCTRequired: 7be34aabb0b77c3cefe644528df0fa0afad4e4d0 RCTSwiftUI: a6c7271c39098bf00dbdad8f8ed997a59bbfbe44 - RCTSwiftUIWrapper: 5ec163e8fde163d3fba714a992b50a266e1ece37 + RCTSwiftUIWrapper: ff9098ccf7727e58218f2f8ea110349863f43438 RCTTypeSafety: 27927d0ca04e419ed9467578b3e6297e37210b5c React: 4bc1f928568ad4bcfd147260f907b4ea5873a03b React-callinvoker: 87f8728235a0dc62e9dc19b3851c829d9347d015 React-Codegen: 4b8b4817cea7a54b83851d4c1f91f79aa73de30a - React-Core: 19e0183e28d7a6613ecacebd7525fe6650efa3b6 - React-CoreModules: 73cc86f2a0ff84b93d6325073ad2e4874d21ad40 - React-cxxreact: 4bf734645c77c9b86e2f3e933e0411cf2f14d1ba + React-Core: 76bed73b02821e5630e7f2cb2e82432ee964695d + React-CoreModules: 752dbfdaeb096658aa0adc4a03ba6214815a08df + React-cxxreact: b6798528aa601c6db66e6adc7e2da2b059c8be74 React-debug: b2c9f60a9b7a81cefd737cb61e31c2bc39fdfe17 - React-defaultsnativemodule: d5577e030a746840c77d791f06382a5fd7c2b789 - React-domnativemodule: cec896810e9856a07ae62682b2c4e699307f9f35 - React-Fabric: ea457167d2bb9b8ceb31fd0882393ab08d32f0b8 - React-FabricComponents: aa8cf0b3409a81222786fb6e2e45069f44e060ca - React-FabricImage: 7629c06d41d6dea01d152ce0077b15147169f48f - React-featureflags: 7f1e45dd4148aabba7b42b2d588fb45d432c0a6d - React-featureflagsnativemodule: cb1c09c4e3e4873f101bbdd9be2fa0f7906ec5ab - React-graphics: 163d15b019d7ff23032a1a8d2b37f5afdd561bbb - React-hermes: ec50b9fcea2c3bfdd42f8cec845eac3f35888572 - React-idlecallbacksnativemodule: 1a358f7d16b9ff916a646ba184cded54f74439b8 - React-ImageManager: 958477b5f4acc67f864111c55de84bcdbd1d6592 - React-intersectionobservernativemodule: 189460858d6105bc44ded7fb02d19cd887f25bc6 - React-jserrorhandler: 291eddd4e3dc80927c306e039ecbeb4dc515eb6f - React-jsi: 3216c876cd4c571a57909e22d77c8fd9530aa067 - React-jsiexecutor: 475563c0042841a85930a455d3199f6b1483a5fe - React-jsinspector: 856aff364b569a4cd861605656de41d34c3cd92d - React-jsinspectorcdp: f34715c4c392e75f217bd5453aa8ff5bc394c111 - React-jsinspectornetwork: 8a02d4d189476b1a92d6c49014fa83973b6fc24d - React-jsinspectortracing: 9a97753c772fbce4f2ed8d4fb684e507d7e49a5a - React-jsitooling: 6fda3ff1bfed7525e7be2f5ca152b6d2d378e4a8 - React-jsitracing: a2dd6d6df9d017d5be176d5e71e09f8ce6f99594 - React-logger: 6ac901f5c7f7321d2be1a40b203bccc2e23411e3 - React-Mapbuffer: 9d33f0f79b6b5705d08d89d8fb9709d1ee655c81 - React-microtasksnativemodule: 1a5a9488d2a05c74ea276c2012df632d8221d169 - react-native-biometrics: 352e5a794bfffc46a0c86725ea7dc62deb085bdc - react-native-blur: 981b2ec64b3084ecf98812333f2a8c6e83643a1e - react-native-cloud-fs: cd21282c5cecaf285225e447dd7f3cf2f9015496 - react-native-config: 81fd713bbbc6fbe39588c975edf5485d0e15adf8 - react-native-document-picker: ca09736423f98ee844aec0ecf76c280103ef05cd - react-native-get-random-values: 4c1e8378eb5a30b2ac9aa6e28da7c3a987350e8a - react-native-netinfo: f0a9899081c185db1de5bb2fdc1c88c202a059ac - react-native-orientation-locker: 5819fd23ca89cbac0d736fb4314745f62716d517 - react-native-restart: 7595693413fe3ca15893702f2c8306c62a708162 - react-native-safe-area-context: fea29ae0275beaa22f72d0a8be1eb0ab09c3feae - react-native-sapling: 36b28bc90d96e6ccc754c515d0dd3ba99049a094 - react-native-slider: f44eb4f327db65c7c0519cc91aefb7b0d50f1615 - react-native-themis: 52e1ff00dbd17ca8ddec02c6e071259602f4b5c7 - react-native-video: f9758cda5b9dd6fd378389002f28f3f19017a406 - react-native-webview: 5887b6094417c75a9bee446261f89c32adf6b602 - React-NativeModulesApple: dfce21d2c4b7eab44db0af861fcb8998d0b8ad16 - React-networking: 26355121d0bf86d974dff5a3cc11f8aeb9f28a22 + React-defaultsnativemodule: d9eb6790253633d37bab0dfd46994d772968be51 + React-domnativemodule: eee0fbeb6828e86ad1d1a0f8d2d89bc604a62cc4 + React-Fabric: 5eec4db4e42bbb55308900ee2aeb395d641f63b1 + React-FabricComponents: 556077c756a43b0c0ab719b07a282bc0bb081fc6 + React-FabricImage: 2ebf436bfe52bc6d9d2ae37a3d643280c8266e4e + React-featureflags: d3a2bd36b3763547e7887a30257191192ee789e6 + React-featureflagsnativemodule: 9c06fad6d4f1def2dc7a45b56da2b96a0b7853a5 + React-graphics: b116d3926d6c159565ea9ee96504d8c1d9cfbcdc + React-hermes: 32fc9c231c1aa5c2fcfe851b0d19ee9269f88f4c + React-idlecallbacksnativemodule: d8034c2adb86c8ff3c03be505cb9a20c8ced1737 + React-ImageManager: 6c5cd273187a1f3ccf68f6d6bf57e06647baf50e + React-intersectionobservernativemodule: 1d8f1fe45ab8d45a82b08562ff412b6f128d41d3 + React-jserrorhandler: c1455b7243cf6fed0a8fd82bfbb2ef7637372304 + React-jsi: adf8527fec197ad9d0480cc5b8945eb56de627f0 + React-jsiexecutor: 315fa2f879b43e3a9ca08f5f4b733472f7e4e8a4 + React-jsinspector: 31fa81ccb390c1369acd545c3710ab6169ee77ff + React-jsinspectorcdp: 2d80f6c2d69b9b1809c272d999730dcc5b21a973 + React-jsinspectornetwork: 3aed0076638835994bfce74ea3f05a901d3ab110 + React-jsinspectortracing: 9f5ff99c584ae25d71ba158f852219e62dba8afc + React-jsitooling: 4e41ef5710527621ab85f2ee5a9c8ea05791aeee + React-jsitracing: f7f0e13dfa856460817b7f74f36c883dd0eb89b6 + React-logger: b8483fa08e0d62e430c76d864309d90576ca2f68 + React-Mapbuffer: d0c5f3793332ebec11bfbbbd962ea526ee85efff + React-microtasksnativemodule: 1a7d806e2ec20df1c6d88b29e72787fb48aeab70 + react-native-biometrics: 43ed5b828646a7862dbc7945556446be00798e7d + react-native-blur: b83ffbc5380d8bd2f06804b4b0e848be3507e65c + react-native-cloud-fs: 1f838a872b0204376514f5df175ccbbd342f496f + react-native-config: 916e53e7333d5b2bcb7ee9882f5605143b4fc4c5 + react-native-document-picker: 910f7b853dc56664285752289d477a48537f0178 + react-native-get-random-values: 9ef342c6e33fa57ac82f73e9270d5d651a48071a + react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 + react-native-orientation-locker: cc6f357b289a2e0dd2210fea0c52cb8e0727fdaa + react-native-restart: 0bc732f4461709022a742bb29bcccf6bbc5b4863 + react-native-safe-area-context: 0a3b034bb63a5b684dd2f5fffd3c90ef6ed41ee8 + react-native-sapling: dcefd6adbe3dc7717a8336f7a9719c046b35ddab + react-native-slider: 05e7080478df08489251c2a6739a0d5628b7c198 + react-native-themis: b681fd9654ec2b55b9fb81d086159d974f752d6c + react-native-video: 624deff94be379ffaba289bed13fc0917f01abcb + react-native-webview: cdce419e8022d0ef6f07db21890631258e7a9e6e + React-NativeModulesApple: e554252d69442010807867cc7d70c0008048ad20 + React-networking: 669cb54cc7e5b65d7dafeeb36970a1421adc8bb3 React-oscompat: 80166b66da22e7af7fad94474e9997bd52d4c8c6 - React-perflogger: 63c90e0d8c24df87ffa14dad01aeafc352847dd0 - React-performancecdpmetrics: 5b0a0eb369b5fcb18109fba91bdd5ac2a2360753 - React-performancetimeline: 9a45658d92ce7b30d41fa557bbe9fa7c399f301b + React-perflogger: d6797918d2b1031e91a9d8f5e7fdd2c8728fb390 + React-performancecdpmetrics: 7706707d5dd49d708518a91abe456dcb585a5865 + React-performancetimeline: c9807b559901c4298a92f6bcb069f49f518b7020 React-RCTActionSheet: 3bd5f5db9f983cf38d51bb9a7a198e2ebea94821 - React-RCTAnimation: 346865a809fa5132f6c594c8b376c6cf46b44e88 - React-RCTAppDelegate: b2d1e0d3663c987f49f45094883b9e36fcbf0181 - React-RCTBlob: 74759ebb7ff9077d19f60c301782c1f8c3eb2813 - React-RCTFabric: 7a352dc4db7da5334b36d0074d3e44a112d4d168 - React-RCTFBReactNativeSpec: f74fabd086f4a302a9883086ad1398a4408aecd4 - React-RCTImage: 60763f56e8a5e45d861d7c4777e428bb820ec52a - React-RCTLinking: 52aee78b0b3163167c7fcf58f80a42943c03a056 - React-RCTNetwork: f5e1e8ae5eff6982efff6289b06ec0a76d0a6ac2 - React-RCTRuntime: b1c69249aab7cf0ff2b9cf7bd7d1cdc23c60c89f - React-RCTSettings: 298bb40d3412bf32e0b4f0797e48416b0b7278a1 - React-RCTText: dfb74800e27d792d1188fa975a3b9807c3362e3e - React-RCTVibration: ffe5fd4f50a835e353a3b6869eb005dab11eea44 + React-RCTAnimation: 46a9978f27dc434dbeed16afa7b82619b690a9af + React-RCTAppDelegate: 62ecd60a2b2a8cae26ce6a066bfa59cfde97af01 + React-RCTBlob: 8285c859513023ee3cc8c806d9b59d4da078c4ba + React-RCTFabric: ab7096fa22eea969efe8947c6296d3c5e03bf51a + React-RCTFBReactNativeSpec: 7bddf0751b44174a60921dc680fa6396a0873de1 + React-RCTImage: a5364d0f098692cfbf5bef1e8a63e7712ecb14b7 + React-RCTLinking: 34b63b0aa0e92d30f5d7aa2c255a8f95fa75ee8f + React-RCTNetwork: 1ef88b7a5310b8f915d3556b5b247def113191ed + React-RCTRuntime: 5217917c3c456268a029c09af419b3c6d93bf6d4 + React-RCTSettings: 2c45623d6c0f30851a123f621eb9d32298bcbb0c + React-RCTText: 0ee70f5dc18004b4d81b2c214267c6cbec058587 + React-RCTVibration: 88557e21e7cc3fe76b5b174cba28ff45c6def997 React-rendererconsistency: ac8a9e9ee3eb299458cc848944133ff4be46cc41 - React-renderercss: 25ff740b0da15dab6ba505c702c86bfbe9cd764e - React-rendererdebug: 48afb7a15ed4f2a87760e63abdc70bb92f4165d0 - React-RuntimeApple: bcc8fbdce32bc7100294bf9a4b741da233d38de2 - React-RuntimeCore: 632c35fbe0980a390719470a9f6d2f1ba9dc3bd0 - React-runtimeexecutor: 8151aae90978856b75f3c5079c428c00f795ffa6 - React-RuntimeHermes: 1269317d3d7d899f27aa3c03a04d7ce017171837 - React-runtimescheduler: 752209b337a93cd3a25ecea691308f6b801706cf - React-timing: 73729fab687aa4876d45707e9f7ddc9446effab1 - React-utils: a60c501ec701ca062f3c5367ce766c4e5bfc363a - React-webperformancenativemodule: 7ec95df9690d9cc96e31f3282facecd39a3914a6 - ReactAppDependencyProvider: bfb12ead469222b022a2024f32aba47ce50de512 - ReactCodegen: 0e88072391201f99a9ce48e9ad27310d63b336ae - ReactCommon: 136c3863bf14312a58944f674691f2c5874deafb - ReactNativeExceptionHandler: b11ff67c78802b2f62eed0e10e75cb1ef7947c60 - RNBootSplash: d8407c268d5159ea026dc741ec867ebbe4708f25 - RNCAsyncStorage: 8857fb173af29664cb90897903902dc8533e36cc - RNCClipboard: 4eea71d801c880175c12f6ab14332ca86fed935f - RNCMaskedView: 8bfc13a356455b15d56114738f4d2a804769c1bf - RNDeviceInfo: 53f9c84e28e854a308d3e548e25ef120b4615531 - RNExitApp: a804a6de055a698e2f6c11e8fce146c5c8ce3ead - RNFastImage: 94681302bfbe8076b0163450183ae2121b45e525 - RNFBApp: 76f7bc724c9b60f1439ca60b256eed17b14a6ddb - RNFBAppCheck: 52bbfdd0396db9fe16e5734a36734e9edb3535ee - RNFBMessaging: a39a75dc6e4f3d1433eaffefe131a400380602a3 - RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 - RNGestureHandler: 1f7ac76fa9d6ffedfdde38ce781442ffadac8880 - RNGoogleSignin: 9c5c73089b78fd865f9a6758fc05ef7da7bd2be2 - RNKeychain: d0bdaca4688ae123909b137de08491f49a6cf6b1 - RNNotifee: 4a6ee5c7deaf00e005050052d73ee6315dff7ec9 - RNPermissions: d5c31fdf7f0368d8740f2d3aefe212ed007e6cca - RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93 - RNReactNativeHapticFeedback: 43c09eb41d8321be2e1375cb87ae734e58f677b0 - RNReanimated: 0a23a0a9721f450580f0fdf04b9ae928cd22915a - RNScreens: c73f6bcfc19e209736c4e069f62b0f274535214b - RNScrypt: 95fdef077b482e9fdf8a761120cb69d129ef4016 - RNSentry: f3c0498f67c1a7ff86155b66b74318cdfcaeb693 - RNSha256: e1bc64e9e50b293d5282bb4caa1b2043931f1c9d - RNSVG: 5bd1e478698eb9e5cc8f926157333ac814468064 - RNWorklets: b94f5c1b61a985c309dcc0092aacf41515cc39d6 + React-renderercss: f04cbe3b06ee071c6ca724f41a3c3aa31332601e + React-rendererdebug: 2a2e4f7d42abcbec2047e989a1afda5d62905679 + React-RuntimeApple: ce2ae0ea88316a7c708be1e6601e4ec5f6febdce + React-RuntimeCore: 55b3dcac1c0e7acf98aaebb9b4c6a793bdc332e0 + React-runtimeexecutor: e4bf693c55393af5c4c62ac775c7212552ccde7a + React-RuntimeHermes: a9e2538786653648830a0efb278d51237c1a8c27 + React-runtimescheduler: 0142588a3aad9a8607f0de743330d6e459f604b8 + React-timing: 95d4939cbcd64d05c94d7c18b9cfba7c931340fd + React-utils: 28158276c67b375d1b7546a342571cfffbea9770 + React-webperformancenativemodule: 3aa0693c4d19898831317e17b005fad3444d2c99 + ReactAppDependencyProvider: 0eb286cc274abb059ee601b862ebddac2e681d01 + ReactCodegen: d663254bf59e57e5ed7c65638bd45f358a373bba + ReactCommon: 15e1e727fa34f760beb7dd52928687fda8edf8dc + ReactNativeExceptionHandler: a23922ca00122b050ae9412f960061791c232c47 + RNBootSplash: 7fcc9a58ae343aeb1a1dd49f9030832fe432c544 + RNCAsyncStorage: fd44f4b03e007e642e98df6726737bc66e9ba609 + RNCClipboard: e560338bf6cc4656a09ff90610b62ddc0dbdad65 + RNCMaskedView: d707a83784c67099b54b37d056ababb2767ce15e + RNDeviceInfo: 36d7f232bfe7c9b5c494cb7793230424ed32c388 + RNExitApp: a2fd7923ab37b9166704fdc488622a48dcd372a2 + RNFastImage: 674d5912e174468a60971d2ba9efc7bb43d116fa + RNFBApp: 7104f721191eec915eb669285a552d46e9567f35 + RNFBAppCheck: 6e60a78f5899b488c82ffa42426ee1538fda3078 + RNFBMessaging: 91df9cd73442c4906b379851d3d13f6132f623d2 + RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8 + RNGestureHandler: c6327cf6e2bd384dc90351ccfff0da8142d62f54 + RNGoogleSignin: c1de96d92d6dd4335fa8e0f0ed4312a9d34e4ecb + RNKeychain: 76d042fc1dfba47f3945920bc82e0bce9ad1ff55 + RNNotifee: 5e3b271e8ea7456a36eec994085543c9adca9168 + RNPermissions: 0dbae39cf157f6c699f1454bbdcc25a0977eca83 + RNQuickAction: c2c8f379e614428be0babe4d53a575739667744d + RNReactNativeHapticFeedback: 5f1542065f0b24c9252bd8cf3e83bc9c548182e4 + RNReanimated: fbcb7fd8da5b0b088401542c58fb5d266388f1cf + RNScreens: d6413aeb1878cdafd3c721e2c5218faf5d5d3b13 + RNScrypt: 3e8612600c93aaa3bfa7849b6d1a4ab61613e2af + RNSentry: 0cb5c73bdb064318193d5b658774bd34f83107cf + RNSha256: 4d35f112e967f58273d625a19376f4eafc72bd5c + RNSVG: b5da7cb4bb60503fd841bf6eddae1d171e515d79 + RNWorklets: 69f7239afaf3a156f7f9549eeb0ae8d02adc095f SDWebImage: e9c98383c7572d713c1a0d7dd2783b10599b9838 SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57 SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c SDWebImageWebPCoder: 0e06e365080397465cc73a7a9b472d8a3bd0f377 Sentry: d587a8fe91ca13503ecd69a1905f3e8a0fcf61be SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - VisionCamera: 68d40255fa8866e815cbbb063730102d3da276fd + VisionCamera: b51af005669c6642dd1b4fca434eda4c1778de87 Yoga: 33b53536a0500d039f2cd78caf1d5d68712d3af7 -PODFILE CHECKSUM: 6c9f36f7a741b08836b8fe7eeb4d59447eddae08 +PODFILE CHECKSUM: 75ef8cd7b745e16499a01e7522c1aeb89b4950d7 COCOAPODS: 1.16.2 diff --git a/jest.config.js b/jest.config.js index f04a96521..8640de7dc 100644 --- a/jest.config.js +++ b/jest.config.js @@ -32,6 +32,7 @@ module.exports = { moduleNameMapper: { '^src/(.*)': '/src/$1', '\\.svg': '/src/mocks/svg.mock.js', + '^lottie-react-native$': '/src/mocks/lottie-react-native.mock.tsx', '^react-native-themis': '/node_modules/react-native-themis/src/index.js', '^@stablelib/wipe$': '/src/mocks/stablelib/wipe.mock.ts', '^@stablelib/nacl$': '/src/mocks/stablelib/nacl.mock.ts', diff --git a/package.json b/package.json index 728f9b8b2..8f1fdc69a 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "formik": "^2.2.9", "graphql": "^16.6.0", "lodash-es": "^4.18.1", + "lottie-react-native": "7.3.8", "memoizee": "^0.4.15", "node-forge": "^1.3.2", "pbkdf2": "^3.1.5", diff --git a/src/assets/animations/tkey-coin-animation.json b/src/assets/animations/tkey-coin-animation.json new file mode 100644 index 000000000..3ef79dbbc --- /dev/null +++ b/src/assets/animations/tkey-coin-animation.json @@ -0,0 +1 @@ +{"ddd":0,"h":400,"w":400,"meta":{"g":"@lottiefiles/toolkit-js 0.57.2-beta.0"},"layers":[{"ty":3,"sr":1,"st":0,"op":300,"ip":0,"ln":"60","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[45.1,45.1,100]},"p":{"a":0,"k":[200,190.4,0]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}},"ind":1},{"ty":0,"sr":1,"st":4.75,"op":32.25,"ip":4.75,"ln":"57","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[-2930.3999999999996,-911.5999999999999]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.223,0.223,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":4.75},{"s":[9.8,9.8,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":31.75}]},"p":{"a":0,"k":[0,0,0]},"r":{"a":0,"k":-24},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":4.75},{"s":[0],"t":32.25}]}},"w":400,"h":400,"refId":"1","ind":2,"parent":1},{"ty":0,"sr":1,"st":0,"op":32.25,"ip":0,"ln":"56","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[3264.3999999999996,1217.2]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.223,0.223,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0},{"s":[9.8,9.8,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":27.5}]},"p":{"a":0,"k":[0,0,0]},"r":{"a":0,"k":-24},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":0},{"s":[0],"t":27.5}]}},"w":400,"h":400,"refId":"1","ind":3,"parent":1},{"ty":0,"sr":1,"st":2.25,"op":32.25,"ip":2.25,"ln":"55","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[316.40000000000003,3540]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.223,0.223,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":2.25},{"s":[9.8,9.8,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":29.75}]},"p":{"a":0,"k":[0,0,0]},"r":{"a":0,"k":2},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":2.25},{"s":[0],"t":29.75}]}},"w":400,"h":400,"refId":"1","ind":4,"parent":1},{"ty":0,"sr":1,"st":4.75,"op":32.25,"ip":4.75,"ln":"54","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[-185.60000000000002,-1890.8000000000002]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.223,0.223,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":4.75},{"s":[19.6,19.6,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":32.25}]},"p":{"a":0,"k":[0,0,0]},"r":{"a":0,"k":7},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":4.75},{"s":[0],"t":32.25}]}},"w":400,"h":400,"refId":"1","ind":5,"parent":1},{"ty":0,"sr":1,"st":2.25,"op":32.25,"ip":2.25,"ln":"53","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[1607.6000000000001,2409.6]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.223,0.223,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":2.25},{"s":[16.8,16.8,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":29.75}]},"p":{"a":0,"k":[0,0,0]},"r":{"a":0,"k":-18},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":2.25},{"s":[0],"t":29.75}]}},"w":400,"h":400,"refId":"1","ind":6,"parent":1},{"ty":0,"sr":1,"st":3.75,"op":31.25,"ip":3.75,"ln":"52","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[-1826.8000000000002,-327.59999999999997]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.223,0.223,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":3.75},{"s":[21,21,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":31.25}]},"p":{"a":0,"k":[0,23.758,0]},"r":{"a":0,"k":20},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":3.75},{"s":[0],"t":31.25}]}},"w":400,"h":400,"refId":"1","ind":7,"parent":1},{"ty":0,"sr":1,"st":2.25,"op":32.25,"ip":2.25,"ln":"51","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[1794.0000000000002,-664.8]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.223,0.223,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":2.25},{"s":[16.8,16.8,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":29.75}]},"p":{"a":0,"k":[0,0,0]},"r":{"a":0,"k":-18},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":2.25},{"s":[0],"t":29.75}]}},"w":400,"h":400,"refId":"1","ind":8,"parent":1},{"ty":0,"sr":1,"st":-1,"op":32.25,"ip":0,"ln":"50","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[-1138.4,2462.8]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.223,0.223,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0},{"s":[14,14,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":27.5}]},"p":{"a":0,"k":[0,0,0]},"r":{"a":0,"k":10},"o":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[100],"t":0},{"s":[0],"t":27.5}]}},"w":400,"h":400,"refId":"1","ind":9,"parent":1},{"ty":0,"sr":1,"st":-2,"op":88,"ip":-2,"ln":"33","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[200,200]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":-2},{"s":[0,0,100],"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":-1},{"s":[0,0,100],"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":0},{"s":[0,0,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":1},{"s":[6.923,6.923,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":2},{"s":[13.846,13.846,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":3},{"s":[20.769,20.769,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":4},{"s":[27.692,27.692,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":5},{"s":[34.615,34.615,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":6},{"s":[41.538,41.538,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":7},{"s":[48.462,48.462,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":8},{"s":[55.385,55.385,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":9},{"s":[62.308,62.308,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":10},{"s":[69.231,69.231,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":11},{"s":[76.154,76.154,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":12},{"s":[83.077,83.077,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":13},{"s":[90,90,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":14},{"s":[94.04,94.04,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":15},{"s":[97.393,97.393,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":16},{"s":[99.995,99.995,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":17},{"s":[101.822,101.822,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":18},{"s":[102.888,102.888,100],"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.003,0.003,0]},"t":19},{"s":[103.241,103.241,100],"i":{"x":[0.833,0.833,0.833],"y":[0.997,0.997,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":20},{"s":[102.953,102.953,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":21},{"s":[102.117,102.117,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":22},{"s":[100.841,100.841,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":23},{"s":[99.235,99.235,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":24},{"s":[97.413,97.413,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":25},{"s":[95.485,95.485,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":26},{"s":[93.551,93.551,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":27},{"s":[91.698,91.698,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":28},{"s":[90,90,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":29},{"s":[88.514,88.514,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":30},{"s":[87.28,87.28,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":31},{"s":[86.323,86.323,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":32},{"s":[85.651,85.651,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":33},{"s":[85.259,85.259,100],"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.003,0.003,0]},"t":34},{"s":[85.129,85.129,100],"i":{"x":[0.833,0.833,0.833],"y":[0.997,0.997,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":35},{"s":[85.235,85.235,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":36},{"s":[85.542,85.542,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":37},{"s":[86.012,86.012,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":38},{"s":[86.603,86.603,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":39},{"s":[87.273,87.273,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":40},{"s":[87.982,87.982,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":41},{"s":[88.694,88.694,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":42},{"s":[89.375,89.375,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":43},{"s":[90,90,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":44},{"s":[90.547,90.547,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":45},{"s":[91.001,91.001,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":46},{"s":[91.353,91.353,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":47},{"s":[91.6,91.6,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":48},{"s":[91.744,91.744,100],"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.003,0.003,0]},"t":49},{"s":[91.792,91.792,100],"i":{"x":[0.833,0.833,0.833],"y":[0.997,0.997,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":50},{"s":[91.753,91.753,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":51},{"s":[91.64,91.64,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":52},{"s":[91.467,91.467,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":53},{"s":[91.25,91.25,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":54},{"s":[91.003,91.003,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":55},{"s":[90.742,90.742,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":56},{"s":[90.481,90.481,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":57},{"s":[90.23,90.23,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":58},{"s":[90,90,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":59},{"s":[89.799,89.799,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":60},{"s":[89.632,89.632,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":61},{"s":[89.502,89.502,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":62},{"s":[89.411,89.411,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":63},{"s":[89.358,89.358,100],"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.003,0.003,0]},"t":64},{"s":[89.341,89.341,100],"i":{"x":[0.833,0.833,0.833],"y":[0.997,0.997,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":65},{"s":[89.355,89.355,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":66},{"s":[89.397,89.397,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":67},{"s":[89.46,89.46,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":68},{"s":[89.54,89.54,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":69},{"s":[89.631,89.631,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":70},{"s":[89.727,89.727,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":71},{"s":[89.823,89.823,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":72},{"s":[89.915,89.915,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":73},{"s":[90,90,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":74},{"s":[90.074,90.074,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":75},{"s":[90.135,90.135,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":76},{"s":[90.183,90.183,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":77},{"s":[90.217,90.217,100],"i":{"x":[0.833,0.833,0.833],"y":[0.999,0.999,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":78},{"s":[90.236,90.236,100],"i":{"x":[0.833,0.833,0.833],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.003,0.003,0]},"t":79},{"s":[90.243,90.243,100],"i":{"x":[0.833,0.833,0.833],"y":[0.997,0.997,1]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0]},"t":80},{"s":[90.237,90.237,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":81},{"s":[90.222,90.222,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.001,0.001,0]},"t":82},{"s":[90.199,90.199,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":83},{"s":[90.169,90.169,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":84},{"s":[90.136,90.136,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":85},{"s":[90.1,90.1,100],"i":{"x":[0.833,0.833,0.833],"y":[0.998,0.998,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.002,0.002,0]},"t":86},{"s":[90.065,90.065,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":87}]},"p":{"a":0,"k":[-4.435,8.869,0]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}},"w":400,"h":400,"refId":"4","ind":10,"parent":1},{"ty":4,"sr":1,"st":1,"op":32,"ip":1,"ln":"16","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.245,0.245,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":1},{"s":[64.774,64.774,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":18.75}]},"p":{"a":0,"k":[200,200]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}},"shapes":[{"ty":"gr","it":[{"ty":"el","d":1,"p":{"a":0,"k":[0,0]},"s":{"a":0,"k":[300,300]}},{"ty":"st","lc":2,"lj":2,"ml":4,"o":{"a":0,"k":100},"w":{"a":1,"k":[{"o":{"x":0.167,"y":0},"i":{"x":0.242,"y":1},"s":[30],"t":0.75},{"s":[0],"t":19}]},"c":{"a":0,"k":[0.9451,0.656,0.315]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}}]}],"ind":11},{"ty":4,"sr":1,"st":4.5,"op":33.25,"ip":4.5,"ln":"15","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0]},"s":{"a":1,"k":[{"s":[0,0,100],"i":{"x":[0.245,0.245,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":4.5},{"s":[89.938,89.938,100],"i":{"x":[0.99,0.99,0.99],"y":[1,1,1]},"o":{"x":[0.01,0.01,0.01],"y":[0,0,0]},"t":19.75}]},"p":{"a":0,"k":[200,200]},"r":{"a":0,"k":0},"o":{"a":0,"k":50}},"shapes":[{"ty":"gr","it":[{"ty":"el","d":1,"p":{"a":0,"k":[0,0]},"s":{"a":0,"k":[300,300]}},{"ty":"st","lc":2,"lj":2,"ml":4,"o":{"a":0,"k":100},"w":{"a":1,"k":[{"o":{"x":0.167,"y":0},"i":{"x":0.242,"y":1},"s":[15],"t":4.75},{"s":[0],"t":20}]},"c":{"a":0,"k":[0.9686,0.8431,0.7725]}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}}]}],"ind":12}],"v":"5.7.0","fr":30,"op":90,"ip":0,"assets":[{"id":"1","layers":[{"ty":4,"sr":1,"st":0,"op":900,"ip":0,"hd":true,"ln":"49","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[29.688,-30.887,0]},"s":{"a":0,"k":[235,235,100]},"p":{"a":0,"k":[203.873,202.38,0]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}},"shapes":[{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.303,-0.474],[0,-1.778],[-4.208,-0.829]],"o":[[-1.6,0],[-1.304,0.475],[0,2.371],[0,0]],"v":[[27.643,-50.931],[23.288,-50.22],[21.332,-46.842],[27.643,-42.043]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-1.422,0.86],[0,1.719],[1.303,0.8],[2.311,0.771]],"o":[[2.074,-0.178],[1.422,-0.858],[0,-1.54],[-1.304,-0.8],[0,0]],"v":[[32.265,-12.533],[37.509,-14.088],[39.643,-17.955],[37.687,-21.466],[32.265,-23.821]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[3.289,1.274],[2.103,2.104],[1.007,2.726],[0.118,2.904],[0,0],[-0.149,-0.947],[-0.504,-0.858],[-0.949,-0.622],[-1.719,-0.118],[0,0],[1.274,0.326],[1.362,0.475],[2.014,0.919],[1.422,1.275],[0.769,1.749],[0,2.548],[-1.453,2.637],[-2.282,1.689],[-2.844,0.8],[-2.786,0],[0,0],[0,0],[0,0],[-2.844,-0.8],[-2.164,-1.689],[-1.275,-2.607],[0,-3.614],[0,0],[0.267,0.771],[0.503,0.475],[0.769,0.297],[1.125,0.237],[0,0],[-3.408,-1.511],[-1.808,-1.807],[-0.533,-2.133],[0,-2.489],[0.918,-2.429],[2.074,-1.955],[3.289,-1.244],[4.68,0],[0,0],[0,0]],"o":[[-4.682,0],[-3.289,-1.274],[-2.104,-2.103],[-1.008,-2.725],[0,0],[0,0.771],[0.147,0.949],[0.503,0.86],[0.947,0.622],[0,0],[-1.186,-0.356],[-1.275,-0.325],[-2.43,-0.829],[-2.015,-0.918],[-1.422,-1.274],[-0.771,-1.747],[0,-3.614],[1.451,-2.636],[2.28,-1.689],[2.844,-0.8],[0,0],[0,0],[0,0],[3.08,0],[2.844,0.8],[2.162,1.689],[1.274,2.608],[0,0],[-0.119,-1.125],[-0.267,-0.769],[-0.504,-0.474],[-0.771,-0.296],[0,0],[5.747,1.244],[3.407,1.511],[1.807,1.808],[0.533,2.133],[0,2.43],[-0.919,2.43],[-2.075,1.955],[-3.289,1.244],[0,0],[0,0],[0,0]],"v":[[27.643,1.511],[15.688,-0.4],[7.6,-5.466],[2.933,-12.711],[1.244,-21.155],[20.266,-21.155],[20.488,-18.577],[21.466,-15.866],[23.643,-13.644],[27.643,-12.533],[27.643,-25.066],[23.954,-26.088],[19.999,-27.288],[13.333,-29.91],[8.177,-33.198],[4.889,-37.732],[3.733,-44.176],[5.911,-53.553],[11.511,-60.042],[19.199,-63.775],[27.643,-64.975],[27.643,-72.086],[32.265,-72.086],[32.265,-64.975],[41.154,-63.775],[48.664,-60.042],[53.82,-53.598],[55.731,-44.265],[38.754,-44.265],[38.176,-47.109],[37.021,-48.976],[35.109,-50.131],[32.265,-50.931],[32.265,-40.976],[45.998,-36.843],[53.82,-31.865],[57.331,-25.954],[58.131,-19.021],[56.753,-11.733],[52.264,-5.155],[44.22,-0.356],[32.265,1.511],[32.265,10.311],[27.643,10.311]]}}},{"ty":"fl","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":100}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}}]}],"ind":1},{"ty":0,"sr":1,"st":0,"op":300,"ip":0,"ln":"79","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[188,188]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[200,200]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}},"w":376,"h":376,"refId":"2","ind":2}]},{"id":"2","layers":[{"ty":2,"sr":1,"st":0,"op":300,"ip":0,"ln":"78","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[157.684,157]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[187.429,188,0]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}},"refId":"3","ind":1}]},{"id":"3","e":1,"w":316,"h":314,"p":"data:image/png;base64,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","u":""},{"id":"4","layers":[{"ty":4,"sr":1,"st":0,"op":900,"ip":0,"hd":true,"ln":"32","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[29.688,-30.887,0]},"s":{"a":0,"k":[235,235,100]},"p":{"a":0,"k":[203.873,202.38,0]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}},"shapes":[{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.303,-0.474],[0,-1.778],[-4.208,-0.829]],"o":[[-1.6,0],[-1.304,0.475],[0,2.371],[0,0]],"v":[[27.643,-50.931],[23.288,-50.22],[21.332,-46.842],[27.643,-42.043]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-1.422,0.86],[0,1.719],[1.303,0.8],[2.311,0.771]],"o":[[2.074,-0.178],[1.422,-0.858],[0,-1.54],[-1.304,-0.8],[0,0]],"v":[[32.265,-12.533],[37.509,-14.088],[39.643,-17.955],[37.687,-21.466],[32.265,-23.821]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[3.289,1.274],[2.103,2.104],[1.007,2.726],[0.118,2.904],[0,0],[-0.149,-0.947],[-0.504,-0.858],[-0.949,-0.622],[-1.719,-0.118],[0,0],[1.274,0.326],[1.362,0.475],[2.014,0.919],[1.422,1.275],[0.769,1.749],[0,2.548],[-1.453,2.637],[-2.282,1.689],[-2.844,0.8],[-2.786,0],[0,0],[0,0],[0,0],[-2.844,-0.8],[-2.164,-1.689],[-1.275,-2.607],[0,-3.614],[0,0],[0.267,0.771],[0.503,0.475],[0.769,0.297],[1.125,0.237],[0,0],[-3.408,-1.511],[-1.808,-1.807],[-0.533,-2.133],[0,-2.489],[0.918,-2.429],[2.074,-1.955],[3.289,-1.244],[4.68,0],[0,0],[0,0]],"o":[[-4.682,0],[-3.289,-1.274],[-2.104,-2.103],[-1.008,-2.725],[0,0],[0,0.771],[0.147,0.949],[0.503,0.86],[0.947,0.622],[0,0],[-1.186,-0.356],[-1.275,-0.325],[-2.43,-0.829],[-2.015,-0.918],[-1.422,-1.274],[-0.771,-1.747],[0,-3.614],[1.451,-2.636],[2.28,-1.689],[2.844,-0.8],[0,0],[0,0],[0,0],[3.08,0],[2.844,0.8],[2.162,1.689],[1.274,2.608],[0,0],[-0.119,-1.125],[-0.267,-0.769],[-0.504,-0.474],[-0.771,-0.296],[0,0],[5.747,1.244],[3.407,1.511],[1.807,1.808],[0.533,2.133],[0,2.43],[-0.919,2.43],[-2.075,1.955],[-3.289,1.244],[0,0],[0,0],[0,0]],"v":[[27.643,1.511],[15.688,-0.4],[7.6,-5.466],[2.933,-12.711],[1.244,-21.155],[20.266,-21.155],[20.488,-18.577],[21.466,-15.866],[23.643,-13.644],[27.643,-12.533],[27.643,-25.066],[23.954,-26.088],[19.999,-27.288],[13.333,-29.91],[8.177,-33.198],[4.889,-37.732],[3.733,-44.176],[5.911,-53.553],[11.511,-60.042],[19.199,-63.775],[27.643,-64.975],[27.643,-72.086],[32.265,-72.086],[32.265,-64.975],[41.154,-63.775],[48.664,-60.042],[53.82,-53.598],[55.731,-44.265],[38.754,-44.265],[38.176,-47.109],[37.021,-48.976],[35.109,-50.131],[32.265,-50.931],[32.265,-40.976],[45.998,-36.843],[53.82,-31.865],[57.331,-25.954],[58.131,-19.021],[56.753,-11.733],[52.264,-5.155],[44.22,-0.356],[32.265,1.511],[32.265,10.311],[27.643,10.311]]}}},{"ty":"fl","c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":100}},{"ty":"tr","a":{"a":0,"k":[0,0]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}}]}],"ind":1},{"ty":0,"sr":1,"st":0,"op":300,"ip":0,"ln":"80","hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[188,188]},"s":{"a":0,"k":[100,100]},"p":{"a":0,"k":[200,200]},"r":{"a":0,"k":0},"o":{"a":0,"k":100}},"w":376,"h":376,"refId":"2","ind":2}]}]} diff --git a/src/components/checkbox-group-item/index.tsx b/src/components/checkbox-group-item/index.tsx index de840a76c..57c8438dc 100644 --- a/src/components/checkbox-group-item/index.tsx +++ b/src/components/checkbox-group-item/index.tsx @@ -2,6 +2,7 @@ import React, { ReactNode, memo, useCallback, useState } from 'react'; import { AlertButton, AlertOptions, View } from 'react-native'; import Dialog from 'react-native-dialog'; +import { formatSize } from '../../styles/format-size.ts'; import { IconNameEnum } from '../icon/icon-name.enum'; import { TouchableIcon } from '../icon/touchable-icon/touchable-icon'; @@ -30,7 +31,7 @@ export const CheckboxGroupItem = memo(({ infoAlertArgs, {infoAlertArgs && ( <> - + + + diff --git a/src/components/icon/assets/dollar-filled.svg b/src/components/icon/assets/dollar-filled.svg new file mode 100644 index 000000000..d2057c78e --- /dev/null +++ b/src/components/icon/assets/dollar-filled.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon/assets/gears.svg b/src/components/icon/assets/gears.svg new file mode 100644 index 000000000..1b0a1cba6 --- /dev/null +++ b/src/components/icon/assets/gears.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon/assets/info-filled-alt.svg b/src/components/icon/assets/info-filled-alt.svg index 8b3c32dcb..b400362c8 100644 --- a/src/components/icon/assets/info-filled-alt.svg +++ b/src/components/icon/assets/info-filled-alt.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/components/icon/assets/megaphone.svg b/src/components/icon/assets/megaphone.svg new file mode 100644 index 000000000..8168cae02 --- /dev/null +++ b/src/components/icon/assets/megaphone.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon/assets/reward.svg b/src/components/icon/assets/reward.svg new file mode 100644 index 000000000..9944278d0 --- /dev/null +++ b/src/components/icon/assets/reward.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon/assets/sound-off.svg b/src/components/icon/assets/sound-off.svg new file mode 100644 index 000000000..ac16abe53 --- /dev/null +++ b/src/components/icon/assets/sound-off.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon/assets/uptrend.svg b/src/components/icon/assets/uptrend.svg new file mode 100644 index 000000000..3e0be9f8a --- /dev/null +++ b/src/components/icon/assets/uptrend.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon/icon-name.enum.ts b/src/components/icon/icon-name.enum.ts index 5d568efd8..fdf15d201 100644 --- a/src/components/icon/icon-name.enum.ts +++ b/src/components/icon/icon-name.enum.ts @@ -177,5 +177,12 @@ export enum IconNameEnum { NoConnection = 'NoConnection', ScamInfo = 'ScamInfo', Stake = 'Stake', - MessageCircle = 'MessageCircle' + MessageCircle = 'MessageCircle', + DollarFiled = 'DollarFiled', + SoundOff = 'SoundOff', + Reward = 'Reward', + Uptrend = 'Uptrend', + Gears = 'Gears', + Megaphone = 'Megaphone', + Calendar = 'Calendar' } diff --git a/src/components/icon/icon-name.map.ts b/src/components/icon/icon-name.map.ts index 1ec78a75c..3569dadb8 100644 --- a/src/components/icon/icon-name.map.ts +++ b/src/components/icon/icon-name.map.ts @@ -22,6 +22,7 @@ import BrokenImage from './assets/broken-image.svg'; import BurnIcon from './assets/burn.svg'; import BuyWithCryptoIcon from './assets/buy-with-crypto.svg'; import BuyIcon from './assets/buy.svg'; +import CalendarIcon from './assets/calendar.svg'; import ChartIcon from './assets/chart-icon.svg'; import CheckCircleIcon from './assets/check-circle.svg'; import CheckIcon from './assets/check.svg'; @@ -54,6 +55,7 @@ import DetailsArrowRightIcon from './assets/details-arrow-right.svg'; import DetailsArrowUpIcon from './assets/details-arrow-up.svg'; import DiezIcon from './assets/diez.svg'; import DocsIcon from './assets/docs.svg'; +import DollarFilledIcon from './assets/dollar-filled.svg'; import DownloadCloudIcon from './assets/download-cloud.svg'; import DownloadIcon from './assets/download.svg'; import EarnDappIcon from './assets/earn-dapp.svg'; @@ -73,6 +75,7 @@ import GHighIcon from './assets/g-high.svg'; import GLowIcon from './assets/g-low.svg'; import GMidIcon from './assets/g-mid.svg'; import GearIcon from './assets/gear.svg'; +import GearsIcon from './assets/gears.svg'; import GlobeIcon from './assets/globe.svg'; import GoogleDriveNativeIcon from './assets/google-drive-native.svg'; import GoogleDriveIcon from './assets/google-drive.svg'; @@ -97,6 +100,7 @@ import LockIcon from './assets/lock.svg'; import LogOutIcon from './assets/log-out.svg'; import ManualBackupIcon from './assets/manual-backup.svg'; import MarketIcon from './assets/market.svg'; +import MegaphoneIcon from './assets/megaphone.svg'; import MessageCircleIcon from './assets/message-circle.svg'; import MinusIcon from './assets/minus-icon.svg'; import MissedEndorsementsIcon from './assets/missed-endorsements.svg'; @@ -124,6 +128,7 @@ import QuipuSwapDarkIcon from './assets/quipuswapDark.svg'; import RampIcon from './assets/ramp.svg'; import RefreshIcon from './assets/refresh-icon.svg'; import RetryIcon from './assets/retry.svg'; +import RewardIcon from './assets/reward.svg'; import ScamInfoIcon from './assets/scam-info.svg'; import SearchNewIcon from './assets/search-new.svg'; import SearchIcon from './assets/search.svg'; @@ -141,6 +146,7 @@ import TwitterIcon from './assets/socials/twitter.svg'; import WebsiteIcon from './assets/socials/website.svg'; import YouTubeIcon from './assets/socials/you-tube.svg'; import SoonBadgeIcon from './assets/soon-badge.svg'; +import SoundOffIcon from './assets/sound-off.svg'; import SpicyIcon from './assets/spicy.svg'; import StakeIcon from './assets/stake.svg'; import SuccessIcon from './assets/success.svg'; @@ -169,6 +175,7 @@ import TrashIcon from './assets/trash.svg'; import TriangleDownIcon from './assets/triangle-down.svg'; import UkraineIcon from './assets/ukraine.svg'; import UpdateIcon from './assets/update.svg'; +import UptrendIcon from './assets/uptrend.svg'; import UtorgIcon from './assets/utorg.svg'; import VortexIcon from './assets/vortex.svg'; import WTezIcon from './assets/wtez.svg'; @@ -254,6 +261,13 @@ export const iconNameMap: Record> = { [IconNameEnum.Website]: WebsiteIcon, [IconNameEnum.NFTCollection]: NFTCollectionIcon, [IconNameEnum.GoogleDrive]: GoogleDriveIcon, + [IconNameEnum.DollarFiled]: DollarFilledIcon, + [IconNameEnum.SoundOff]: SoundOffIcon, + [IconNameEnum.Reward]: RewardIcon, + [IconNameEnum.Gears]: GearsIcon, + [IconNameEnum.Calendar]: CalendarIcon, + [IconNameEnum.Uptrend]: UptrendIcon, + [IconNameEnum.Megaphone]: MegaphoneIcon, /** topup icons **/ [IconNameEnum.Exolix]: ExolixIcon, [IconNameEnum.MoonPay]: MoonPayIcon, diff --git a/src/components/lottie-animation/index.tsx b/src/components/lottie-animation/index.tsx new file mode 100644 index 000000000..5a4a1f099 --- /dev/null +++ b/src/components/lottie-animation/index.tsx @@ -0,0 +1,10 @@ +import LottieView, { AnimationObject, LottieViewProps } from 'lottie-react-native'; +import React, { memo } from 'react'; + +interface LottieAnimationProps extends Omit { + source: AnimationObject; +} + +export const LottieAnimation = memo(({ source, autoPlay = true, loop = true, ...props }) => ( + +)); diff --git a/src/hooks/use-rewards-address.hook.ts b/src/hooks/use-rewards-address.hook.ts new file mode 100644 index 000000000..e2da3e62f --- /dev/null +++ b/src/hooks/use-rewards-address.hook.ts @@ -0,0 +1,9 @@ +import { useMemo } from 'react'; + +import { useAccountsListSelector } from 'src/store/wallet/wallet-selectors'; + +export const useRewardsAddress = (): string | undefined => { + const accounts = useAccountsListSelector(); + + return useMemo(() => accounts.at(0)?.publicKeyHash, [accounts]); +}; diff --git a/src/hooks/use-tkey-rewards-stats.hook.ts b/src/hooks/use-tkey-rewards-stats.hook.ts new file mode 100644 index 000000000..0e17eca1c --- /dev/null +++ b/src/hooks/use-tkey-rewards-stats.hook.ts @@ -0,0 +1,35 @@ +import { BigNumber } from 'bignumber.js'; +import { useEffect, useMemo } from 'react'; +import { useDispatch } from 'react-redux'; + +import { loadTkeyRewardsStatsActions } from 'src/store/rewards/rewards-actions'; +import { useIsTkeyRewardsStatsLoadingSelector, useTkeyRewardsStatsSelector } from 'src/store/rewards/rewards-selectors'; +import { isDefined } from 'src/utils/is-defined.ts'; + +import { useRewardsAddress } from './use-rewards-address.hook'; + +export const useTkeyRewardsStats = () => { + const dispatch = useDispatch(); + const rewardsAddress = useRewardsAddress(); + const storedStats = useTkeyRewardsStatsSelector(); + const isLoading = useIsTkeyRewardsStatsLoadingSelector(); + + useEffect(() => { + if (rewardsAddress) { + dispatch(loadTkeyRewardsStatsActions.submit(rewardsAddress)); + } + }, [dispatch, rewardsAddress]); + + const stats = useMemo( + () => + storedStats + ? { + total: new BigNumber(storedStats.total), + lastAmount: isDefined(storedStats.lastAmount) ? new BigNumber(storedStats.lastAmount) : undefined + } + : undefined, + [storedStats] + ); + + return { isLoading, stats }; +}; diff --git a/src/mocks/lottie-react-native.mock.tsx b/src/mocks/lottie-react-native.mock.tsx new file mode 100644 index 000000000..f20f2993a --- /dev/null +++ b/src/mocks/lottie-react-native.mock.tsx @@ -0,0 +1,3 @@ +import { View } from 'react-native'; + +export default View; diff --git a/src/modals/promo-rewards-enable-modal/index.tsx b/src/modals/promo-rewards-enable-modal/index.tsx new file mode 100644 index 000000000..567b052bb --- /dev/null +++ b/src/modals/promo-rewards-enable-modal/index.tsx @@ -0,0 +1,67 @@ +import React, { FC, useCallback } from 'react'; +import { Text, View } from 'react-native'; +import { useDispatch } from 'react-redux'; + +import tkeyCoinAnimation from 'src/assets/animations/tkey-coin-animation.json'; +import { ButtonLargePrimary } from 'src/components/button/button-large/button-large-primary/button-large-primary'; +import { ButtonsFloatingContainer } from 'src/components/button/buttons-floating-container/buttons-floating-container'; +import { Icon } from 'src/components/icon/icon'; +import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { InsetSubstitute } from 'src/components/inset-substitute/inset-substitute'; +import { LottieAnimation } from 'src/components/lottie-animation'; +import { ModalStatusBar } from 'src/components/modal-status-bar/modal-status-bar'; +import { ScreenContainer } from 'src/components/screen-container/screen-container'; +import { useNavigation } from 'src/navigator/hooks/use-navigation.hook'; +import { togglePartnersPromotionAction } from 'src/store/partners-promotion/partners-promotion-actions'; +import { useIsPartnersPromoEnabledSelector } from 'src/store/partners-promotion/partners-promotion-selectors'; +import { formatSize } from 'src/styles/format-size'; +import { showSuccessToast } from 'src/toast/toast.utils'; + +import { usePromoRewardsEnableModalStyles } from './styles'; + +const benefits = [ + { iconName: IconNameEnum.Megaphone, text: 'Non-intrusive promo content' }, + { iconName: IconNameEnum.Calendar, text: 'Auto-payouts every month without claim' }, + { iconName: IconNameEnum.Uptrend, text: 'Boost with Temple Wallet extension' }, + { iconName: IconNameEnum.Gears, text: 'Turn feature on when it works for you' } +]; + +export const PromoRewardsEnableModal: FC = () => { + const dispatch = useDispatch(); + const { goBack } = useNavigation(); + const styles = usePromoRewardsEnableModalStyles(); + const isPromoEnabled = useIsPartnersPromoEnabledSelector(); + + const enablePromo = useCallback(() => { + dispatch(togglePartnersPromotionAction(true)); + showSuccessToast({ description: 'Promo rewards activated' }); + goBack(); + }, [dispatch, goBack]); + + return ( + <> + + + + + Receive share of{`\n`}20% promo rewards + + + {benefits.map(({ iconName, text }) => ( + + + {text} + + ))} + + + By enabling Promo, you agree to share your wallet address and IP to receive tokens and view ads. + + + + + + + + ); +}; diff --git a/src/modals/promo-rewards-enable-modal/styles.ts b/src/modals/promo-rewards-enable-modal/styles.ts new file mode 100644 index 000000000..61833c953 --- /dev/null +++ b/src/modals/promo-rewards-enable-modal/styles.ts @@ -0,0 +1,52 @@ +import { createUseStyles } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; + +export const usePromoRewardsEnableModalStyles = createUseStyles(({ colors, typography }) => ({ + content: { flexGrow: 1, paddingTop: formatSize(24) }, + animation: { + alignSelf: 'center', + width: formatSize(320), + height: formatSize(168) + }, + titleContainer: { paddingVertical: formatSize(12), width: '100%' }, + title: { + ...typography.body20Bold, + textTransform: 'none', + color: colors.black, + lineHeight: formatSize(25), + textAlign: 'center' + }, + benefits: { + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'space-between', + paddingTop: formatSize(16), + paddingBottom: formatSize(8) + }, + benefit: { + backgroundColor: colors.cardBG, + borderColor: colors.lines, + borderRadius: formatSize(8), + borderWidth: formatSize(0.5), + marginBottom: formatSize(8), + padding: formatSize(12), + width: '48.7%' + }, + benefitText: { + ...typography.caption11Regular, + color: colors.black, + lineHeight: formatSize(16), + marginTop: formatSize(4) + }, + agreement: { + ...typography.caption11Regular, + color: colors.gray1, + lineHeight: formatSize(13), + paddingHorizontal: formatSize(4), + paddingVertical: formatSize(12), + textAlign: 'center' + }, + buttonsContainer: { + paddingHorizontal: formatSize(16) + } +})); diff --git a/src/modals/rewards-announcement-modal/index.tsx b/src/modals/rewards-announcement-modal/index.tsx new file mode 100644 index 000000000..ad6c5e75f --- /dev/null +++ b/src/modals/rewards-announcement-modal/index.tsx @@ -0,0 +1,85 @@ +import { useIsFocused } from '@react-navigation/native'; +import React, { FC, useCallback, useEffect } from 'react'; +import { Text, TouchableOpacity, View } from 'react-native'; +import { useDispatch } from 'react-redux'; + +import tkeyCoinAnimation from 'src/assets/animations/tkey-coin-animation.json'; +import { ButtonLargePrimary } from 'src/components/button/button-large/button-large-primary/button-large-primary'; +import { ButtonsFloatingContainer } from 'src/components/button/buttons-floating-container/buttons-floating-container'; +import { Disclaimer } from 'src/components/disclaimer/disclaimer'; +import { Divider } from 'src/components/divider/divider'; +import { Icon } from 'src/components/icon/icon'; +import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { InsetSubstitute } from 'src/components/inset-substitute/inset-substitute'; +import { LottieAnimation } from 'src/components/lottie-animation'; +import { ModalStatusBar } from 'src/components/modal-status-bar/modal-status-bar'; +import { ScreenContainer } from 'src/components/screen-container/screen-container'; +import { ScreensEnum } from 'src/navigator/enums/screens.enum'; +import { useNavigation, useNavigateToScreen } from 'src/navigator/hooks/use-navigation.hook'; +import { setHasSeenRewardsAnnouncementAction } from 'src/store/rewards/rewards-actions'; +import { formatSize } from 'src/styles/format-size'; +import { AnalyticsEventCategory } from 'src/utils/analytics/analytics-event.enum'; +import { useAnalytics } from 'src/utils/analytics/use-analytics.hook'; + +import { useRewardsAnnouncementModalStyles } from './styles'; + +export const RewardsAnnouncementModal: FC = () => { + const dispatch = useDispatch(); + const { goBack } = useNavigation(); + const navigateToScreen = useNavigateToScreen(); + const { trackEvent } = useAnalytics(); + const isFocused = useIsFocused(); + const styles = useRewardsAnnouncementModalStyles(); + + useEffect(() => { + if (!isFocused) return; + dispatch(setHasSeenRewardsAnnouncementAction()); + void trackEvent('AdsEnabled', AnalyticsEventCategory.General); + }, [dispatch, isFocused, trackEvent]); + + const managePromo = useCallback( + () => navigateToScreen({ screen: ScreensEnum.AdvancedFeaturesSettings }), + [navigateToScreen] + ); + + return ( + <> + + + + + TKEY rewards for all + + We turned wallet usage into earning with Promo rewards and it’s now active in your wallet.{' '} + 20% revenue goes to you, no extra steps. + + + + + + Auto-payouts in TKEY every month. + + + + + Ad content runs quietly without interruption. + + + + + + Manage Promo + + + + + + + + ); +}; diff --git a/src/modals/rewards-announcement-modal/styles.ts b/src/modals/rewards-announcement-modal/styles.ts new file mode 100644 index 000000000..5de239a85 --- /dev/null +++ b/src/modals/rewards-announcement-modal/styles.ts @@ -0,0 +1,69 @@ +import { createUseStyles } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; + +export const useRewardsAnnouncementModalStyles = createUseStyles(({ colors, typography }) => ({ + content: { + flex: 1, + paddingVertical: formatSize(24), + paddingHorizontal: formatSize(24) + }, + animation: { + alignSelf: 'center', + width: formatSize(320), + height: formatSize(168), + marginBottom: formatSize(32) + }, + info: { + alignItems: 'center', + marginBottom: formatSize(16) + }, + title: { + ...typography.body20Bold, + textTransform: 'none', + color: colors.black, + textAlign: 'center', + marginBottom: formatSize(8) + }, + description: { + ...typography.caption13Regular, + color: colors.gray1, + lineHeight: formatSize(18), + textAlign: 'center' + }, + emphasizedDescription: { + ...typography.caption13Semibold + }, + benefits: { + flexDirection: 'row', + marginBottom: formatSize(8) + }, + benefit: { + flex: 1, + padding: formatSize(12), + borderWidth: formatSize(0.5), + borderColor: colors.lines, + borderRadius: formatSize(8), + backgroundColor: colors.cardBG + }, + benefitText: { + ...typography.caption11Regular, + color: colors.black, + marginTop: formatSize(4), + lineHeight: formatSize(16) + }, + managePromo: { + alignSelf: 'center', + flexDirection: 'row', + alignItems: 'center', + marginTop: formatSize(8), + padding: formatSize(10) + }, + managePromoText: { + ...typography.caption13Semibold, + color: colors.orange, + marginLeft: formatSize(4) + }, + buttonsContainer: { + paddingHorizontal: formatSize(16) + } +})); diff --git a/src/navigator/enums/modals.enum.ts b/src/navigator/enums/modals.enum.ts index d41030662..aada3e935 100644 --- a/src/navigator/enums/modals.enum.ts +++ b/src/navigator/enums/modals.enum.ts @@ -32,6 +32,8 @@ export enum ModalsEnum { ImportAccountFromPrivateKey = 'ImportAccountFromPrivateKey', KoloCard = 'KoloCard', ShieldedAnnouncement = 'ShieldedAnnouncement', + PromoRewardsEnable = 'PromoRewardsEnable', + RewardsAnnouncement = 'RewardsAnnouncement', Rebalance = 'Rebalance' } @@ -64,6 +66,8 @@ export type ModalsParamList = { [ModalsEnum.ImportAccountFromPrivateKey]: undefined; [ModalsEnum.KoloCard]: undefined; [ModalsEnum.ShieldedAnnouncement]: undefined; + [ModalsEnum.PromoRewardsEnable]: undefined; + [ModalsEnum.RewardsAnnouncement]: undefined; [ModalsEnum.Rebalance]: undefined; }; @@ -100,4 +104,6 @@ export type ModalParams = | ModalParamsPart | ModalParamsPart | ModalParamsPart + | ModalParamsPart + | ModalParamsPart | ModalParamsPart; diff --git a/src/navigator/root-stack.tsx b/src/navigator/root-stack.tsx index b586cb7c2..b131fea15 100644 --- a/src/navigator/root-stack.tsx +++ b/src/navigator/root-stack.tsx @@ -26,11 +26,13 @@ import { InAppBrowser } from 'src/modals/in-app-browser'; import { KoloCardWidgetModal } from 'src/modals/kolo-card'; import { ManageEarnOpportunityModal } from 'src/modals/manage-earn-opportunity-modal'; import { Newsletter } from 'src/modals/newsletter/newsletter-modal'; +import { PromoRewardsEnableModal } from 'src/modals/promo-rewards-enable-modal'; import { RebalanceModal } from 'src/modals/rebalance-modal/rebalance-modal'; import { ReceiveModal } from 'src/modals/receive-modal/receive-modal'; import { RenameAccountModal } from 'src/modals/rename-account-modal/rename-account-modal'; import { RevealPrivateKeyModal } from 'src/modals/reveal-private-key-modal/reveal-private-key-modal'; import { RevealSeedPhraseModal } from 'src/modals/reveal-seed-phrase-modal/reveal-seed-phrase-modal'; +import { RewardsAnnouncementModal } from 'src/modals/rewards-announcement-modal'; import { SelectBakerModal } from 'src/modals/select-baker-modal/select-baker-modal'; import { SendModal } from 'src/modals/send-modal/send-modal'; import { ShieldedAnnouncementModal } from 'src/modals/shielded-announcement-modal/shielded-announcement-modal'; @@ -218,6 +220,16 @@ export const RootStackScreen = () => { component={RebalanceModal} options={useModalOptions('Rebalance')} /> + + { @@ -45,6 +46,7 @@ export const Earn: FC = () => { return ( <> + { + const styles = usePromoRewardsCardStyles(); + const isPromoEnabled = useIsPartnersPromoEnabledSelector(); + const navigateToModal = useNavigateToModal(); + const { isLoading, stats } = useTkeyRewardsStats(); + + const openEnableModal = useCallback(() => navigateToModal(ModalsEnum.PromoRewardsEnable), [navigateToModal]); + + if (!isPromoEnabled) { + return ( + + + + + + Promo rewards + + + + Earn TKEY token through built-in promo feature and claim your slice of 20% monthly rewards. + + + + Up to 511 TKEY / month + + + + ); + } + + return ( + + + + + + Promo rewards + {(!stats || stats.total.isZero()) && ( + + + + )} + + {isLoading ? ( + + + + ) : ( + + + All time: + {formatAssetAmount(stats?.total ?? ZERO, 2)} TKEY + + + Last payment: + +{formatAssetAmount(stats?.lastAmount ?? ZERO, 2)} TKEY + + + )} + + + + ); +}); + +interface PromoRewardsCardFrameProps extends PropsWithChildren { + reversed?: boolean; +} + +const PromoRewardsCardFrame: FC = ({ children, reversed = false }) => { + const styles = usePromoRewardsCardStyles(); + + return ( + + + + + + + + + + + {children} + + ); +}; + +const showPayoutInfo = () => + Alert.alert( + 'Promo rewards', + 'This section display display your rewards for Promo. You can manage this feature in the Settings.' + ); diff --git a/src/screens/earn/promo-rewards-card/styles.ts b/src/screens/earn/promo-rewards-card/styles.ts new file mode 100644 index 000000000..413fb7ed6 --- /dev/null +++ b/src/screens/earn/promo-rewards-card/styles.ts @@ -0,0 +1,36 @@ +import { black } from 'src/config/styles'; +import { createUseStylesMemoized } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; +import { generateShadow } from 'src/styles/generate-shadow'; + +export const usePromoRewardsCardStyles = createUseStylesMemoized(({ colors, typography }) => ({ + root: { + ...generateShadow(1, black), + marginHorizontal: formatSize(16), + marginVertical: formatSize(8), + borderRadius: formatSize(8), + overflow: 'hidden' + }, + card: { + backgroundColor: colors.cardBG + }, + borderGradient: { position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, zIndex: 1 }, + content: { padding: formatSize(16) }, + titleRow: { flexDirection: 'row', alignItems: 'center' }, + title: { ...typography.body15Semibold, color: colors.black, flex: 1, marginLeft: formatSize(8) }, + description: { + ...typography.caption11Regular, + color: colors.gray1, + marginTop: formatSize(12), + lineHeight: formatSize(13) + }, + introFooter: { alignItems: 'center', paddingVertical: formatSize(12), backgroundColor: colors.peach10 }, + introFooterText: { ...typography.caption13Semibold, color: colors.orange }, + stats: { flexDirection: 'row', justifyContent: 'space-between', marginTop: formatSize(12), height: formatSize(36) }, + stat: { flex: 1 }, + statEnd: { alignItems: 'flex-end' }, + label: { ...typography.caption11Regular, color: colors.gray1 }, + value: { ...typography.numbersRegular17, color: colors.black, marginTop: formatSize(2) }, + positiveValue: { ...typography.numbersRegular17, color: colors.adding, marginTop: formatSize(2) }, + loader: { justifyContent: 'center', alignItems: 'center', marginTop: formatSize(12), height: formatSize(36) } +})); diff --git a/src/screens/earn/selectors.ts b/src/screens/earn/selectors.ts index c8be6490d..96af48558 100644 --- a/src/screens/earn/selectors.ts +++ b/src/screens/earn/selectors.ts @@ -1,4 +1,5 @@ export enum EarnPageSelectors { + PromoRewardsCard = 'Earn page/Promo rewards card', FarmingCard = 'Earn page/Farming card', SavingsCard = 'Earn page/Savings card' } diff --git a/src/screens/wallet/wallet.tsx b/src/screens/wallet/wallet.tsx index 2e8e4e7a3..db31343b7 100644 --- a/src/screens/wallet/wallet.tsx +++ b/src/screens/wallet/wallet.tsx @@ -26,7 +26,8 @@ import { useIgnoredAddressesSelector } from 'src/store/contact-book/contact-book-selectors'; import { useShouldShowNewsletterModalSelector } from 'src/store/newsletter/newsletter-selectors'; -import { useHasSeenAnnouncementSelector } from 'src/store/sapling'; +import { useHasSeenRewardsAnnouncementSelector } from 'src/store/rewards/rewards-selectors'; +import { useHasSeenSaplingAnnouncementSelector } from 'src/store/sapling'; import { setKoloCardAnimationShownAction, walletOpenedAction } from 'src/store/settings/settings-actions'; import { useIsAnyBackupMadeSelector, useIsKoloCardAnimationShownSelector } from 'src/store/settings/settings-selectors'; import { useAccountsListSelector } from 'src/store/wallet/wallet-selectors'; @@ -56,7 +57,8 @@ export const Wallet = memo(() => { const contactsAddresses = useContactsAddresses(); const bottomSheetController = useBottomSheetController(); const shouldShowNewsletterModal = useShouldShowNewsletterModalSelector(); - const hasSeenAnnouncement = useHasSeenAnnouncementSelector(); + const hasSeenSaplingAnnouncement = useHasSeenSaplingAnnouncementSelector(); + const hasSeenRewardsAnnouncement = useHasSeenRewardsAnnouncementSelector(); const isKoloCardAnimationShown = useIsKoloCardAnimationShownSelector(); const handleKoloCardAnimationComplete = useCallback(() => { @@ -92,10 +94,16 @@ export const Wallet = memo(() => { }, [shouldShowNewsletterModal, isAnyBackupMade]); useEffect(() => { - if (!hasSeenAnnouncement) { + if (!hasSeenSaplingAnnouncement) { navigateToModal(ModalsEnum.ShieldedAnnouncement); } - }, [hasSeenAnnouncement]); + }, [hasSeenSaplingAnnouncement]); + + useEffect(() => { + if (hasSeenSaplingAnnouncement && !hasSeenRewardsAnnouncement) { + navigateToModal(ModalsEnum.RewardsAnnouncement); + } + }, [hasSeenSaplingAnnouncement, hasSeenRewardsAnnouncement, navigateToModal]); const trackPageOpened = useCallback(() => { pageEvent(ScreensEnum.Wallet, ''); diff --git a/src/store/index.ts b/src/store/index.ts index d9b96d053..20bf62b81 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -12,6 +12,7 @@ import { exolixEpics } from './exolix/exolix-epics'; import { farmsEpics } from './farms/epics'; import { marketEpics } from './market/market-epics'; import { notificationsEpics } from './notifications/notifications-epics'; +import { rewardsEpics } from './rewards/rewards-epics'; import { rootStateEpics } from './root-state.epics'; import { saplingEpics } from './sapling'; import { savingsEpics } from './savings/epics'; @@ -23,6 +24,7 @@ import { walletEpics } from './wallet/wallet-epics'; export const { store, persistor } = createStore( rootStateEpics, + rewardsEpics, walletEpics, tokensMetadataEpics, bakingEpics, diff --git a/src/store/migrations.ts b/src/store/migrations.ts index 73413e08c..72e94e82e 100644 --- a/src/store/migrations.ts +++ b/src/store/migrations.ts @@ -12,6 +12,7 @@ import { isDefined } from 'src/utils/is-defined'; import { DCP_RPC, MARIGOLD_RPC, OLD_TEMPLE_RPC_URLS, TEMPLE_RPC } from 'src/utils/rpc/rpc-list'; import { createEntity } from './create-entity'; +import { rewardsInitialState } from './rewards/rewards-state'; import type { RootState } from './types'; type TypedPersistedRootState = Exclude & RootState; @@ -188,6 +189,23 @@ export const MIGRATIONS: MigrationManifest = { state.settings.isInAppBrowserEnabled = true; } + return state; + }, + '9': (untypedState: PersistedState): undefined | TypedPersistedRootState => { + if (!untypedState) { + return untypedState; + } + + const state = untypedState as TypedPersistedRootState; + state.partnersPromotion = { + ...state.partnersPromotion, + isEnabled: true + }; + state.rewards = { + ...rewardsInitialState, + hasSeenRewardsAnnouncement: false + }; + return state; } }; diff --git a/src/store/rewards/rewards-actions.ts b/src/store/rewards/rewards-actions.ts new file mode 100644 index 000000000..3e41d67f5 --- /dev/null +++ b/src/store/rewards/rewards-actions.ts @@ -0,0 +1,11 @@ +import { createAction } from '@reduxjs/toolkit'; + +import { createActions } from '../create-actions'; + +import { TkeyRewardsStats } from './rewards-state'; + +export const loadTkeyRewardsStatsActions = createActions( + 'rewards/LOAD_TKEY_REWARDS_STATS' +); + +export const setHasSeenRewardsAnnouncementAction = createAction('rewards/SET_HAS_SEEN_REWARDS_ANNOUNCEMENT'); diff --git a/src/store/rewards/rewards-epics.ts b/src/store/rewards/rewards-epics.ts new file mode 100644 index 000000000..b41032535 --- /dev/null +++ b/src/store/rewards/rewards-epics.ts @@ -0,0 +1,66 @@ +import { BigNumber } from 'bignumber.js'; +import { combineEpics } from 'redux-observable'; +import { from, of } from 'rxjs'; +import { catchError, map, switchMap, withLatestFrom } from 'rxjs/operators'; +import { ofType, toPayload } from 'ts-action-operators'; + +import { tzktApi } from 'src/api.service'; +import { TzktTokenTransfer } from 'src/interfaces/tzkt/token-transfer.interface'; +import type { AnyActionEpic } from 'src/store/types'; +import { TEMPLE_TOKEN_METADATA } from 'src/token/data/tokens-metadata'; +import { ZERO } from 'src/utils/number.util'; +import { mutezToTz } from 'src/utils/tezos.util'; + +import { loadTkeyRewardsStatsActions } from './rewards-actions'; + +const TEMPLE_REWARDS_PAYOUT_ADDRESS = 'tz1N7mkPWedKcMPHt9tgiA4SstDHS4L6LKKQ'; +const TZKT_MAX_QUERY_ITEMS_LIMIT = 10_000; + +const loadTkeyRewardsStatsEpic: AnyActionEpic = (action$, state$) => + action$.pipe( + ofType(loadTkeyRewardsStatsActions.submit), + toPayload(), + withLatestFrom(state$), + switchMap(([rewardsAddress, state]) => { + const currentStats = state.rewards.tkeyStats.data; + + return from( + tzktApi.get('/tokens/transfers', { + params: { + 'sort.desc': 'id', + to: rewardsAddress, + from: TEMPLE_REWARDS_PAYOUT_ADDRESS, + limit: TZKT_MAX_QUERY_ITEMS_LIMIT, + 'token.contract': TEMPLE_TOKEN_METADATA.address, + 'token.tokenId': TEMPLE_TOKEN_METADATA.id, + ...(currentStats?.lastTransferTs ? { 'timestamp.gt': currentStats.lastTransferTs } : {}) + } + }) + ).pipe( + map(({ data: transfers }) => { + const total = mutezToTz( + transfers.reduce((sum, transfer) => sum.plus(transfer.amount), ZERO), + TEMPLE_TOKEN_METADATA.decimals + ) + .plus(currentStats?.total ?? ZERO) + .toFixed(); + const lastAmount = transfers[0] + ? mutezToTz(new BigNumber(transfers[0].amount), TEMPLE_TOKEN_METADATA.decimals).toFixed() + : currentStats?.lastAmount; + + return loadTkeyRewardsStatsActions.success({ + total, + lastAmount, + lastTransferTs: transfers[0]?.timestamp ?? currentStats?.lastTransferTs + }); + }), + catchError(error => { + console.error('Failed to load TKEY rewards stats:', error); + + return of(loadTkeyRewardsStatsActions.fail(error.message)); + }) + ); + }) + ); + +export const rewardsEpics = combineEpics(loadTkeyRewardsStatsEpic); diff --git a/src/store/rewards/rewards-reducers.ts b/src/store/rewards/rewards-reducers.ts new file mode 100644 index 000000000..82d74ccc7 --- /dev/null +++ b/src/store/rewards/rewards-reducers.ts @@ -0,0 +1,21 @@ +import { createReducer } from '@reduxjs/toolkit'; + +import { createEntity } from '../create-entity'; + +import { loadTkeyRewardsStatsActions, setHasSeenRewardsAnnouncementAction } from './rewards-actions'; +import { rewardsInitialState, RewardsState } from './rewards-state'; + +export const rewardsReducer = createReducer(rewardsInitialState, builder => { + builder.addCase(loadTkeyRewardsStatsActions.submit, state => { + state.tkeyStats = createEntity(state.tkeyStats.data, true); + }); + builder.addCase(loadTkeyRewardsStatsActions.success, (state, { payload: stats }) => { + state.tkeyStats = createEntity(stats, false); + }); + builder.addCase(loadTkeyRewardsStatsActions.fail, (state, { payload: error }) => { + state.tkeyStats = createEntity(state.tkeyStats.data, false, error); + }); + builder.addCase(setHasSeenRewardsAnnouncementAction, state => { + state.hasSeenRewardsAnnouncement = true; + }); +}); diff --git a/src/store/rewards/rewards-selectors.ts b/src/store/rewards/rewards-selectors.ts new file mode 100644 index 000000000..df96904be --- /dev/null +++ b/src/store/rewards/rewards-selectors.ts @@ -0,0 +1,8 @@ +import { useSelector } from '../selector'; + +export const useTkeyRewardsStatsSelector = () => useSelector(state => state.rewards.tkeyStats.data); + +export const useIsTkeyRewardsStatsLoadingSelector = () => useSelector(state => state.rewards.tkeyStats.isLoading); + +export const useHasSeenRewardsAnnouncementSelector = () => + useSelector(state => state.rewards.hasSeenRewardsAnnouncement); diff --git a/src/store/rewards/rewards-state.ts b/src/store/rewards/rewards-state.ts new file mode 100644 index 000000000..fb3649e06 --- /dev/null +++ b/src/store/rewards/rewards-state.ts @@ -0,0 +1,18 @@ +import { createEntity } from '../create-entity.ts'; +import { LoadableEntityState } from '../types'; + +export interface TkeyRewardsStats { + lastAmount?: string; + lastTransferTs?: string; + total: string; +} + +export interface RewardsState { + hasSeenRewardsAnnouncement: boolean; + tkeyStats: LoadableEntityState; +} + +export const rewardsInitialState: RewardsState = { + hasSeenRewardsAnnouncement: true, + tkeyStats: createEntity(null) +}; diff --git a/src/store/root-state.map.ts b/src/store/root-state.map.ts index cf4a4b7fe..586e9363f 100644 --- a/src/store/root-state.map.ts +++ b/src/store/root-state.map.ts @@ -13,6 +13,7 @@ import { marketReducers } from './market/market-reducers'; import { newsletterReducers } from './newsletter/newsletter-reducers'; import { notificationsReducers } from './notifications/notifications-reducers'; import { partnersPromotionReducers } from './partners-promotion/partners-promotion-reducers'; +import { rewardsReducer } from './rewards/rewards-reducers'; import { saplingReducers } from './sapling/sapling-reducers'; import { savingsReducer } from './savings/reducers'; import { securityReducers } from './security/security-reducers'; @@ -37,6 +38,7 @@ export const rootStateReducersMap = { contactBook: contactBookReducers, buyWithCreditCard: buyWithCreditCardReducer, partnersPromotion: partnersPromotionReducers, + rewards: rewardsReducer, abTesting: abTestingReducer, farms: farmsReducer, savings: savingsReducer, diff --git a/src/store/root-state.mock.ts b/src/store/root-state.mock.ts index 5bcb2f0c9..10c7b685c 100644 --- a/src/store/root-state.mock.ts +++ b/src/store/root-state.mock.ts @@ -13,6 +13,7 @@ import { mockMarketState } from './market/market-state.mock'; import { mockNewsletterState } from './newsletter/newsletter-state.mock'; import { mockNotificationsState } from './notifications/notifications-state.mock'; import { mockPartnersPromotionState } from './partners-promotion/partners-promotion-state.mock'; +import { rewardsInitialState } from './rewards/rewards-state'; import { saplingInitialState } from './sapling/sapling-state'; import { mockSavingsState } from './savings/state.mock'; import { mockSecurityState } from './security/security-state.mock'; @@ -39,6 +40,7 @@ export const mockRootState: RootState = { collections: collectionsMockState, buyWithCreditCard: mockBuyWithCreditCardState, partnersPromotion: mockPartnersPromotionState, + rewards: rewardsInitialState, abTesting: mockABTestingState, collectibles: mockCollectiblesState, farms: mockFarmsState, diff --git a/src/store/root-state.reducers.ts b/src/store/root-state.reducers.ts index 0b4b2e4b2..92d19f8bd 100644 --- a/src/store/root-state.reducers.ts +++ b/src/store/root-state.reducers.ts @@ -45,7 +45,7 @@ const persistConfigBlacklist: (keyof RootState)[] = [ const persistConfig: PersistConfig = { key: 'root', - version: 8, + version: 9, storage: SlicedAsyncStorage, stateReconciler: autoMergeLevel2, writeFailHandler: persistFailHandler, diff --git a/src/store/sapling/index.ts b/src/store/sapling/index.ts index 7e2d082c8..eced5ea27 100644 --- a/src/store/sapling/index.ts +++ b/src/store/sapling/index.ts @@ -4,7 +4,7 @@ export { useShieldedBalanceSelector, useIsSaplingCredentialsLoadedSelector, useIsSaplingBalanceLoadingSelector, - useHasSeenAnnouncementSelector, + useHasSeenSaplingAnnouncementSelector, useSaplingTransactionHistorySelector, useIsSaplingHistoryLoadingSelector, useIsSaplingPreparingSelector, diff --git a/src/store/sapling/sapling-selectors.ts b/src/store/sapling/sapling-selectors.ts index 2aaba52a0..5b0afc180 100644 --- a/src/store/sapling/sapling-selectors.ts +++ b/src/store/sapling/sapling-selectors.ts @@ -15,6 +15,6 @@ export const useIsSaplingCredentialsLoadedSelector = () => useSaplingAccountStat export const useIsSaplingBalanceLoadingSelector = () => useSaplingAccountState().isBalanceLoading; export const useSaplingTransactionHistorySelector = () => useSaplingAccountState().transactionHistory; export const useIsSaplingHistoryLoadingSelector = () => useSaplingAccountState().isHistoryLoading; -export const useHasSeenAnnouncementSelector = () => useSelector(({ sapling }) => sapling.hasSeenAnnouncement); +export const useHasSeenSaplingAnnouncementSelector = () => useSelector(({ sapling }) => sapling.hasSeenAnnouncement); export const useIsSaplingPreparingSelector = () => useSelector(({ sapling }) => sapling.isPreparing); export const usePreparedOpParamsSelector = () => useSelector(({ sapling }) => sapling.preparedOpParams); diff --git a/yarn.lock b/yarn.lock index ea8216641..bd5bca716 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11519,6 +11519,23 @@ __metadata: languageName: node linkType: hard +"lottie-react-native@npm:7.3.8": + version: 7.3.8 + resolution: "lottie-react-native@npm:7.3.8" + peerDependencies: + "@lottiefiles/dotlottie-react": ^0.13.5 + react: "*" + react-native: ">=0.46" + react-native-windows: ">=0.63.x" + peerDependenciesMeta: + "@lottiefiles/dotlottie-react": + optional: true + react-native-windows: + optional: true + checksum: 10c0/19cb5561a4d75d3bc2e2d2e09e328802c96e7724bd4804383331162cc7e3d584c5f45a90dbd5909e3fe93a294dd50f4a0ff517e1ab8450213b789a64f814440d + languageName: node + linkType: hard + "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -15408,6 +15425,7 @@ __metadata: jest-date-mock: "npm:^1.0.10" knip: "npm:^5.81.0" lodash-es: "npm:^4.18.1" + lottie-react-native: "npm:7.3.8" memoizee: "npm:^0.4.15" node-forge: "npm:^1.3.2" node-libs-react-native: "npm:^1.2.1"