0) {
+ println "android.packagingOptions.$prop += $options ($options.length)"
+ // Ex: android.packagingOptions.pickFirsts += '**/SCCS/**'
+ options.each {
+ android.packagingOptions[prop] += it
+ }
+ }
+}
+
+dependencies {
+ // The version of react-native is set by the React Native Gradle Plugin
+ implementation("com.facebook.react:react-android")
+ // implementation(':react-native-gesture-handler:')
+ def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true";
+ def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true";
+ def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true";
+ def frescoVersion = rootProject.ext.frescoVersion
+
+ // If your app supports Android versions before Ice Cream Sandwich (API level 14)
+ if (isGifEnabled || isWebpEnabled) {
+ implementation("com.facebook.fresco:fresco:${frescoVersion}")
+ implementation("com.facebook.fresco:imagepipeline-okhttp3:${frescoVersion}")
+ }
+
+ if (isGifEnabled) {
+ // For animated gif support
+ implementation("com.facebook.fresco:animated-gif:${frescoVersion}")
+ }
+
+ if (isWebpEnabled) {
+ // For webp support
+ implementation("com.facebook.fresco:webpsupport:${frescoVersion}")
+ if (isWebpAnimatedEnabled) {
+ // Animated webp support
+ implementation("com.facebook.fresco:animated-webp:${frescoVersion}")
+ }
+ }
+
+ implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
+
+ debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
+ debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
+ exclude group:'com.squareup.okhttp3', module:'okhttp'
+ }
+ debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
+
+ if (hermesEnabled.toBoolean()) {
+ implementation("com.facebook.react:hermes-android")
+ } else {
+ implementation jscFlavor
+ }
+}
+
+apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
+applyNativeModulesAppBuildGradle(project)
diff --git a/NFTVerse/MobileApp/android/app/debug.keystore b/NFTVerse/MobileApp/android/app/debug.keystore
new file mode 100644
index 00000000..364e105e
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/debug.keystore differ
diff --git a/NFTVerse/MobileApp/android/app/proguard-rules.pro b/NFTVerse/MobileApp/android/app/proguard-rules.pro
new file mode 100644
index 00000000..551eb41d
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/proguard-rules.pro
@@ -0,0 +1,14 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# react-native-reanimated
+-keep class com.swmansion.reanimated.** { *; }
+-keep class com.facebook.react.turbomodule.** { *; }
+
+# Add any project specific keep options here:
diff --git a/NFTVerse/MobileApp/android/app/src/debug/AndroidManifest.xml b/NFTVerse/MobileApp/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 00000000..99e38fc5
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
diff --git a/NFTVerse/MobileApp/android/app/src/debug/java/com/cricktales/nftverse/ReactNativeFlipper.java b/NFTVerse/MobileApp/android/app/src/debug/java/com/cricktales/nftverse/ReactNativeFlipper.java
new file mode 100644
index 00000000..a81e27f2
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/debug/java/com/cricktales/nftverse/ReactNativeFlipper.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the LICENSE file in the root
+ * directory of this source tree.
+ */
+package com.cricktales.nftverse;
+
+import android.content.Context;
+import com.facebook.flipper.android.AndroidFlipperClient;
+import com.facebook.flipper.android.utils.FlipperUtils;
+import com.facebook.flipper.core.FlipperClient;
+import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
+import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
+import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
+import com.facebook.flipper.plugins.inspector.DescriptorMapping;
+import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
+import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
+import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
+import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
+import com.facebook.react.ReactInstanceEventListener;
+import com.facebook.react.ReactInstanceManager;
+import com.facebook.react.bridge.ReactContext;
+import com.facebook.react.modules.network.NetworkingModule;
+import okhttp3.OkHttpClient;
+
+/**
+ * Class responsible of loading Flipper inside your React Native application. This is the debug
+ * flavor of it. Here you can add your own plugins and customize the Flipper setup.
+ */
+public class ReactNativeFlipper {
+ public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
+ if (FlipperUtils.shouldEnableFlipper(context)) {
+ final FlipperClient client = AndroidFlipperClient.getInstance(context);
+
+ client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
+ client.addPlugin(new DatabasesFlipperPlugin(context));
+ client.addPlugin(new SharedPreferencesFlipperPlugin(context));
+ client.addPlugin(CrashReporterPlugin.getInstance());
+
+ NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
+ NetworkingModule.setCustomClientBuilder(
+ new NetworkingModule.CustomClientBuilder() {
+ @Override
+ public void apply(OkHttpClient.Builder builder) {
+ builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
+ }
+ });
+ client.addPlugin(networkFlipperPlugin);
+ client.start();
+
+ // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
+ // Hence we run if after all native modules have been initialized
+ ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
+ if (reactContext == null) {
+ reactInstanceManager.addReactInstanceEventListener(
+ new ReactInstanceEventListener() {
+ @Override
+ public void onReactContextInitialized(ReactContext reactContext) {
+ reactInstanceManager.removeReactInstanceEventListener(this);
+ reactContext.runOnNativeModulesQueueThread(
+ new Runnable() {
+ @Override
+ public void run() {
+ client.addPlugin(new FrescoFlipperPlugin());
+ }
+ });
+ }
+ });
+ } else {
+ client.addPlugin(new FrescoFlipperPlugin());
+ }
+ }
+ }
+}
diff --git a/NFTVerse/MobileApp/android/app/src/main/AndroidManifest.xml b/NFTVerse/MobileApp/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..0d104485
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/android/app/src/main/java/com/cricktales/nftverse/MainActivity.java b/NFTVerse/MobileApp/android/app/src/main/java/com/cricktales/nftverse/MainActivity.java
new file mode 100644
index 00000000..163525f0
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/java/com/cricktales/nftverse/MainActivity.java
@@ -0,0 +1,68 @@
+package com.cricktales.nftverse;
+
+import android.os.Build;
+import android.os.Bundle;
+
+import com.facebook.react.ReactActivity;
+import com.facebook.react.ReactActivityDelegate;
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
+import com.facebook.react.defaults.DefaultReactActivityDelegate;
+
+import expo.modules.ReactActivityDelegateWrapper;
+
+public class MainActivity extends ReactActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ // Set the theme to AppTheme BEFORE onCreate to support
+ // coloring the background, status bar, and navigation bar.
+ // This is required for expo-splash-screen.
+ setTheme(R.style.AppTheme);
+ super.onCreate(null);
+ }
+
+ /**
+ * Returns the name of the main component registered from JavaScript.
+ * This is used to schedule rendering of the component.
+ */
+ @Override
+ protected String getMainComponentName() {
+ return "main";
+ }
+
+ /**
+ * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
+ * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
+ * (aka React 18) with two boolean flags.
+ */
+ @Override
+ protected ReactActivityDelegate createReactActivityDelegate() {
+ return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate(
+ this,
+ getMainComponentName(),
+ // If you opted-in for the New Architecture, we enable the Fabric Renderer.
+ DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
+ // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
+ DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
+ ));
+ }
+
+ /**
+ * Align the back button behavior with Android S
+ * where moving root activities to background instead of finishing activities.
+ * @see onBackPressed
+ */
+ @Override
+ public void invokeDefaultOnBackPressed() {
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
+ if (!moveTaskToBack(false)) {
+ // For non-root activities, use the default implementation to finish them.
+ super.invokeDefaultOnBackPressed();
+ }
+ return;
+ }
+
+ // Use the default back button implementation on Android S
+ // because it's doing more than {@link Activity#moveTaskToBack} in fact.
+ super.invokeDefaultOnBackPressed();
+ }
+}
diff --git a/NFTVerse/MobileApp/android/app/src/main/java/com/cricktales/nftverse/MainApplication.java b/NFTVerse/MobileApp/android/app/src/main/java/com/cricktales/nftverse/MainApplication.java
new file mode 100644
index 00000000..812cc9e8
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/java/com/cricktales/nftverse/MainApplication.java
@@ -0,0 +1,76 @@
+package com.cricktales.nftverse;
+
+import android.app.Application;
+import android.content.res.Configuration;
+import androidx.annotation.NonNull;
+
+import com.facebook.react.PackageList;
+import com.facebook.react.ReactApplication;
+import com.facebook.react.ReactNativeHost;
+import com.facebook.react.ReactPackage;
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
+import com.facebook.react.defaults.DefaultReactNativeHost;
+import com.facebook.soloader.SoLoader;
+
+import expo.modules.ApplicationLifecycleDispatcher;
+import expo.modules.ReactNativeHostWrapper;
+
+import java.util.List;
+
+public class MainApplication extends Application implements ReactApplication {
+
+ private final ReactNativeHost mReactNativeHost =
+ new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) {
+ @Override
+ public boolean getUseDeveloperSupport() {
+ return BuildConfig.DEBUG;
+ }
+
+ @Override
+ protected List getPackages() {
+ @SuppressWarnings("UnnecessaryLocalVariable")
+ List packages = new PackageList(this).getPackages();
+ // Packages that cannot be autolinked yet can be added manually here, for example:
+ // packages.add(new MyReactNativePackage());
+ return packages;
+ }
+
+ @Override
+ protected String getJSMainModuleName() {
+ return "index";
+ }
+
+ @Override
+ protected boolean isNewArchEnabled() {
+ return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
+ }
+
+ @Override
+ protected Boolean isHermesEnabled() {
+ return BuildConfig.IS_HERMES_ENABLED;
+ }
+ });
+
+ @Override
+ public ReactNativeHost getReactNativeHost() {
+ return mReactNativeHost;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ SoLoader.init(this, /* native exopackage */ false);
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ // If you opted-in for the New Architecture, we load the native entry point for this app.
+ DefaultNewArchitectureEntryPoint.load();
+ }
+ ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
+ ApplicationLifecycleDispatcher.onApplicationCreate(this);
+ }
+
+ @Override
+ public void onConfigurationChanged(@NonNull Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
+ }
+}
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/drawable-hdpi/splashscreen_image.png b/NFTVerse/MobileApp/android/app/src/main/res/drawable-hdpi/splashscreen_image.png
new file mode 100644
index 00000000..97f69d1f
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/drawable-hdpi/splashscreen_image.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/drawable-mdpi/splashscreen_image.png b/NFTVerse/MobileApp/android/app/src/main/res/drawable-mdpi/splashscreen_image.png
new file mode 100644
index 00000000..97f69d1f
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/drawable-mdpi/splashscreen_image.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png b/NFTVerse/MobileApp/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png
new file mode 100644
index 00000000..97f69d1f
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png b/NFTVerse/MobileApp/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png
new file mode 100644
index 00000000..97f69d1f
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png b/NFTVerse/MobileApp/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png
new file mode 100644
index 00000000..97f69d1f
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/drawable/rn_edit_text_material.xml b/NFTVerse/MobileApp/android/app/src/main/res/drawable/rn_edit_text_material.xml
new file mode 100644
index 00000000..f35d9962
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/res/drawable/rn_edit_text_material.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/drawable/splashscreen.xml b/NFTVerse/MobileApp/android/app/src/main/res/drawable/splashscreen.xml
new file mode 100644
index 00000000..c8568e16
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/res/drawable/splashscreen.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 00000000..3941bea9
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_foreground.xml b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_foreground.xml
new file mode 100644
index 00000000..3941bea9
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_foreground.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 00000000..3941bea9
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/values-night/colors.xml b/NFTVerse/MobileApp/android/app/src/main/res/values-night/colors.xml
new file mode 100644
index 00000000..3c05de5b
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/res/values-night/colors.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/values/colors.xml b/NFTVerse/MobileApp/android/app/src/main/res/values/colors.xml
new file mode 100644
index 00000000..f387b901
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+ #ffffff
+ #ffffff
+ #023c69
+ #ffffff
+
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/values/strings.xml b/NFTVerse/MobileApp/android/app/src/main/res/values/strings.xml
new file mode 100644
index 00000000..aea09460
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/res/values/strings.xml
@@ -0,0 +1,5 @@
+
+ Crick Tales
+ contain
+ false
+
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/android/app/src/main/res/values/styles.xml b/NFTVerse/MobileApp/android/app/src/main/res/values/styles.xml
new file mode 100644
index 00000000..f03e23f8
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/android/app/src/release/java/com/cricktales/nftverse/ReactNativeFlipper.java b/NFTVerse/MobileApp/android/app/src/release/java/com/cricktales/nftverse/ReactNativeFlipper.java
new file mode 100644
index 00000000..f863c284
--- /dev/null
+++ b/NFTVerse/MobileApp/android/app/src/release/java/com/cricktales/nftverse/ReactNativeFlipper.java
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the LICENSE file in the root
+ * directory of this source tree.
+ */
+package com.cricktales.nftverse;
+
+import android.content.Context;
+import com.facebook.react.ReactInstanceManager;
+
+/**
+ * Class responsible of loading Flipper inside your React Native application. This is the release
+ * flavor of it so it's empty as we don't want to load Flipper.
+ */
+public class ReactNativeFlipper {
+ public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
+ // Do nothing as we don't want to initialize Flipper on Release.
+ }
+}
diff --git a/NFTVerse/MobileApp/android/build.gradle b/NFTVerse/MobileApp/android/build.gradle
new file mode 100644
index 00000000..136cd1a6
--- /dev/null
+++ b/NFTVerse/MobileApp/android/build.gradle
@@ -0,0 +1,44 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ ext {
+ buildToolsVersion = findProperty('android.buildToolsVersion') ?: '33.0.0'
+ minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '21')
+ compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '33')
+ targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '33')
+ if (findProperty('android.kotlinVersion')) {
+ kotlinVersion = findProperty('android.kotlinVersion')
+ }
+ frescoVersion = findProperty('expo.frescoVersion') ?: '2.5.0'
+
+ // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
+ ndkVersion = "23.1.7779620"
+ }
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath('com.android.tools.build:gradle:7.2.1')
+ classpath('com.facebook.react:react-native-gradle-plugin')
+ classpath('de.undercouch:gradle-download-task:5.0.1')
+ classpath 'com.google.gms:google-services:4.3.15'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
+ url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android'))
+ }
+ maven {
+ // Android JSC is installed from npm
+ url(new File(['node', '--print', "require.resolve('jsc-android/package.json')"].execute(null, rootDir).text.trim(), '../dist'))
+ }
+
+ google()
+ mavenCentral()
+ maven { url 'https://www.jitpack.io' }
+ }
+}
diff --git a/NFTVerse/MobileApp/android/gradle.properties b/NFTVerse/MobileApp/android/gradle.properties
new file mode 100644
index 00000000..2353a6ea
--- /dev/null
+++ b/NFTVerse/MobileApp/android/gradle.properties
@@ -0,0 +1,55 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
+org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+
+# Version of flipper SDK to use with React Native
+FLIPPER_VERSION=0.125.0
+
+# Use this property to specify which architecture you want to build.
+# You can also override it from the CLI using
+# ./gradlew -PreactNativeArchitectures=x86_64
+reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
+
+# Use this property to enable support to the new architecture.
+# This will allow you to use TurboModules and the Fabric render in
+# your application. You should enable this flag either if you want
+# to write custom TurboModules/Fabric components OR use libraries that
+# are providing them.
+newArchEnabled=false
+
+# The hosted JavaScript engine
+# Supported values: expo.jsEngine = "hermes" | "jsc"
+expo.jsEngine=hermes
+
+# Enable GIF support in React Native images (~200 B increase)
+expo.gif.enabled=true
+# Enable webp support in React Native images (~85 KB increase)
+expo.webp.enabled=true
+# Enable animated webp support (~3.4 MB increase)
+# Disabled by default because iOS doesn't support animated webp
+expo.webp.animated=false
+android.disableAutomaticComponentCreation=true
+android.bundle.enableUncompressedNativeLibs = false
diff --git a/NFTVerse/MobileApp/android/gradle/wrapper/gradle-wrapper.jar b/NFTVerse/MobileApp/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..249e5832
Binary files /dev/null and b/NFTVerse/MobileApp/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/NFTVerse/MobileApp/android/gradle/wrapper/gradle-wrapper.properties b/NFTVerse/MobileApp/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..ae04661e
--- /dev/null
+++ b/NFTVerse/MobileApp/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/NFTVerse/MobileApp/android/gradlew b/NFTVerse/MobileApp/android/gradlew
new file mode 100644
index 00000000..a69d9cb6
--- /dev/null
+++ b/NFTVerse/MobileApp/android/gradlew
@@ -0,0 +1,240 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/NFTVerse/MobileApp/android/gradlew.bat b/NFTVerse/MobileApp/android/gradlew.bat
new file mode 100644
index 00000000..f127cfd4
--- /dev/null
+++ b/NFTVerse/MobileApp/android/gradlew.bat
@@ -0,0 +1,91 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/NFTVerse/MobileApp/android/settings.gradle b/NFTVerse/MobileApp/android/settings.gradle
new file mode 100644
index 00000000..1016b1a1
--- /dev/null
+++ b/NFTVerse/MobileApp/android/settings.gradle
@@ -0,0 +1,10 @@
+rootProject.name = 'Crick Tales'
+
+apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle");
+useExpoModules()
+
+apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
+applyNativeModulesSettingsGradle(settings)
+
+include ':app'
+includeBuild(new File(["node", "--print", "require.resolve('react-native-gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile())
diff --git a/NFTVerse/MobileApp/app.json b/NFTVerse/MobileApp/app.json
new file mode 100644
index 00000000..81ba2a5d
--- /dev/null
+++ b/NFTVerse/MobileApp/app.json
@@ -0,0 +1,31 @@
+{
+ "expo": {
+ "name": "cricktales",
+ "slug": "crick-tales",
+ "version": "1.0.0",
+ "orientation": "portrait",
+ "icon": "./assets/icon.png",
+ "userInterfaceStyle": "light",
+ "splash": {
+ "image": "./assets/splash.png",
+ "resizeMode": "contain",
+ "backgroundColor": "#ffffff"
+ },
+ "assetBundlePatterns": [
+ "**/*"
+ ],
+ "ios": {
+ "supportsTablet": true
+ },
+ "android": {
+ "adaptiveIcon": {
+ "foregroundImage": "./assets/adaptive-icon.png",
+ "backgroundColor": "#ffffff"
+ },
+ "package": "com.cricktales.nftverse"
+ },
+ "web": {
+ "favicon": "./assets/favicon.png"
+ }
+ }
+}
diff --git a/NFTVerse/MobileApp/assets/LiveMatch/emptycard.png b/NFTVerse/MobileApp/assets/LiveMatch/emptycard.png
new file mode 100644
index 00000000..51e8897c
Binary files /dev/null and b/NFTVerse/MobileApp/assets/LiveMatch/emptycard.png differ
diff --git a/NFTVerse/MobileApp/assets/LiveMatch/head.png b/NFTVerse/MobileApp/assets/LiveMatch/head.png
new file mode 100644
index 00000000..8e8bd0a0
Binary files /dev/null and b/NFTVerse/MobileApp/assets/LiveMatch/head.png differ
diff --git a/NFTVerse/MobileApp/assets/LiveMatch/oppo.png b/NFTVerse/MobileApp/assets/LiveMatch/oppo.png
new file mode 100644
index 00000000..b66a852a
Binary files /dev/null and b/NFTVerse/MobileApp/assets/LiveMatch/oppo.png differ
diff --git a/NFTVerse/MobileApp/assets/LiveMatch/selectcard.png b/NFTVerse/MobileApp/assets/LiveMatch/selectcard.png
new file mode 100644
index 00000000..7998bb1d
Binary files /dev/null and b/NFTVerse/MobileApp/assets/LiveMatch/selectcard.png differ
diff --git a/NFTVerse/MobileApp/assets/LiveMatch/tail.png b/NFTVerse/MobileApp/assets/LiveMatch/tail.png
new file mode 100644
index 00000000..d5678eae
Binary files /dev/null and b/NFTVerse/MobileApp/assets/LiveMatch/tail.png differ
diff --git a/NFTVerse/MobileApp/assets/adaptive-icon.png b/NFTVerse/MobileApp/assets/adaptive-icon.png
new file mode 100644
index 00000000..03d6f6b6
Binary files /dev/null and b/NFTVerse/MobileApp/assets/adaptive-icon.png differ
diff --git a/NFTVerse/MobileApp/assets/auth/authbg.png b/NFTVerse/MobileApp/assets/auth/authbg.png
new file mode 100644
index 00000000..95386345
Binary files /dev/null and b/NFTVerse/MobileApp/assets/auth/authbg.png differ
diff --git a/NFTVerse/MobileApp/assets/auth/header.png b/NFTVerse/MobileApp/assets/auth/header.png
new file mode 100644
index 00000000..8361c142
Binary files /dev/null and b/NFTVerse/MobileApp/assets/auth/header.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/activity-black.png b/NFTVerse/MobileApp/assets/authorized-view/activity-black.png
new file mode 100644
index 00000000..207ca9f0
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/activity-black.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/activity-green.png b/NFTVerse/MobileApp/assets/authorized-view/activity-green.png
new file mode 100644
index 00000000..b01a30bd
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/activity-green.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/assets-black.png b/NFTVerse/MobileApp/assets/authorized-view/assets-black.png
new file mode 100644
index 00000000..9844add3
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/assets-black.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/assets-green.png b/NFTVerse/MobileApp/assets/authorized-view/assets-green.png
new file mode 100644
index 00000000..4c2d32f1
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/assets-green.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/balance-bg.png b/NFTVerse/MobileApp/assets/authorized-view/balance-bg.png
new file mode 100644
index 00000000..05c2fb2d
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/balance-bg.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/buy.png b/NFTVerse/MobileApp/assets/authorized-view/buy.png
new file mode 100644
index 00000000..14e1bfc6
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/buy.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/connect-bg.png b/NFTVerse/MobileApp/assets/authorized-view/connect-bg.png
new file mode 100644
index 00000000..7593d38a
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/connect-bg.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/connect.png b/NFTVerse/MobileApp/assets/authorized-view/connect.png
new file mode 100644
index 00000000..62218736
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/connect.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/default-nft-view.png b/NFTVerse/MobileApp/assets/authorized-view/default-nft-view.png
new file mode 100644
index 00000000..e060733c
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/default-nft-view.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/default-profile.png b/NFTVerse/MobileApp/assets/authorized-view/default-profile.png
new file mode 100644
index 00000000..94f6170f
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/default-profile.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/discord.png b/NFTVerse/MobileApp/assets/authorized-view/discord.png
new file mode 100644
index 00000000..b964cfa4
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/discord.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/facebook.png b/NFTVerse/MobileApp/assets/authorized-view/facebook.png
new file mode 100644
index 00000000..23346250
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/facebook.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/faq-bg.png b/NFTVerse/MobileApp/assets/authorized-view/faq-bg.png
new file mode 100644
index 00000000..4343e1ed
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/faq-bg.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/faq.png b/NFTVerse/MobileApp/assets/authorized-view/faq.png
new file mode 100644
index 00000000..00c5b140
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/faq.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/flow.png b/NFTVerse/MobileApp/assets/authorized-view/flow.png
new file mode 100644
index 00000000..88905ee1
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/flow.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/info.png b/NFTVerse/MobileApp/assets/authorized-view/info.png
new file mode 100644
index 00000000..f7ce9294
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/info.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/instagram.png b/NFTVerse/MobileApp/assets/authorized-view/instagram.png
new file mode 100644
index 00000000..786c1df2
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/instagram.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/linkedin.png b/NFTVerse/MobileApp/assets/authorized-view/linkedin.png
new file mode 100644
index 00000000..b35fe065
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/linkedin.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/logout.png b/NFTVerse/MobileApp/assets/authorized-view/logout.png
new file mode 100644
index 00000000..6772e9da
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/logout.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/profile-black.png b/NFTVerse/MobileApp/assets/authorized-view/profile-black.png
new file mode 100644
index 00000000..6089daf0
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/profile-black.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/profile-green.png b/NFTVerse/MobileApp/assets/authorized-view/profile-green.png
new file mode 100644
index 00000000..b1b1f78f
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/profile-green.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/profile-header.png b/NFTVerse/MobileApp/assets/authorized-view/profile-header.png
new file mode 100644
index 00000000..a7f15efa
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/profile-header.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/recharge.png b/NFTVerse/MobileApp/assets/authorized-view/recharge.png
new file mode 100644
index 00000000..d30a832e
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/recharge.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/screen4.png b/NFTVerse/MobileApp/assets/authorized-view/screen4.png
new file mode 100644
index 00000000..09a6c1d8
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/screen4.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/screen5.png b/NFTVerse/MobileApp/assets/authorized-view/screen5.png
new file mode 100644
index 00000000..24209a35
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/screen5.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/twitter.png b/NFTVerse/MobileApp/assets/authorized-view/twitter.png
new file mode 100644
index 00000000..ce313dfe
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/twitter.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/wallet-black.png b/NFTVerse/MobileApp/assets/authorized-view/wallet-black.png
new file mode 100644
index 00000000..e59c51e4
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/wallet-black.png differ
diff --git a/NFTVerse/MobileApp/assets/authorized-view/wallet-green.png b/NFTVerse/MobileApp/assets/authorized-view/wallet-green.png
new file mode 100644
index 00000000..7ec9e4e4
Binary files /dev/null and b/NFTVerse/MobileApp/assets/authorized-view/wallet-green.png differ
diff --git a/NFTVerse/MobileApp/assets/common/Algorand.png b/NFTVerse/MobileApp/assets/common/Algorand.png
new file mode 100644
index 00000000..f9df7efe
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/Algorand.png differ
diff --git a/NFTVerse/MobileApp/assets/common/Refresh.png b/NFTVerse/MobileApp/assets/common/Refresh.png
new file mode 100644
index 00000000..147f0eb7
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/Refresh.png differ
diff --git a/NFTVerse/MobileApp/assets/common/Vector.png b/NFTVerse/MobileApp/assets/common/Vector.png
new file mode 100644
index 00000000..34219657
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/Vector.png differ
diff --git a/NFTVerse/MobileApp/assets/common/arrow-right-green.png b/NFTVerse/MobileApp/assets/common/arrow-right-green.png
new file mode 100644
index 00000000..064bfc97
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/arrow-right-green.png differ
diff --git a/NFTVerse/MobileApp/assets/common/arrow.png b/NFTVerse/MobileApp/assets/common/arrow.png
new file mode 100644
index 00000000..fb5d62dc
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/arrow.png differ
diff --git a/NFTVerse/MobileApp/assets/common/coins.png b/NFTVerse/MobileApp/assets/common/coins.png
new file mode 100644
index 00000000..611c263f
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/coins.png differ
diff --git a/NFTVerse/MobileApp/assets/common/copy.png b/NFTVerse/MobileApp/assets/common/copy.png
new file mode 100644
index 00000000..f38927b7
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/copy.png differ
diff --git a/NFTVerse/MobileApp/assets/common/description.png b/NFTVerse/MobileApp/assets/common/description.png
new file mode 100644
index 00000000..3f93a62c
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/description.png differ
diff --git a/NFTVerse/MobileApp/assets/common/details.png b/NFTVerse/MobileApp/assets/common/details.png
new file mode 100644
index 00000000..55d21abb
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/details.png differ
diff --git a/NFTVerse/MobileApp/assets/common/ethereum.png b/NFTVerse/MobileApp/assets/common/ethereum.png
new file mode 100644
index 00000000..8a805be9
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/ethereum.png differ
diff --git a/NFTVerse/MobileApp/assets/common/info.png b/NFTVerse/MobileApp/assets/common/info.png
new file mode 100644
index 00000000..0f694ad1
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/info.png differ
diff --git a/NFTVerse/MobileApp/assets/common/like-black.png b/NFTVerse/MobileApp/assets/common/like-black.png
new file mode 100644
index 00000000..b7464a95
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/like-black.png differ
diff --git a/NFTVerse/MobileApp/assets/common/like-gray.png b/NFTVerse/MobileApp/assets/common/like-gray.png
new file mode 100644
index 00000000..32088cc2
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/like-gray.png differ
diff --git a/NFTVerse/MobileApp/assets/common/logo.png b/NFTVerse/MobileApp/assets/common/logo.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/logo.png differ
diff --git a/NFTVerse/MobileApp/assets/common/mail-white.png b/NFTVerse/MobileApp/assets/common/mail-white.png
new file mode 100644
index 00000000..2848e905
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/mail-white.png differ
diff --git a/NFTVerse/MobileApp/assets/common/mail.png b/NFTVerse/MobileApp/assets/common/mail.png
new file mode 100644
index 00000000..fbe05bf6
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/mail.png differ
diff --git a/NFTVerse/MobileApp/assets/common/nft.png b/NFTVerse/MobileApp/assets/common/nft.png
new file mode 100644
index 00000000..1e41816c
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/nft.png differ
diff --git a/NFTVerse/MobileApp/assets/common/options.png b/NFTVerse/MobileApp/assets/common/options.png
new file mode 100644
index 00000000..d0246157
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/options.png differ
diff --git a/NFTVerse/MobileApp/assets/common/reload.png b/NFTVerse/MobileApp/assets/common/reload.png
new file mode 100644
index 00000000..333afd4b
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/reload.png differ
diff --git a/NFTVerse/MobileApp/assets/common/share.png b/NFTVerse/MobileApp/assets/common/share.png
new file mode 100644
index 00000000..59c91f53
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/share.png differ
diff --git a/NFTVerse/MobileApp/assets/common/view-black.png b/NFTVerse/MobileApp/assets/common/view-black.png
new file mode 100644
index 00000000..2214ca07
Binary files /dev/null and b/NFTVerse/MobileApp/assets/common/view-black.png differ
diff --git a/NFTVerse/MobileApp/assets/contest/bat.png b/NFTVerse/MobileApp/assets/contest/bat.png
new file mode 100644
index 00000000..471ddc81
Binary files /dev/null and b/NFTVerse/MobileApp/assets/contest/bat.png differ
diff --git a/NFTVerse/MobileApp/assets/contest/contesthead.png b/NFTVerse/MobileApp/assets/contest/contesthead.png
new file mode 100644
index 00000000..7f2b9e4d
Binary files /dev/null and b/NFTVerse/MobileApp/assets/contest/contesthead.png differ
diff --git a/NFTVerse/MobileApp/assets/contest/team1.png b/NFTVerse/MobileApp/assets/contest/team1.png
new file mode 100644
index 00000000..d29ad4f4
Binary files /dev/null and b/NFTVerse/MobileApp/assets/contest/team1.png differ
diff --git a/NFTVerse/MobileApp/assets/contest/team2.png b/NFTVerse/MobileApp/assets/contest/team2.png
new file mode 100644
index 00000000..a5d9a8c0
Binary files /dev/null and b/NFTVerse/MobileApp/assets/contest/team2.png differ
diff --git a/NFTVerse/MobileApp/assets/favicon.png b/NFTVerse/MobileApp/assets/favicon.png
new file mode 100644
index 00000000..e75f697b
Binary files /dev/null and b/NFTVerse/MobileApp/assets/favicon.png differ
diff --git a/NFTVerse/MobileApp/assets/icon.png b/NFTVerse/MobileApp/assets/icon.png
new file mode 100644
index 00000000..ae77e561
Binary files /dev/null and b/NFTVerse/MobileApp/assets/icon.png differ
diff --git a/NFTVerse/MobileApp/assets/images/knob.png b/NFTVerse/MobileApp/assets/images/knob.png
new file mode 100644
index 00000000..94a2c305
Binary files /dev/null and b/NFTVerse/MobileApp/assets/images/knob.png differ
diff --git a/NFTVerse/MobileApp/assets/joincontest/cards.png b/NFTVerse/MobileApp/assets/joincontest/cards.png
new file mode 100644
index 00000000..06acbf55
Binary files /dev/null and b/NFTVerse/MobileApp/assets/joincontest/cards.png differ
diff --git a/NFTVerse/MobileApp/assets/joincontest/tokens.png b/NFTVerse/MobileApp/assets/joincontest/tokens.png
new file mode 100644
index 00000000..751bd6db
Binary files /dev/null and b/NFTVerse/MobileApp/assets/joincontest/tokens.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/Group (1).png b/NFTVerse/MobileApp/assets/kyc/Group (1).png
new file mode 100644
index 00000000..f2ae87dc
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/Group (1).png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/Kyc.png b/NFTVerse/MobileApp/assets/kyc/Kyc.png
new file mode 100644
index 00000000..a67cf7f6
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/Kyc.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/backside.png b/NFTVerse/MobileApp/assets/kyc/backside.png
new file mode 100644
index 00000000..b02a9147
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/backside.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/bulletpoint.png b/NFTVerse/MobileApp/assets/kyc/bulletpoint.png
new file mode 100644
index 00000000..39dd88d7
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/bulletpoint.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/edit.png b/NFTVerse/MobileApp/assets/kyc/edit.png
new file mode 100644
index 00000000..dd5e1748
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/edit.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/failed.png b/NFTVerse/MobileApp/assets/kyc/failed.png
new file mode 100644
index 00000000..4c024e80
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/failed.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/frontside.png b/NFTVerse/MobileApp/assets/kyc/frontside.png
new file mode 100644
index 00000000..5a3ca4c4
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/frontside.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/kycverify.png b/NFTVerse/MobileApp/assets/kyc/kycverify.png
new file mode 100644
index 00000000..78b9ff29
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/kycverify.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/pending.png b/NFTVerse/MobileApp/assets/kyc/pending.png
new file mode 100644
index 00000000..28f50517
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/pending.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/selfie.png b/NFTVerse/MobileApp/assets/kyc/selfie.png
new file mode 100644
index 00000000..11b49db0
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/selfie.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/status1.png b/NFTVerse/MobileApp/assets/kyc/status1.png
new file mode 100644
index 00000000..3443cfb2
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/status1.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/thankyou.png b/NFTVerse/MobileApp/assets/kyc/thankyou.png
new file mode 100644
index 00000000..cb31f81d
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/thankyou.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/verified.png b/NFTVerse/MobileApp/assets/kyc/verified.png
new file mode 100644
index 00000000..926072ca
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/verified.png differ
diff --git a/NFTVerse/MobileApp/assets/kyc/verifiedimage.png b/NFTVerse/MobileApp/assets/kyc/verifiedimage.png
new file mode 100644
index 00000000..6f7604ee
Binary files /dev/null and b/NFTVerse/MobileApp/assets/kyc/verifiedimage.png differ
diff --git a/NFTVerse/MobileApp/assets/navigationIcon/activity.png b/NFTVerse/MobileApp/assets/navigationIcon/activity.png
new file mode 100644
index 00000000..b6a1d6a2
Binary files /dev/null and b/NFTVerse/MobileApp/assets/navigationIcon/activity.png differ
diff --git a/NFTVerse/MobileApp/assets/navigationIcon/activityhover.png b/NFTVerse/MobileApp/assets/navigationIcon/activityhover.png
new file mode 100644
index 00000000..96b5813c
Binary files /dev/null and b/NFTVerse/MobileApp/assets/navigationIcon/activityhover.png differ
diff --git a/NFTVerse/MobileApp/assets/navigationIcon/cryptos.png b/NFTVerse/MobileApp/assets/navigationIcon/cryptos.png
new file mode 100644
index 00000000..a99c0504
Binary files /dev/null and b/NFTVerse/MobileApp/assets/navigationIcon/cryptos.png differ
diff --git a/NFTVerse/MobileApp/assets/navigationIcon/cryptoshover.png b/NFTVerse/MobileApp/assets/navigationIcon/cryptoshover.png
new file mode 100644
index 00000000..dd05709e
Binary files /dev/null and b/NFTVerse/MobileApp/assets/navigationIcon/cryptoshover.png differ
diff --git a/NFTVerse/MobileApp/assets/navigationIcon/home.png b/NFTVerse/MobileApp/assets/navigationIcon/home.png
new file mode 100644
index 00000000..4b3031b2
Binary files /dev/null and b/NFTVerse/MobileApp/assets/navigationIcon/home.png differ
diff --git a/NFTVerse/MobileApp/assets/navigationIcon/homehover.png b/NFTVerse/MobileApp/assets/navigationIcon/homehover.png
new file mode 100644
index 00000000..fd95509d
Binary files /dev/null and b/NFTVerse/MobileApp/assets/navigationIcon/homehover.png differ
diff --git a/NFTVerse/MobileApp/assets/navigationIcon/rewards.png b/NFTVerse/MobileApp/assets/navigationIcon/rewards.png
new file mode 100644
index 00000000..7f433145
Binary files /dev/null and b/NFTVerse/MobileApp/assets/navigationIcon/rewards.png differ
diff --git a/NFTVerse/MobileApp/assets/navigationIcon/rewardshover.png b/NFTVerse/MobileApp/assets/navigationIcon/rewardshover.png
new file mode 100644
index 00000000..cea8e8b0
Binary files /dev/null and b/NFTVerse/MobileApp/assets/navigationIcon/rewardshover.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/onboardingbg.png b/NFTVerse/MobileApp/assets/onboarding/onboardingbg.png
new file mode 100644
index 00000000..5c710b84
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/onboardingbg.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen1-bg.png b/NFTVerse/MobileApp/assets/onboarding/screen1-bg.png
new file mode 100644
index 00000000..f2e8682a
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen1-bg.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen1-hero.png b/NFTVerse/MobileApp/assets/onboarding/screen1-hero.png
new file mode 100644
index 00000000..b9a7ca5b
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen1-hero.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen1.png b/NFTVerse/MobileApp/assets/onboarding/screen1.png
new file mode 100644
index 00000000..a945ee09
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen1.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen2-bg.png b/NFTVerse/MobileApp/assets/onboarding/screen2-bg.png
new file mode 100644
index 00000000..417a1413
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen2-bg.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen2-hero.png b/NFTVerse/MobileApp/assets/onboarding/screen2-hero.png
new file mode 100644
index 00000000..6aaa024e
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen2-hero.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen2.png b/NFTVerse/MobileApp/assets/onboarding/screen2.png
new file mode 100644
index 00000000..54c88020
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen2.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen3-bg.png b/NFTVerse/MobileApp/assets/onboarding/screen3-bg.png
new file mode 100644
index 00000000..e55fb942
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen3-bg.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen3-hero.png b/NFTVerse/MobileApp/assets/onboarding/screen3-hero.png
new file mode 100644
index 00000000..f3c33981
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen3-hero.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen3.png b/NFTVerse/MobileApp/assets/onboarding/screen3.png
new file mode 100644
index 00000000..a13e6998
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen3.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen4.png b/NFTVerse/MobileApp/assets/onboarding/screen4.png
new file mode 100644
index 00000000..2061c2f1
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen4.png differ
diff --git a/NFTVerse/MobileApp/assets/onboarding/screen5.png b/NFTVerse/MobileApp/assets/onboarding/screen5.png
new file mode 100644
index 00000000..24209a35
Binary files /dev/null and b/NFTVerse/MobileApp/assets/onboarding/screen5.png differ
diff --git a/NFTVerse/MobileApp/assets/profileOptions/Blog.png b/NFTVerse/MobileApp/assets/profileOptions/Blog.png
new file mode 100644
index 00000000..e8ec86ad
Binary files /dev/null and b/NFTVerse/MobileApp/assets/profileOptions/Blog.png differ
diff --git a/NFTVerse/MobileApp/assets/profileOptions/Kyc.png b/NFTVerse/MobileApp/assets/profileOptions/Kyc.png
new file mode 100644
index 00000000..ca57f680
Binary files /dev/null and b/NFTVerse/MobileApp/assets/profileOptions/Kyc.png differ
diff --git a/NFTVerse/MobileApp/assets/profileOptions/Logout.png b/NFTVerse/MobileApp/assets/profileOptions/Logout.png
new file mode 100644
index 00000000..29df0da5
Binary files /dev/null and b/NFTVerse/MobileApp/assets/profileOptions/Logout.png differ
diff --git a/NFTVerse/MobileApp/assets/profileOptions/Mainnet.png b/NFTVerse/MobileApp/assets/profileOptions/Mainnet.png
new file mode 100644
index 00000000..aac2d675
Binary files /dev/null and b/NFTVerse/MobileApp/assets/profileOptions/Mainnet.png differ
diff --git a/NFTVerse/MobileApp/assets/profileOptions/Testnet.png b/NFTVerse/MobileApp/assets/profileOptions/Testnet.png
new file mode 100644
index 00000000..c6f2748a
Binary files /dev/null and b/NFTVerse/MobileApp/assets/profileOptions/Testnet.png differ
diff --git a/NFTVerse/MobileApp/assets/profileOptions/algoscan.png b/NFTVerse/MobileApp/assets/profileOptions/algoscan.png
new file mode 100644
index 00000000..9534dab2
Binary files /dev/null and b/NFTVerse/MobileApp/assets/profileOptions/algoscan.png differ
diff --git a/NFTVerse/MobileApp/assets/profileOptions/connect.png b/NFTVerse/MobileApp/assets/profileOptions/connect.png
new file mode 100644
index 00000000..b9277cb6
Binary files /dev/null and b/NFTVerse/MobileApp/assets/profileOptions/connect.png differ
diff --git a/NFTVerse/MobileApp/assets/profileOptions/quest.png b/NFTVerse/MobileApp/assets/profileOptions/quest.png
new file mode 100644
index 00000000..54853500
Binary files /dev/null and b/NFTVerse/MobileApp/assets/profileOptions/quest.png differ
diff --git a/NFTVerse/MobileApp/assets/profileOptions/support.png b/NFTVerse/MobileApp/assets/profileOptions/support.png
new file mode 100644
index 00000000..0ff09f59
Binary files /dev/null and b/NFTVerse/MobileApp/assets/profileOptions/support.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/coins.png b/NFTVerse/MobileApp/assets/rewards/coins.png
new file mode 100644
index 00000000..5131fbb2
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/coins.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/comingsoon.png b/NFTVerse/MobileApp/assets/rewards/comingsoon.png
new file mode 100644
index 00000000..612de166
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/comingsoon.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/five.png b/NFTVerse/MobileApp/assets/rewards/five.png
new file mode 100644
index 00000000..8708cda2
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/five.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/four.png b/NFTVerse/MobileApp/assets/rewards/four.png
new file mode 100644
index 00000000..b09bb93e
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/four.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/kyc.png b/NFTVerse/MobileApp/assets/rewards/kyc.png
new file mode 100644
index 00000000..da02d028
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/kyc.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/kycbg.png b/NFTVerse/MobileApp/assets/rewards/kycbg.png
new file mode 100644
index 00000000..82be3276
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/kycbg.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/lost.png b/NFTVerse/MobileApp/assets/rewards/lost.png
new file mode 100644
index 00000000..d83fb4ca
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/lost.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/one.png b/NFTVerse/MobileApp/assets/rewards/one.png
new file mode 100644
index 00000000..ff9bafac
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/one.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/refer.png b/NFTVerse/MobileApp/assets/rewards/refer.png
new file mode 100644
index 00000000..9f321c00
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/refer.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/shareInsta.png b/NFTVerse/MobileApp/assets/rewards/shareInsta.png
new file mode 100644
index 00000000..877f77bf
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/shareInsta.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/sharefacebook.png b/NFTVerse/MobileApp/assets/rewards/sharefacebook.png
new file mode 100644
index 00000000..d459e83b
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/sharefacebook.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/sharetwitter.png b/NFTVerse/MobileApp/assets/rewards/sharetwitter.png
new file mode 100644
index 00000000..d8e56f5b
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/sharetwitter.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/sharewhatsapp.png b/NFTVerse/MobileApp/assets/rewards/sharewhatsapp.png
new file mode 100644
index 00000000..b470c0ac
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/sharewhatsapp.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/six.png b/NFTVerse/MobileApp/assets/rewards/six.png
new file mode 100644
index 00000000..cd83449b
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/six.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/three.png b/NFTVerse/MobileApp/assets/rewards/three.png
new file mode 100644
index 00000000..218170ec
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/three.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/two.png b/NFTVerse/MobileApp/assets/rewards/two.png
new file mode 100644
index 00000000..9e5fe401
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/two.png differ
diff --git a/NFTVerse/MobileApp/assets/rewards/win.png b/NFTVerse/MobileApp/assets/rewards/win.png
new file mode 100644
index 00000000..8995d145
Binary files /dev/null and b/NFTVerse/MobileApp/assets/rewards/win.png differ
diff --git a/NFTVerse/MobileApp/assets/send/arrow.png b/NFTVerse/MobileApp/assets/send/arrow.png
new file mode 100644
index 00000000..53b6e301
Binary files /dev/null and b/NFTVerse/MobileApp/assets/send/arrow.png differ
diff --git a/NFTVerse/MobileApp/assets/send/search.png b/NFTVerse/MobileApp/assets/send/search.png
new file mode 100644
index 00000000..72515885
Binary files /dev/null and b/NFTVerse/MobileApp/assets/send/search.png differ
diff --git a/NFTVerse/MobileApp/assets/splash.gif b/NFTVerse/MobileApp/assets/splash.gif
new file mode 100644
index 00000000..70ccc398
Binary files /dev/null and b/NFTVerse/MobileApp/assets/splash.gif differ
diff --git a/NFTVerse/MobileApp/assets/splash.png b/NFTVerse/MobileApp/assets/splash.png
new file mode 100644
index 00000000..115addff
Binary files /dev/null and b/NFTVerse/MobileApp/assets/splash.png differ
diff --git a/NFTVerse/MobileApp/assets/throwcard/p1.png b/NFTVerse/MobileApp/assets/throwcard/p1.png
new file mode 100644
index 00000000..2bd73adf
Binary files /dev/null and b/NFTVerse/MobileApp/assets/throwcard/p1.png differ
diff --git a/NFTVerse/MobileApp/assets/throwcard/p2.png b/NFTVerse/MobileApp/assets/throwcard/p2.png
new file mode 100644
index 00000000..9793c6c2
Binary files /dev/null and b/NFTVerse/MobileApp/assets/throwcard/p2.png differ
diff --git a/NFTVerse/MobileApp/assets/throwcard/p3.png b/NFTVerse/MobileApp/assets/throwcard/p3.png
new file mode 100644
index 00000000..10141d9e
Binary files /dev/null and b/NFTVerse/MobileApp/assets/throwcard/p3.png differ
diff --git a/NFTVerse/MobileApp/assets/throwcard/p4.png b/NFTVerse/MobileApp/assets/throwcard/p4.png
new file mode 100644
index 00000000..1d047ecc
Binary files /dev/null and b/NFTVerse/MobileApp/assets/throwcard/p4.png differ
diff --git a/NFTVerse/MobileApp/assets/throwcard/p5.png b/NFTVerse/MobileApp/assets/throwcard/p5.png
new file mode 100644
index 00000000..924b362f
Binary files /dev/null and b/NFTVerse/MobileApp/assets/throwcard/p5.png differ
diff --git a/NFTVerse/MobileApp/assets/throwcard/p6.png b/NFTVerse/MobileApp/assets/throwcard/p6.png
new file mode 100644
index 00000000..afb3a30e
Binary files /dev/null and b/NFTVerse/MobileApp/assets/throwcard/p6.png differ
diff --git a/NFTVerse/MobileApp/assets/throwcard/p7.png b/NFTVerse/MobileApp/assets/throwcard/p7.png
new file mode 100644
index 00000000..7a64d0ba
Binary files /dev/null and b/NFTVerse/MobileApp/assets/throwcard/p7.png differ
diff --git a/NFTVerse/MobileApp/assets/throwcard/player.png b/NFTVerse/MobileApp/assets/throwcard/player.png
new file mode 100644
index 00000000..c7f220a3
Binary files /dev/null and b/NFTVerse/MobileApp/assets/throwcard/player.png differ
diff --git a/NFTVerse/MobileApp/assets/wallet/Tick.png b/NFTVerse/MobileApp/assets/wallet/Tick.png
new file mode 100644
index 00000000..a37551d1
Binary files /dev/null and b/NFTVerse/MobileApp/assets/wallet/Tick.png differ
diff --git a/NFTVerse/MobileApp/assets/wallet/algorandhexagon.png b/NFTVerse/MobileApp/assets/wallet/algorandhexagon.png
new file mode 100644
index 00000000..d64a40d4
Binary files /dev/null and b/NFTVerse/MobileApp/assets/wallet/algorandhexagon.png differ
diff --git a/NFTVerse/MobileApp/assets/wallet/flow.png b/NFTVerse/MobileApp/assets/wallet/flow.png
new file mode 100644
index 00000000..8e0dc1df
Binary files /dev/null and b/NFTVerse/MobileApp/assets/wallet/flow.png differ
diff --git a/NFTVerse/MobileApp/assets/wallet/talecoinstack.png b/NFTVerse/MobileApp/assets/wallet/talecoinstack.png
new file mode 100644
index 00000000..7297f9de
Binary files /dev/null and b/NFTVerse/MobileApp/assets/wallet/talecoinstack.png differ
diff --git a/NFTVerse/MobileApp/assets/wheel/spin1.png b/NFTVerse/MobileApp/assets/wheel/spin1.png
new file mode 100644
index 00000000..4507b875
Binary files /dev/null and b/NFTVerse/MobileApp/assets/wheel/spin1.png differ
diff --git a/NFTVerse/MobileApp/assets/wheel/spin2.png b/NFTVerse/MobileApp/assets/wheel/spin2.png
new file mode 100644
index 00000000..df1b24fe
Binary files /dev/null and b/NFTVerse/MobileApp/assets/wheel/spin2.png differ
diff --git a/NFTVerse/MobileApp/assets/wheel/spin3.png b/NFTVerse/MobileApp/assets/wheel/spin3.png
new file mode 100644
index 00000000..1d9d5e66
Binary files /dev/null and b/NFTVerse/MobileApp/assets/wheel/spin3.png differ
diff --git a/NFTVerse/MobileApp/assets/wheel/spin4.png b/NFTVerse/MobileApp/assets/wheel/spin4.png
new file mode 100644
index 00000000..789c763d
Binary files /dev/null and b/NFTVerse/MobileApp/assets/wheel/spin4.png differ
diff --git a/NFTVerse/MobileApp/assets/wheel/spin5.png b/NFTVerse/MobileApp/assets/wheel/spin5.png
new file mode 100644
index 00000000..3bb0c94f
Binary files /dev/null and b/NFTVerse/MobileApp/assets/wheel/spin5.png differ
diff --git a/NFTVerse/MobileApp/assets/wheel/spin6.png b/NFTVerse/MobileApp/assets/wheel/spin6.png
new file mode 100644
index 00000000..92bd617f
Binary files /dev/null and b/NFTVerse/MobileApp/assets/wheel/spin6.png differ
diff --git a/NFTVerse/MobileApp/babel.config.js b/NFTVerse/MobileApp/babel.config.js
new file mode 100644
index 00000000..82c96ca1
--- /dev/null
+++ b/NFTVerse/MobileApp/babel.config.js
@@ -0,0 +1,16 @@
+module.exports = function (api) {
+ api.cache(true);
+ return {
+ presets: ['babel-preset-expo'],
+ plugins: ["nativewind/babel",
+ [
+ 'module:react-native-dotenv',
+ {
+ moduleName: 'denv',
+ path: '.env',
+ },
+ ]
+ ]
+
+ };
+};
diff --git a/NFTVerse/MobileApp/components/CommonComponent/ThreeD/Forgltf.jsx b/NFTVerse/MobileApp/components/CommonComponent/ThreeD/Forgltf.jsx
new file mode 100644
index 00000000..ef5ad0a1
--- /dev/null
+++ b/NFTVerse/MobileApp/components/CommonComponent/ThreeD/Forgltf.jsx
@@ -0,0 +1,58 @@
+import { Canvas } from "@react-three/fiber";
+import { useLoader } from "@react-three/fiber";
+import { Environment, OrbitControls, useGLTF } from "@react-three/drei";
+import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
+import { Suspense, useEffect, useMemo, useState } from "react";
+import { toast } from "react-toastify";
+import { useTransition } from "react";
+import { View } from "react-native";
+
+const Model = ({ src }) => {
+
+ // let gltf = useGLTF(src);
+ // useGLTF.preload(src);
+ const [isPending, startTransition] = useTransition();
+ const [gltf, setGltf] = useState();
+ useEffect(() => {
+ try {
+ startTransition(() =>
+ void new GLTFLoader().load(src, setGltf), [src]
+ )
+ }
+ catch {
+ toast('error')
+ }
+ }, [src])
+ // }
+ // catch {
+ // toast('texture files are not supported')
+ // }
+ // useLoader(GLTFLoader, "./gift.glb");
+
+ return (
+ <>
+ {gltf?.scene && <>
+
+
+ >
+ }
+ >
+ );
+};
+
+export default function Forgltf({ src }) {
+ return (
+
+
+
+
+
+
+ {/* */}
+
+
+
+
+ );
+}
+//
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/CommonComponent/ThreeD/ThreeDRenderer.jsx b/NFTVerse/MobileApp/components/CommonComponent/ThreeD/ThreeDRenderer.jsx
new file mode 100644
index 00000000..2ef043a0
--- /dev/null
+++ b/NFTVerse/MobileApp/components/CommonComponent/ThreeD/ThreeDRenderer.jsx
@@ -0,0 +1,74 @@
+import { Canvas, useLoader } from "@react-three/fiber";
+// import * as THREE from "three"
+import { OrbitControls, useFBX, Html, useProgress, Environment } from "@react-three/drei";
+import { Suspense, useState } from "react";
+import { FBXLoader } from "three-stdlib";
+import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
+// import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
+// import ReactThreeFbxViewer from 'react-three-fbx-viewer'
+import * as material from "@mui/material";
+import { useTransition } from "react";
+import { useEffect } from "react";
+import { useSelector } from "react-redux";
+// import { LinearProgress } from "@material-ui/core";
+import Forgltf from "./Forgltf";
+function Loader() {
+ const { progress } = useProgress();
+ return {progress} % loaded;
+}
+const ThreeDRenderer = ({ src, className, type }) => {
+ const canvas = document.querySelector("Canvas")
+ const [gltfscene, setGltfScene] = useState()
+ const [isPending, startTransition] = useTransition();
+ const [FBX, setFBX] = useState({});
+ // const gui = new dat.GUI()
+
+ // const [scale,setScale] = useState();
+ // let fbx = useFBX(src);
+ useEffect(() => {
+ if (type === "fbx") {
+ startTransition(() =>
+ void new FBXLoader().load(src, setFBX), [src]
+ )
+ }
+ }, [src, type])
+
+
+
+ const appCtx = useSelector((state) => state.app);
+ // const gltf = useLoader(GLTFLoader, "/adamHead.gltf");
+ function ThreeD() {
+ const fbx = useFBX(src);
+ return ;
+ }
+ return (
+ <>
+ {isPending ? (
+
+ Loading...
+ {/* */}
+
+ ) : (
+
+ type === "fbx" ?
+
+
+
+
+
+
+
+
+
+
+ :
+ (type ==="gltf" || type ==="glb") &&
+
+
+
+ )}
+ >
+ );
+};
+
+export default ThreeDRenderer;
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/CommonComponent/fetchwalletBalance.jsx b/NFTVerse/MobileApp/components/CommonComponent/fetchwalletBalance.jsx
new file mode 100644
index 00000000..c96527c3
--- /dev/null
+++ b/NFTVerse/MobileApp/components/CommonComponent/fetchwalletBalance.jsx
@@ -0,0 +1,35 @@
+import axios from 'axios'
+import { URL_BLOCKCHAIN_SERVICE } from 'denv'
+import React, { useEffect, useState } from 'react'
+import { useSelector } from 'react-redux';
+
+
+export default function FetchwalletBalance() {
+ const appCtx = useSelector((state) => state.app);
+ const [balance, setBalance] = useState(0);
+ const fetchAlgos = () => {
+ let config = {
+ url: `${URL_BLOCKCHAIN_SERVICE}/user/wallet/balance?blockchain=ALGORAND`,
+ method: 'get',
+ headers: {
+ "X-Auth-Token": appCtx.authToken,
+ "Content-Type": "application/json",
+ }
+ }
+ axios(config)
+ .then(function (response) {
+ console.log(response);
+ setBalance(response?.data?.balance);
+ })
+ .catch(function (error) {
+ console.log(error);
+ })
+ }
+ useEffect(() => {
+ fetchAlgos();
+ }, [fetchAlgos])
+ return {
+ balance,
+ fetchAlgos
+ }
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/CommonComponent/useWalletView/useWalletView.js b/NFTVerse/MobileApp/components/CommonComponent/useWalletView/useWalletView.js
new file mode 100644
index 00000000..4ca997f2
--- /dev/null
+++ b/NFTVerse/MobileApp/components/CommonComponent/useWalletView/useWalletView.js
@@ -0,0 +1,219 @@
+import algosdk from 'algosdk';
+import React, { useState } from 'react'
+import { useDispatch, useSelector } from 'react-redux';
+import AlgorandClient from '../../services/algorandsdk';
+// import CryptoJS from 'react-native-crypto-js'
+
+export const useWalletView = () => {
+ const [accountAsset, setAccountAsset] = useState([]);
+ const [amount, setAmount] = useState(0);
+ const [assetUrl, setAssetUrl] = useState([]);
+ const [optedIn, setOptIn] = useState(false)
+ const appCtx = useSelector((state) => state.app)
+ const [taleAmount, setTaleAmount] = useState(0);
+ const [optInSuccessfull, setOptInSuccessfull] = useState(false);
+ const dispatch = useDispatch();
+ const showAssets = (async () => {
+ let accountInfo = await AlgorandClient.accountInformation(appCtx.walletAddress[0]?.address).do();
+ setAmount(accountInfo.amount / 1000000)
+ console.log(amount);
+ setAccountAsset(accountInfo["created-assets"]);
+ if (accountInfo["created-assets"] === undefined) {
+ setAccountAsset([]);
+ // document.getElementById('wallet_asset_div').innerHTML = 'No asset found
';
+ } else {
+ var c = 'Your Assets
';
+ // console.log(accountInfo['created-assets'])
+ var assetobj = accountInfo['created-assets']
+ let array = [];
+ let assetUrl = [];
+ for (const item in assetobj) {
+ array = ([...array, { key: assetobj[item].index, value: assetobj[item].params.name }])
+ assetUrl = ([...assetUrl, { key: assetobj[item].index, value: assetobj[item].params.url }])
+ // console.log(`key = ${item}, value = ${assetobj[item]["assetname"]}`);
+ // c = c + '';
+ }
+ setAccountAsset(array);
+ setAssetUrl(assetUrl);
+ // document.getElementById('wallet_asset_div').innerHTML = c;
+ }
+ })
+ const optInAsset = (assetId) => {
+ const waitForConfirmation = async function (AlgorandClient, txId) {
+ let response = await AlgorandClient.status().do();
+ let lastround = response["last-round"];
+ while (true) {
+ const pendingInfo = await AlgorandClient.pendingTransactionInformation(txId).do();
+ if (pendingInfo["confirmed-round"] !== null && pendingInfo["confirmed-round"] > 0) {
+ //Got the completed Transaction
+ // console.log("Transaction " + txId + " confirmed in round " + pendingInfo["confirmed-round"]);
+ break;
+ }
+ lastround++;
+ await AlgorandClient.statusAfterBlock(lastround).do();
+ }
+ };
+
+
+ // Function used to print created asset for account and assetid
+ const printCreatedAsset = async function (AlgorandClient, account, assetid) {
+ // note: if you have an indexer instance available it is easier to just use this
+ // let accountInfo = await indexerClient.searchAccounts()
+ // .assetID(assetIndex).do();
+ // and in the loop below use this to extract the asset for a particular account
+ // accountInfo['accounts'][idx][account]);
+ let accountInfo = await AlgorandClient.accountInformation(account).do();
+ for (let idx = 0; idx < accountInfo['created-assets'].length; idx++) {
+ let scrutinizedAsset = accountInfo['created-assets'][idx];
+ if (scrutinizedAsset['index'] == assetid) {
+ // console.log("AssetID = " + scrutinizedAsset['index']);
+ let myparms = JSON.stringify(scrutinizedAsset['params'], undefined, 2);
+ // console.log("parms = " + myparms);
+ break;
+ }
+ }
+ };
+ // Function used to print asset holding for account and assetid
+ const printAssetHolding = async function (AlgorandClient, account, assetid) {
+ // note: if you have an indexer instance available it is easier to just use this
+ // let accountInfo = await indexerClient.searchAccounts()
+ // .assetID(assetIndex).do();
+ // and in the loop below use this to extract the asset for a particular account
+ // accountInfo['accounts'][idx][account]);
+ let accountInfo = await AlgorandClient.accountInformation(account).do();
+ for (let idx = 0; idx < accountInfo['assets'].length; idx++) {
+ let scrutinizedAsset = accountInfo['assets'][idx];
+ if (scrutinizedAsset['asset-id'] == assetid) {
+ let myassetholding = JSON.stringify(scrutinizedAsset, undefined, 2);
+ // console.log("assetholdinginfo = " + myassetholding);
+ break;
+ }
+ }
+ };
+ const oldMnemonic = appCtx.mnemonic?.split(' ');
+ let decryptedData='';
+
+ // if (oldMnemonic?.length > 1) {
+ // var ciphertext = CryptoJS.AES.encrypt(JSON.stringify(appCtx.mnemonic), 'secretKey').toString();
+ // let bytes = CryptoJS.AES.decrypt(ciphertext, 'secretKey');
+ // decryptedData = bytes.toString(CryptoJS.enc.Utf8) && JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
+ // }
+ // else {
+ // var bytes = CryptoJS.AES.decrypt(appCtx.mnemonic || '""', 'secretKey');
+ // decryptedData = bytes.toString(CryptoJS.enc.Utf8) && JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
+ // }
+ // JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
+ var account3_mnemonic = decryptedData;
+ var recoveredAccount3 = algosdk.mnemonicToSecretKey(account3_mnemonic);
+
+
+ (async () => {
+
+ let note = undefined;
+ let assetID = parseInt(process.env.REACT_APP_TAIL_COIN_TOKEN);
+ // console.log(process.env.REACT_APP_TAIL_COIN_TOKEN);
+
+ let params = await AlgorandClient.getTransactionParams().do();
+ //comment out the next two lines to use suggested fee
+ params.fee = 1000;
+ params.flatFee = true;
+
+ let sender = recoveredAccount3.addr;
+ let recipient = sender;
+ // We set revocationTarget to undefined as
+ // This is not a clawback operation
+ let revocationTarget = undefined;
+ // CloseReaminerTo is set to undefined as
+ // we are not closing out an asset
+ let closeRemainderTo = undefined;
+ // We are sending 0 assets
+ let amount = 0;
+
+
+ // signing and sending "txn" allows sender to begin accepting asset specified by creator and index
+ let opttxn = algosdk.makeAssetTransferTxnWithSuggestedParams(sender, recipient, closeRemainderTo, revocationTarget,
+ amount, note, assetID, params);
+
+ // Must be signed by the account wishing to opt in to the asset
+ let rawSignedTxn = opttxn.signTxn(recoveredAccount3.sk);
+ let opttx = (await AlgorandClient.sendRawTransaction(rawSignedTxn).do());
+ // console.log("Transaction : " + opttx.txId);
+ // wait for transaction to be confirmed
+ await waitForConfirmation(AlgorandClient, opttx.txId);
+
+ //You should now see the new asset listed in the account information
+ // console.log("Account 3 = " + recoveredAccount3.addr);
+ await printAssetHolding(AlgorandClient, recoveredAccount3.addr, assetID);
+ //////////
+ showTaleData();
+ })().catch(e => {
+ // console.log(e);
+ console.trace();
+ Alert.alert('Your wallet should have atleast 0.451 ALGOS to opt In token and claim reward')
+ setOptInSuccessfull(false)
+ // setOptIn(false)
+ });
+
+ }
+ const showTaleData = async () => {
+ let accountInfo = await AlgorandClient.accountInformation(appCtx.walletAddress[0]?.address).do();
+ setAmount(accountInfo.amount / 1000000)
+ let array = [];
+
+ // setAccountAsset(accountInfo["assets"]);
+ if (accountInfo["assets"] === undefined) {
+ // setAccountAsset([]);
+ // document.getElementById('wallet_asset_div').innerHTML = 'No asset found
';
+ } else {
+ // console.log(accountInfo['assets'])
+ var assetobj = accountInfo['assets']
+ let assetUrl = [];
+ assetobj?.map((asset) => {
+ array = [...array, { key: asset['asset-id'], amount: asset.amount }]
+ })
+ // console.log(array);
+ }
+ const isassetIdPresent = array?.filter((assets) => {
+ return (assets.key == process.env.REACT_APP_TAIL_COIN_TOKEN)
+ })
+ if (isassetIdPresent?.length > 0) {
+ setTaleAmount((isassetIdPresent[0]?.amount) / 100)
+ // console.log(isassetIdPresent);
+ setOptInSuccessfull(false)
+ setOptIn(true);
+ }
+ else {
+ setOptIn(false)
+ // setOptInSuccessfull(false)
+ }
+
+ }
+ const handleOptIn = () => {
+ const isAssetIdPresent = accountAsset?.filter((asset) => { return asset.key === process.env.REACT_APP_TAIL_COIN_TOKEN });
+ if (isAssetIdPresent?.length === 0) {
+ try {
+ optInAsset(process.env.REACT_APP_TAIL_COIN_TOKEN)
+ }
+ catch {
+ setOptInSuccessfull(false)
+ Alert.alert('Your wallet should have atleast 0.451 ALGOS to opt In token and claim reward')
+ }
+ }
+ }
+ return {
+ accountAsset,
+ setAccountAsset,
+ amount,
+ setAmount,
+ assetUrl,
+ setAssetUrl,
+ appCtx,
+ handleOptIn,
+ showAssets,
+ optedIn,
+ taleAmount,
+ showTaleData,
+ setOptInSuccessfull,
+ optInSuccessfull
+ }
+}
diff --git a/NFTVerse/MobileApp/components/LiveRound/LiveRound.jsx b/NFTVerse/MobileApp/components/LiveRound/LiveRound.jsx
new file mode 100644
index 00000000..5fd0b288
--- /dev/null
+++ b/NFTVerse/MobileApp/components/LiveRound/LiveRound.jsx
@@ -0,0 +1,33 @@
+import { View, Text,Dimensions } from 'react-native'
+import React from 'react'
+import BlackPrimaryButton from '../common/BlackPrimaryButton';
+
+export default function LiveRound() {
+ const { width } = Dimensions.get('window');
+ const [slider, setSlider] = React.useState({ currentPage: 0 });
+
+ return (
+
+
+ Round 1/5
+
+ {Array.from(Array(5).keys()).map((key, index) => {
+ return (
+
+ )
+ })}
+
+
+
+
+ 11:11
+
+ Your Turn
+
+
+ )
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/Pages/Contest.jsx b/NFTVerse/MobileApp/components/Pages/Contest.jsx
new file mode 100644
index 00000000..bb646fbd
--- /dev/null
+++ b/NFTVerse/MobileApp/components/Pages/Contest.jsx
@@ -0,0 +1,83 @@
+import { Button, Image, ImageBackground, Pressable, SafeAreaView, ScrollView, Text, View } from 'react-native'
+import React, { Component } from 'react'
+import BlackPrimaryButton from '../common/BlackPrimaryButton'
+import { FlatList, TouchableOpacity } from 'react-native-gesture-handler'
+import { useSelector } from 'react-redux';
+
+export default function Contest({ navigation }) {
+ const matches = [{
+ heading: 'Play with 1 cards',
+ },
+ {
+ heading: 'Play with 1 cards',
+ },
+ {
+ heading: 'Play with 1 cards',
+ },
+ {
+ heading: 'Play with 1 cards',
+ }
+ ];
+ const appCtx = useSelector((state)=>state.app)
+ return (
+
+
+
+
+
+
+ Ongoing Contest
+ Completed Contest
+
+ (
+ <>
+ {isLoading ?
+
+
+
+
+
+ :
+
+ No incoming matches
+
+ }
+ >
+ )}
+ renderItem={({ item, index }) => {
+ return (
+ <>
+
+
+
+
+
+ {item?.heading}
+
+
+
+ { appCtx.walletAddress[0]?.address?navigation.navigate('JoinContest') : navigation.navigate('Wallet',{fromContest:true}) }}
+ >Play Now
+
+
+
+
+
+ >
+ )
+ }}
+ />
+
+ )
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/Pages/JoinContest.jsx b/NFTVerse/MobileApp/components/Pages/JoinContest.jsx
new file mode 100644
index 00000000..7f3c88e5
--- /dev/null
+++ b/NFTVerse/MobileApp/components/Pages/JoinContest.jsx
@@ -0,0 +1,33 @@
+import { View, Text, Image } from 'react-native'
+import React from 'react'
+import { ScrollView } from 'react-native-gesture-handler'
+import BlackPrimaryButton from '../common/BlackPrimaryButton'
+
+export default function JoinContest({ navigation }) {
+ return (
+
+
+
+ Rewards for this contest
+
+
+
+
+ one Card
+
+
+
+
+ 5 tokens
+
+
+
+
+ {navigation.navigate('LiveMatch',{card:Math.floor(Math.random()*7)})}}>Join the contest
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/Pages/LiveMatch.jsx b/NFTVerse/MobileApp/components/Pages/LiveMatch.jsx
new file mode 100644
index 00000000..dec8d82c
--- /dev/null
+++ b/NFTVerse/MobileApp/components/Pages/LiveMatch.jsx
@@ -0,0 +1,120 @@
+import { View, Text, Dimensions, Image, Alert } from 'react-native'
+import React from 'react'
+import { ScrollView } from 'react-native-gesture-handler'
+import BlackPrimaryButton from '../common/BlackPrimaryButton';
+import LiveRound from '../LiveRound/LiveRound';
+import TossModal from '../TossModal/TossModal';
+import ResultModal from '../modals/ResultModal';
+
+export default function LiveMatch({ navigation, route }) {
+ const [tossResult, setTossResult] = React.useState('default');
+ const [openModal, setOpenModal] = React.useState(true);
+ const [tossAgain, setTossAgain] = React.useState('no');
+ const [disabled, setDisabled] = React.useState(false);
+ const [openResultModal, setOpenResultModal] = React.useState(false);
+ const [result, setResult] = React.useState(false);
+
+ const [opponentCard, setOpponentCard] = React.useState([
+ {
+ image: require('../../assets/throwcard/p1.png')
+ },
+ {
+ image: require('../../assets/throwcard/p2.png')
+ },
+ {
+ image: require('../../assets/throwcard/p3.png')
+ },
+ {
+ image: require('../../assets/throwcard/p4.png')
+ },
+ {
+ image: require('../../assets/throwcard/p5.png')
+ },
+ {
+ image: require('../../assets/throwcard/p7.png')
+ }
+ ]);
+
+ React.useEffect(() => {
+ setOpenModal(true)
+ setTossResult('default')
+ }, [])
+ return (
+
+ {/* */}
+
+
+
+
+
+
+ #opponent
+
+
+ {Array.from(Array(5).keys()).map((key, index) => {
+ return (
+
+
+
+
+ )
+ })}
+
+
+ {tossResult === 'default' ?
+
+
+
+
+ :
+ <>
+
+
+
+
+
+
+ >
+ }
+ {route?.params?.thrown ?
+
+
+
+
+ :
+
+
+
+
+ }
+
+
+
+
+
+
+ {route?.params?.thrown ?
+ {
+ if (Math.floor(Math.random() * 10) % 2 === 0) {
+ setOpenResultModal(true)
+ setResult(true)
+ }
+ else {
+ setOpenResultModal(true)
+ setResult(false)
+ }
+ setDisabled(true);
+ }}
+ disabled={disabled}
+ >check
+ :
+ { navigation.navigate('ThrowCard', { card: route?.params?.card }) }}>Select your card
+ }
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/Pages/Marketplace.jsx b/NFTVerse/MobileApp/components/Pages/Marketplace.jsx
new file mode 100644
index 00000000..27f55c5b
--- /dev/null
+++ b/NFTVerse/MobileApp/components/Pages/Marketplace.jsx
@@ -0,0 +1,15 @@
+import { View, Text } from 'react-native'
+import React from 'react'
+import { ScrollView } from 'react-native-gesture-handler'
+
+export default function Marketplace() {
+ return (
+
+
+ Marketplace Coming Soon
+
+
+ )
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/Pages/ThrowCard.jsx b/NFTVerse/MobileApp/components/Pages/ThrowCard.jsx
new file mode 100644
index 00000000..32be0374
--- /dev/null
+++ b/NFTVerse/MobileApp/components/Pages/ThrowCard.jsx
@@ -0,0 +1,54 @@
+import { View, Text, Image } from 'react-native'
+import React from 'react'
+import LiveRound from '../LiveRound/LiveRound'
+import { ScrollView } from 'react-native-gesture-handler'
+import BlackPrimaryButton from '../common/BlackPrimaryButton'
+
+export default function ThrowCard({ navigation, route }) {
+ console.log(route);
+ return (
+
+ {/* */}
+
+
+
+
+
+
+
+ Match Played
+ 62
+
+
+ Total runs
+ 8
+
+
+ Wickets taken
+ 70
+
+
+
+
+ Highest score
+ 62
+
+
+ Stumping
+ 8
+
+
+
+
+ {
+ // route.params.setOpenModal(true)
+ // route.params.setTossResult('')
+ navigation.navigate('LiveMatch',{thrown:true,card:route?.params?.card})
+ }}>Throw Card
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/Pages/Wallet.jsx b/NFTVerse/MobileApp/components/Pages/Wallet.jsx
new file mode 100644
index 00000000..f313e99b
--- /dev/null
+++ b/NFTVerse/MobileApp/components/Pages/Wallet.jsx
@@ -0,0 +1,353 @@
+import axios from 'axios';
+import { REACT_APP_NFTVERSE_DEV_API, REACT_APP_URL_BLOCKCHAIN_SERVICE, REACT_APP_TAIL_COIN_TOKEN, REACT_APP_X_APP_TOKEN } from 'denv';
+import React, { FC, useEffect, useState } from 'react';
+import { ActivityIndicator, Linking } from 'react-native';
+import { Alert } from 'react-native';
+import { Image, ImageBackground, Text, TouchableOpacity, View, Pressable } from 'react-native';
+import { ScrollView } from 'react-native-gesture-handler';
+import { useDispatch, useSelector } from 'react-redux';
+import useAuthorizedHttp from '../../hooks/use-authorized-http';
+import useFetchToken from '../../hooks/useFetchToken';
+import useFetchNotification from '../../hooks/usePushNotification';
+import { appActions } from '../../store/app-slice';
+import AddressBar from '../authorized-view/AddressBar';
+import AssetsView from '../authorized-view/assets/AssetsView';
+import BlackPrimaryButton from '../common/BlackPrimaryButton';
+import FetchwalletBalance from '../CommonComponent/fetchwalletBalance';
+
+const Wallet= ({ navigation, route }) => {
+ const [wallet, setWallet] = useState([{ address: '' }]);
+ const [loading, setLoading] = useState(true);
+ const [walletCreationProgress, setWalletCreationProgress] = useState(0);
+ const [openInfoModal, setOpenInfoModal] = useState(false);
+ const [openFirstUserWalletScreen, setOpenFirstUSerWalletScreen] = useState(false);
+ const [openSetupPasswordModal, setOpenSetupPasswordModal] = useState(false);
+ const [chosenTab, setChosenTab] = useState('nfts');
+ const makeRequest = useAuthorizedHttp();
+ const dispatch = useDispatch();
+ const appCtx = useSelector((state) => state.app);
+ const { balance, fetchAlgos } = FetchwalletBalance();
+ const [optInLoader, setOptInLoader] = useState(false)
+ const { tokenAmount, optedIn, setOptedIn, fetch } = useFetchToken();
+
+ useEffect(() => {
+ fetch();
+ fetchAlgos();
+ }, [])
+
+ const loadData1 = React.useCallback(() => {
+ // user/5GFS77UHBLQJ6DIZMZAIJKTOKZQ5HYWOX4QVIACVNFW32E22O7B2Q3OICI/list
+ // ${appCtx.walletAddress[0]?.address}
+
+ let config = {
+ url: `${REACT_APP_URL_BLOCKCHAIN_SERVICE}/user/${appCtx.walletAddress[0]?.address}/list`,
+ method: 'get',
+ headers: {
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ "X-Auth-Token": appCtx.authToken,
+ "Content-Type": "application/json",
+ }
+ }
+ console.log(config);
+
+ axios(config)
+ .then(function (response) {
+ console.log(response);
+ // setBalance(response?.data?.balance);
+ // dispatch(appActions.setFrontSide(response.data?.fileUrl));
+ })
+ .catch(function (error) {
+ console.log(error);
+ // toast.error('Uploading Back Side failed!');
+ })
+ }, [])
+ useEffect(() => { loadData1() }, [])
+
+
+ useEffect(() => {
+ // if (appCtx.walletAddress[0]?.address!==='loading') {
+ // if (appCtx.authToken) {
+ // if (decryptedData === '') {
+ makeRequest(
+ {
+ url: `${REACT_APP_URL_BLOCKCHAIN_SERVICE}/user/blockchain/account?blockchain=FLOW`,
+
+ },
+ (data) => {
+ const walletData = data?.filter((account) => { return (account?.wallet === "TALEWALLET") });
+ setWallet(walletData);
+ dispatch(appActions.setWalletAddress(walletData));
+ if (walletData?.length === 0) {
+ setOpenFirstUSerWalletScreen(true);
+ }
+ console.log(data);
+
+ },
+ () => {
+ setLoading(false);
+ },
+ () => {
+ // navigate('/logout')
+ }
+ );
+ // }
+ // }
+ }, [dispatch, makeRequest]);
+
+ useEffect(() => {
+
+ if (wallet && wallet.length === 0) {
+ setWalletCreationProgress(0);
+ setTimeout(() => {
+ setWalletCreationProgress(1);
+ setTimeout(() => {
+ makeRequest(
+ {
+ url: `${REACT_APP_URL_BLOCKCHAIN_SERVICE}/user/blockchain/wallet/setup`,
+ method: "post",
+ data: {
+ blockchain: "FLOW",
+ wallet: "TALEWALLET",
+ marketplaceAddress: "cricTales",
+ },
+ },
+ (data) => {
+ setTimeout(() => {
+ setWallet([data]);
+ dispatch(appActions.setWalletAddress([data]));
+ if(route?.params?.fromContest){
+ navigation.navigate('contest')
+ }
+ }, 1000);
+ },
+ (data) => {
+
+ },
+ () => {
+ setWalletCreationProgress(2);
+ }
+ );
+ }, 1000);
+ }, 1000);
+ }
+ }, [loading, makeRequest, wallet]);
+
+ const handlePress = React.useCallback(async (url) => {
+ // Checking if the link is supported for links with custom URL scheme.
+ const supported = await Linking.canOpenURL(url);
+
+ if (supported) {
+ // Opening the link with some app, if the URL scheme is "http" the web link should be opened
+ // by some browser in the mobile
+ await Linking.openURL(url);
+ } else {
+ Alert.alert(`${url} is Invalid !!`);
+ }
+ }, []);
+
+
+ const handleCustodialOptIn = () => {
+ setOptInLoader(true);
+ if (balance >= 0.451) {
+ axios({
+ method: 'get',
+ url: `${REACT_APP_URL_BLOCKCHAIN_SERVICE}/asset/${REACT_APP_TAIL_COIN_TOKEN}/optin`,
+ headers: {
+ "Content-Type": "application/json",
+ "X-Auth-Token": appCtx.authToken
+ }
+ }).then((res) => {
+ setOptInLoader(false);
+ setOptedIn(true);
+ })
+ .catch(() => {
+ setOptInLoader(false);
+ Alert.alert('Failed to optIn asset unsuccessfull')
+ })
+ }
+ else {
+ Alert.alert('Your wallet should have atleast 0.451 ALGOS to opt In Tale Coin Token')
+ setOptInLoader(false);
+ }
+
+ }
+ // const { expoPushToken, notification, sendPushNotification } = useFetchNotification();
+ // console.log(expoPushToken, notification);
+ // console.log('heygfcyiugyefcgq', chosenTab);
+ // useEffect(() => {
+ // console.log(notification, expoPushToken);
+
+ // const func = () => {
+ // sendPushNotification(expoPushToken);
+ // }
+ // func();
+ // }, [expoPushToken]);
+
+ return (
+ <>
+ {
+ wallet?.length === 0 ?
+
+ 0 ? "border-green-500" : "border-gray-400"} opacity-0 ${walletCreationProgress >= 0 && "opacity-100"
+ } transition-all duration-500 ease-out border-2 p-5 rounded-lg text-center gap-5 text-xl w-[100%] lg:w-[400px] flex flex-row justify-center pt-2`}
+ >
+ 0 ? "text-green-500" : ""}`}>1.
+ 0 ? "text-green-500" : ""}`}>Setting up wallet
+
+ {walletCreationProgress > 0 ? (
+ //
+
+ ) : (
+ ''
+ //
+ )}
+
+
+ 1 ? "border-green-500" : "border-gray-400"} opacity-0 ${walletCreationProgress >= 1 && "opacity-100"
+ } transition-all duration-500 ease-out border-2 p-5 rounded-lg text-center gap-5 text-xl w-[100%] lg:w-[400px] flex flex-row justify-center items-center pt-2`}
+ >
+ 1 ? "text-green-500" : ""}`}>2.
+ 1 ? "text-green-500" : ""}`}>Adding NFT capability
+
+ {walletCreationProgress > 1 ? (
+ //
+
+ ) : (
+ ''
+ //
+ )}
+
+
+
+ Wallet Ready
+
+
+ :
+ <>
+
+
+
+
+
+
+
+ {/* {balance} Algos { fetchAlgos() }} className={``}> */}
+ {/*
+ { handlePress('https://ramp.alchemypay.org/#/index') }}>Buy
+ {
+ navigation.navigate("SendAlgosOrAssests")
+ sendPushNotification(expoPushToken);
+ }}>Send
+ */}
+
+ {
+ fetchAlgos();
+ setChosenTab('nfts')
+ }}>
+ NFTs
+
+ {/* {
+ fetch();
+ setChosenTab('tokens')
+ }}>
+ Tokens
+ */}
+
+ {chosenTab === 'tokens' ?
+ <>
+ { navigation.navigate('TaleCoin'), { tokenAmount } }} >
+
+
+ { navigate(`/talecoin`)
+ // }}
+ >
+
+ {/* */}
+
+
+
+
+ {tokenAmount || 0} Tale
+
+ {/* {taleAmount} */}
+
+
+
+ {/* optIn */}
+ {
+
+ handleCustodialOptIn();
+ }}
+ // disabled={optInSuccessfull}
+ >
+ {!optedIn && 'Opt In'}
+ {optInLoader && }
+
+
+
+
+
+
+ {
+ appCtx.taleAmount?.map((item) => {
+ if (item.assetId !== REACT_APP_TAIL_COIN_TOKEN) {
+ return (
+ <>
+
+
+
+
+ {/* */}
+
+
+
+
+ {item?.amount} {item?.params?.name}
+
+ {/* {taleAmount} */}
+
+
+
+
+ >
+ )
+ }
+ })
+ }
+ >
+ :
+ <>
+
+ {/* {
+ navigation.navigate('UploadNft')
+ }}
+ className='text-[15px] font-bold fixed left-[] bottom-[120px] z-20'
+ >
+ Add Nft+
+ */}
+ >
+ }
+
+ >
+
+ }
+ >
+ );
+
+};
+
+export default Wallet;
diff --git a/NFTVerse/MobileApp/components/SpinTheWheel/SpinTheWheel.jsx b/NFTVerse/MobileApp/components/SpinTheWheel/SpinTheWheel.jsx
new file mode 100644
index 00000000..f60bbf88
--- /dev/null
+++ b/NFTVerse/MobileApp/components/SpinTheWheel/SpinTheWheel.jsx
@@ -0,0 +1,194 @@
+import { View, Text, Image, StyleSheet, Alert } from 'react-native'
+import React, { useCallback } from 'react'
+import BlackPrimaryButton from '../common/BlackPrimaryButton'
+import { REACT_APP_X_APP_TOKEN } from 'denv';
+import { useSelector } from 'react-redux';
+import axios from 'axios';
+import { TouchableHighlight } from 'react-native-gesture-handler';
+
+export default function SpinTheWheel({navigation}) {
+ const appCtx = useSelector((state) => state.app)
+ const [reward, setReward] = React.useState([
+ {
+ rewardsValue: { image: require('../../assets/wheel/spin1.png') }
+ },
+ {
+ rewardsValue: { image: require('../../assets/wheel/spin2.png') }
+ },
+ {
+ rewardsValue: { image: require('../../assets/wheel/spin3.png') }
+ },
+ {
+ rewardsValue: { image: require('../../assets/wheel/spin4.png') }
+ },
+ {
+ rewardsValue: { image: require('../../assets/wheel/spin5.png') }
+ },
+ {
+ rewardsValue: { image: require('../../assets/wheel/spin6.png') }
+ },
+ ]);
+ const [result, setResult] = React.useState(null);
+
+ const [metaData, setMetaData] = React.useState('Nothing');
+ const [showColor, setShowColor] = React.useState(['blue']);
+ const [opponentCard, setOpponentCard] = React.useState([
+ {
+ image: require('../../assets/throwcard/p1.png')
+ },
+ {
+ image: require('../../assets/throwcard/p2.png')
+ },
+ {
+ image: require('../../assets/throwcard/p3.png')
+ },
+ {
+ image: require('../../assets/throwcard/p4.png')
+ },
+ {
+ image: require('../../assets/throwcard/p5.png')
+ },
+ {
+ image: require('../../assets/throwcard/p7.png')
+ }
+ ]);
+ // const loadData1 = React.useCallback(() => {
+
+ // let config = {
+ // url: `http://gs-dev.api.onnftverse.com/v1/game/1/spin/items`,
+ // method: 'get',
+ // headers: {
+ // // "X-App-Token": REACT_APP_X_APP_TOKEN,
+ // "X-Auth-Token": appCtx.authToken,
+ // "Content-Type": "application/json",
+ // }
+ // }
+ // console.log(config);
+
+ // axios(config)
+ // .then(function (response) {
+ // setReward(response?.data);
+ // })
+ // .catch(function (error) {
+ // console.log(error);
+ // })
+ // }, [reward])
+ // React.useEffect(() => {
+ // loadData1();
+ // }, [])
+ const handleShowReward = useCallback(() => {
+ let config = {
+ url: `http://gs-dev.api.onnftverse.com/v1/game/${Math.floor(Math.random()*100)}/spin/result`,
+ method: 'get',
+ headers: {
+ // "X-App-Token": REACT_APP_X_APP_TOKEN,
+ "X-Auth-Token": appCtx.authToken,
+ "Content-Type": "application/json",
+ }
+ }
+ console.log(config);
+
+ axios(config)
+ .then(function (response) {
+ let randomReward = opponentCard[Math.floor(Math.random()*6)];
+ // console.log('====================================');
+ // console.log(randomReward,Math.floor(Math.random()*6));
+ // console.log('====================================');
+ metaDataImage = (randomReward)?.image
+ setMetaData(metaDataImage);
+ setResult(response?.data);
+ })
+ .catch(function (error) {
+ Alert.alert('try agiain later')
+ })
+ }, [result])
+ let i = 0, metaDataImage = 'Nothing';
+ let simulateSpinningWheel = (callback) => {
+ //array of colors
+ const color = ["pink", "red", "orange", "blue", "green", "lightblue"];
+ let showColor = 0;//use to iterate through color array
+
+
+ let timerId = setInterval(() => {
+
+ setShowColor(color[showColor])
+ let randomReward = reward[showColor];
+ console.log(randomReward);
+ metaDataImage = randomReward?.rewardsValue && (randomReward?.rewardsValue)?.image;
+ setMetaData(metaDataImage);
+ console.log(metaDataImage);
+ showColor++;
+ if (showColor === color.length-1) {
+ showColor = 0;
+ }
+ }, 1000);
+
+ setTimeout(() => {
+ clearInterval(timerId); //use the timer id to clear the interval
+ //showColor = 0;
+ handleShowReward()
+ }, 10000);
+ // }
+ }
+ React.useEffect(() => {
+ simulateSpinningWheel();
+ }, [])
+
+ return (
+
+ {/* {metaData}
+
+ Stop the spin
+ */}
+
+ {
+ result && Congratulations !!!
+ }
+ {
+ result ?
+
+
+ {/* {metaData} */}
+
+
+
+ :
+
+
+ {/* {metaData} */}
+
+
+
+ }
+ {
+ result && {navigation.navigate('Wallet')}}>Claim your reward
+ }
+
+
+ )
+}
+const styles = StyleSheet.create({
+ container: {
+ //flex: 1,
+ alignItems: "center",
+ justifyContent: "center",
+ //alignSelf: "stretch", //stretch the area of the container across the screen
+ marginTop: -50,//fix a issue with the inside the "MainScreen" container in that the "Score" component was hidden under the buttons.
+ },
+ wheel: {
+ //flex: 1,
+ //backgroundColor:{props.newColor},
+ // borderRadius:100,
+ width: 175,
+ height: 175,
+ alignItems: "center",
+ justifyContent: "center",
+ },
+ awardText: {
+ color: "white",
+ fontSize: 24,
+ fontWeight: "bolder",
+ },
+});
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/TossModal/TossModal.jsx b/NFTVerse/MobileApp/components/TossModal/TossModal.jsx
new file mode 100644
index 00000000..7f2708f5
--- /dev/null
+++ b/NFTVerse/MobileApp/components/TossModal/TossModal.jsx
@@ -0,0 +1,68 @@
+import React from 'react';
+import { Modal, Text, View, Image, Pressable } from 'react-native';
+import BlackPrimaryButton from '../common/BlackPrimaryButton';
+
+const TossModal = ({ openModal, setOpenModal, tossResult, setTossResult, setTossAgain }) => {
+ const handleToss = React.useCallback((pick) => {
+ if (Math.floor(Math.random()*2) % 2 === pick) {
+ setTossResult(true);
+ }
+ else {
+ setTossResult(false)
+ }
+ }, [tossResult])
+ const onClose = React.useCallback(
+ () => {
+ setOpenModal(false)
+ setTossAgain(true)
+ },
+ [openModal],
+ )
+
+ return (
+
+
+
+ {tossResult=='default' ? <>
+ Select Head or Tail for the toss
+
+ { handleToss(2) }}>
+
+
+ Head
+
+ { handleToss(1) }}>
+
+
+ Tail
+
+
+
+ >
+ :
+ <>
+ {!tossResult ?
+ <>
+ OOPs.. No
+ You Lost the toss !!
+ >
+ :
+ <>
+ Congratulations
+ You won the toss !!
+ >
+ }
+
+ Continue
+
+ >
+ }
+
+
+
+ );
+};
+
+export default TossModal;
diff --git a/NFTVerse/MobileApp/components/authorized-view/Activity.tsx b/NFTVerse/MobileApp/components/authorized-view/Activity.tsx
new file mode 100644
index 00000000..cf40033b
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/Activity.tsx
@@ -0,0 +1,174 @@
+import axios from 'axios';
+import { REACT_APP_ALGOEXPLORER_ADDRESS, REACT_APP_ALGORAND_TRANSACTION, REACT_APP_GATEWAY_ALGOEXPLORER } from 'denv';
+import React, { useCallback } from 'react';
+import { Alert, Linking, View } from 'react-native';
+import { FlatList, ScrollView, TouchableOpacity } from 'react-native-gesture-handler';
+import { Text } from 'react-native-paper';
+import { useSelector } from 'react-redux';
+import { StoreStateType } from '../../misc/types';
+import { jsonToCSV } from 'react-native-csv'
+import TransactionSkeletonLoader from '../skeletonLoader/TransactionSkeletonLoader';
+
+const Activity = () => {
+ const [transaction, setTransaction] = React.useState([]);
+ const appCtx = useSelector((state: StoreStateType) => state.app)
+
+ const handlePress = useCallback(async (url: string) => {
+ // Checking if the link is supported for links with custom URL scheme.
+ const supported = await Linking.canOpenURL(url);
+
+ if (supported) {
+ // Opening the link with some app, if the URL scheme is "http" the web link should be opened
+ // by some browser in the mobile
+ await Linking.openURL(url);
+ } else {
+ Alert.alert(`${url} is Invalid !!`);
+ }
+ }, []);
+
+
+ const handleDownload = () => {
+ let array = [{}];
+ let csv = 'amount,sender,reciever,type\n'
+ transaction?.map((tran: any) => {
+ let type = tran['asset-transfer-transaction']?.amount ? tran['asset-transfer-transaction']?.amount : tran['payment-transaction']?.amount ? tran['payment-transaction']?.amount : '0';
+ let type1 = type === 0 ? 'OptedIn' : 'Transfer'
+ csv +=
+ tran['asset-transfer-transaction']?.amount ? tran['asset-transfer-transaction']?.amount / 1000000 : tran['payment-transaction']?.amount ? tran['payment-transaction']?.amount / 1000000 : '0' + ',' +
+ tran?.sender?.substring(0, 10) || null + ',' +
+ tran['asset-transfer-transaction']?.receiver?.substring(0, 10) || tran['payment-transaction']?.receiver?.substring(0, 10) + ',' +
+ type1 + '\n'
+ array = [...array, {
+ amount: tran['asset-transfer-transaction']?.amount ? tran['asset-transfer-transaction']?.amount / 1000000 : tran['payment-transaction']?.amount ? tran['payment-transaction']?.amount / 1000000 : '0',
+ sender: tran?.sender?.substring(0, 10) || null,
+ reciever: tran['asset-transfer-transaction']?.receiver?.substring(0, 10) || tran['payment-transaction']?.receiver?.substring(0, 10),
+ type: type1
+ }]
+
+ })
+ // array.forEach(function(row) {
+ // csv += row.join(',');
+ // csv += "\n";
+ // });
+ const results = jsonToCSV(array);
+ // var hiddenElement = document.createElement('a');
+ // hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
+ // hiddenElement.target = '_blank';
+
+ //provide the name for the CSV file to be downloaded
+ // hiddenElement.download = 'Famous Personalities.csv';
+ // hiddenElement.click();
+
+ }
+ const [isLoading, setIsLoading] = React.useState(false);
+
+ const loadData = React.useCallback(() => {
+ setIsLoading(true)
+ axios(`${REACT_APP_ALGORAND_TRANSACTION}${appCtx.walletAddress[0]?.address}/transactions?limit=100`)
+ .then((res) => {
+ setIsLoading(false)
+ console.log(res.data.transactions);
+ setTransaction(res.data.transactions || []);
+ })
+ .catch((rej) => {
+ setIsLoading(false)
+ setTransaction([])
+ })
+ }, [])
+
+ React.useEffect(() => {
+ loadData();
+ }, [])
+ return (
+ <>
+
+
+
+ Activity
+ {/* Downoad CSV */}
+
+ {
+ isLoading ?
+ <>
+ {/* */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* */}
+ >
+ :
+ transaction?.length !== 0 ?
+ transaction?.map((tran: any) => {
+ let type = tran['asset-transfer-transaction']?.amount ? tran['asset-transfer-transaction']?.amount : tran['payment-transaction']?.amount ? tran['payment-transaction']?.amount : '0';
+
+ return (
+
+
+
+ { handlePress(`${REACT_APP_GATEWAY_ALGOEXPLORER}${tran?.id}`) }}>txid: {tran?.id?.substring(0, 10)}...
+
+
+
+
+
+ Amount
+ {/* {tran?.sender?.substring(0, 10) || null}... */}
+
+
+ {tran['asset-transfer-transaction']?.amount ? tran['asset-transfer-transaction']?.amount / 1000000 : tran['payment-transaction']?.amount ? tran['payment-transaction']?.amount / 1000000 : '0'}
+
+
+
+
+ Sender
+
+
+ { handlePress(`${REACT_APP_ALGOEXPLORER_ADDRESS}${tran?.sender}`) }}>{tran?.sender?.substring(0, 10) || null}...
+
+
+
+
+ Reciever
+
+
+ { handlePress(`${process.env.REACT_APP_REACT_APP_ALGOEXPLORER_ADDRESS}${tran['asset-transfer-transaction']?.receiver || tran['payment-transaction']?.receiver}`) }}>{tran['asset-transfer-transaction']?.receiver?.substring(0, 10) || tran['payment-transaction']?.receiver?.substring(0, 10)}...
+
+
+
+
+ Type
+
+ {type === '0' ? 'Opt In' : 'transfer'}
+ {/*
+ -1.00 Algo
+ */}
+
+
+
+ )
+ })
+ :
+
+ No Transactions found
+
+ }
+
+ >
+ )
+};
+
+export default Activity;
diff --git a/NFTVerse/MobileApp/components/authorized-view/AddressBar.jsx b/NFTVerse/MobileApp/components/authorized-view/AddressBar.jsx
new file mode 100644
index 00000000..8942a09a
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/AddressBar.jsx
@@ -0,0 +1,23 @@
+import React from 'react'
+import { Text, TouchableOpacity, View, Image } from 'react-native'
+import { useSelector } from 'react-redux';
+import * as Clipboard from 'expo-clipboard';
+
+
+export default function AddressBar() {
+ const appCtx = useSelector((state) => state.app);
+
+ const copyToClipboard = () => {
+ Clipboard.setString(appCtx?.walletAddress[0]?.address)
+ }
+ return (
+
+
+
+ {appCtx.walletAddress[0]?.address?.substring(0, 15) || 'loading'}...
+ { copyToClipboard() }}>
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/authorized-view/CrickTales.code-workspace b/NFTVerse/MobileApp/components/authorized-view/CrickTales.code-workspace
new file mode 100644
index 00000000..0ed8cbf2
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/CrickTales.code-workspace
@@ -0,0 +1,9 @@
+{
+ "folders": [
+ {
+ "name": "my-app",
+ "path": "../.."
+ }
+ ],
+ "settings": {}
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/authorized-view/CustomTabBar.jsx b/NFTVerse/MobileApp/components/authorized-view/CustomTabBar.jsx
new file mode 100644
index 00000000..d7e70f9b
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/CustomTabBar.jsx
@@ -0,0 +1,63 @@
+import React from 'react';
+import { Keyboard, Text, TouchableOpacity, View } from 'react-native';
+import { BottomTabBarProps } from '@react-navigation/bottom-tabs';
+
+const CustomTabBar = ({ state, descriptors, navigation }) => {
+ const [keyboardHidden, setKeyboardHidden] = React.useState(true);
+
+ React.useEffect(() => {
+ const showListener = Keyboard.addListener('keyboardDidShow', () => {
+ setKeyboardHidden(false);
+ });
+ const hideListener = Keyboard.addListener('keyboardDidHide', () => {
+ setKeyboardHidden(true);
+ });
+ return () => {
+ showListener.remove();
+ hideListener.remove();
+ };
+ }, []);
+
+ return (
+
+ {state.routes.map((route, index) => {
+ const { options } = descriptors[route.key];
+
+ const label = route.name;
+ const iconName = options.tabBarIcon;
+
+ const isFocused = state.index === index;
+
+ const onPress = () => {
+ const event = navigation.emit({
+ type: 'tabPress',
+ target: route.key,
+ canPreventDefault: true,
+ });
+ if (!isFocused && !event.defaultPrevented) {
+ navigation.navigate(route.name);
+ }
+ };
+
+ return (
+
+ {/* ${isFocused ? 'bg-black' : 'bg-gray-300'
+ } */}
+
+ {iconName && iconName({ color: '', size: 0, focused: isFocused })}
+
+ {label}
+
+
+
+ );
+ })}
+
+ );
+};
+
+export default CustomTabBar;
diff --git a/NFTVerse/MobileApp/components/authorized-view/Header.jsx b/NFTVerse/MobileApp/components/authorized-view/Header.jsx
new file mode 100644
index 00000000..aa22324d
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/Header.jsx
@@ -0,0 +1,34 @@
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { NativeStackNavigationProp } from '@react-navigation/native-stack';
+import React, { FC } from 'react';
+import { Image, Pressable, Text, View } from 'react-native';
+import { TouchableOpacity } from 'react-native-gesture-handler';
+
+
+const Header = ({ navigation }) => {
+ const Tab = createBottomTabNavigator();
+ const handleProfile = React.useCallback(() => {
+ console.log(navigation);
+
+ navigation?.navigate('ProfileOptions')
+ }, [navigation]);
+
+ return (
+
+ {navigation?.navigate('Wallet')}} className="flex flex-row items-center">
+
+ Crick Tales
+
+ {navigation &&
+
+
+
+ }
+
+ );
+};
+
+export default Header;
diff --git a/NFTVerse/MobileApp/components/authorized-view/assets/AssetDetailView.jsx b/NFTVerse/MobileApp/components/authorized-view/assets/AssetDetailView.jsx
new file mode 100644
index 00000000..e0c4e32a
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/assets/AssetDetailView.jsx
@@ -0,0 +1,323 @@
+import React, { useEffect, useState } from 'react';
+import { Alert, FlatList, Image, Linking, ScrollView, Text, TouchableOpacity, View, VirtualizedList } from 'react-native';
+import CollapsableView from './CollapsableView';
+import AssetsView from './AssetsView';
+import { REACT_APP_ALGOEXPLORER_ADDRESS, REACT_APP_GATEWAY_IPFS } from 'denv';
+import { ResizeMode, Video } from 'expo-av';
+
+const AssetDetailView = ({ route }) => {
+ const nftDomain =route?.params?.nfts;
+ const assetMetadata = route?.params?.metaData;
+ // JSON?.parse(nftDomain?.metaData);
+ console.log(assetMetadata);
+
+ const [property, setProperty] = useState([{key:'',value:''}]);
+ console.log(nftDomain);
+ // console.log(assetMetadata);
+ useEffect(() => {
+ setProperty(assetMetadata?.properties?.length? assetMetadata?.properties : assetMetadata?.properties && Object?.entries(assetMetadata?.properties)?.map((e) => ({ [e[0]]: e[1] })))
+ }, [assetMetadata?.properties])
+ let obj = [];
+
+ property?.map((item) => {
+ for (var i in item) {
+ obj = [...obj, { key: i, value: item[i] }]
+ }
+ })
+ const handlePress = React.useCallback(async (url) => {
+ // Checking if the link is supported for links with custom URL scheme.
+ const supported = await Linking.canOpenURL(url);
+
+ if (supported) {
+ // Opening the link with some app, if the URL scheme is "http" the web link should be opened
+ // by some browser in the mobile
+ await Linking.openURL(url);
+ } else {
+ Alert.alert(`${url} is Invalid !!`);
+ }
+ }, []);
+
+ return (
+
+
+
+
+ {assetMetadata?.name}
+
+ {/*
+
+
+
+ */}
+
+
+
+ {assetMetadata?.mime_type?.split('/')[0] === 'text' ? (
+ {assetMetadata?.name}
+ ) : assetMetadata?.mime_type?.split('/')[0] === 'image' || assetMetadata?.type === 'image' ? (
+
+ ) : (
+
+ )}
+
+ {/*
+
+
+
+
+ Creator
+ guywhodoodles
+
+
+
+
+
+ Current owner
+ guywhodoodles
+
+
+
+
+
+
+ Ethereum
+
+
+
+ 320
+
+
+
+ 12
+
+
+ */}
+ {/*
+
+ Price
+ */}
+ {/* {assetMetadata.price || nftDomain.price}{' '} */}
+ {/* {nftDomain.priceUnit && nftDomain.priceUnit.toUpperCase()} */}
+ {/*
+
+ $ */}
+ {/* {Number(1500.65 * ((assetMetadata.price || nftDomain.price) as unknown as number))
+ .toFixed(2)
+ .toString()} */}
+ {/*
+
+
+
+ Current bid by
+ 0xj3js...3htj
+
+ 2 ETH
+ $3000
+
+ */}
+
+ }
+ body={
+
+ {/* About this item */}
+ {assetMetadata?.description}
+ {/* About "{assetMetadata.collection}"
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, nisl nec */}
+
+ }
+ />
+
+ }
+ body={
+ (
+ Uh-oh! No properties found.
+ )}
+ data={obj}
+ renderItem={({ item, index }) => (
+
+ {item?.key}
+ {item?.value }
+
+ )}
+ numColumns={3}
+ className={'flex flex-row flex-wrap gap-3'}
+ />
+ }
+ />
+
+ }
+ body={
+
+ NFT Standard {assetMetadata?.standard || 'arc69'} asset
+ {handlePress(`${REACT_APP_ALGOEXPLORER_ADDRESS}${nftDomain?.params?.creator}`)}}>Mint Address: {nftDomain?.params?.creator?.substr(0,13)}...
+ {/* Show mined address */}
+
+ }
+ />
+
+
+
+
+
+ Creator address
+ {/* {nftDomain?.params?.creator?.substr(0,13)}... */}
+
+ {nftDomain?.params?.creator?.substr(0,13)}...
+
+
+
+
+
+
+ Manager address
+ {/* guywhodoodles */}
+
+ {nftDomain?.params?.manager?.substr(0,13)}...
+
+
+
+
+ }
+ />
+
+ //
+ //
+ //
+ // 2 ETH
+ // $3000
+ // by 0xm3md...j23k
+ //
+ //
+ //
+ // Accept
+ //
+ //
+ // Decline
+ //
+ //
+ //
+ //
+ //
+ //
+ // 2 ETH
+ // $3000
+ // by 0xm3md...j23k
+ //
+ //
+ //
+ // Accept
+ //
+ //
+ // Decline
+ //
+ //
+ //
+ //
+ //
+ //
+ // 2 ETH
+ // $3000
+ // by 0xm3md...j23k
+ //
+ //
+ //
+ // Accept
+ //
+ //
+ // Decline
+ //
+ //
+ //
+ //
+ No Activities to display
+ }
+ />
+ {/* More from this collection */}
+ {/* */}
+
+ );
+};
+
+export default AssetDetailView;
diff --git a/NFTVerse/MobileApp/components/authorized-view/assets/AssetItemView.jsx b/NFTVerse/MobileApp/components/authorized-view/assets/AssetItemView.jsx
new file mode 100644
index 00000000..6e7a59d4
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/assets/AssetItemView.jsx
@@ -0,0 +1,132 @@
+import React, { useEffect } from 'react';
+import { Image, ImageBackground, Pressable, Text, View } from 'react-native';
+import { REACT_APP_GATEWAY_IPFS } from 'denv';
+import { ResizeMode, Video } from 'expo-av';
+import { Linking } from 'react-native';
+import { Alert } from 'react-native';
+
+const AssetItemView = ({ nft, onClick }) => {
+ const [metaData, setMetaData] = React.useState(null);
+ const [src, setSrc] = React.useState('')
+
+ let ipfs = nft?.params?.url?.split('/');
+
+ const fetchData = async () => {
+ fetch(`${REACT_APP_GATEWAY_IPFS}/${ipfs[ipfs?.length - 1]}`).then((response) => {
+ return response.json();
+ }).then((data) => {
+
+ if (nft?.params?.total?.length === 1) {
+ setMetaData(data);
+ }
+ })
+ .catch((rej) => {
+ // console.log(rej);
+ })
+ }
+
+ const handlePress = React.useCallback(async (url) => {
+ // Checking if the link is supported for links with custom URL scheme.
+ const supported = await Linking.canOpenURL(url);
+
+ if (supported) {
+ // Opening the link with some app, if the URL scheme is "http" the web link should be opened
+ // by some browser in the mobile
+ await Linking.openURL(url);
+ } else {
+ Alert.alert(`${url} is Invalid !!`);
+ }
+ }, []);
+
+ useEffect(() => {
+ fetchData();
+ }, [])
+ // handlePress(`https://www.talewallet.com/asset/${nft?.assetId}`)
+
+ return (
+ <>
+
+ {metaData && (
+
+ { (metaData?.mime_type?.split('/')[0] === 'threeD' || metaData?.type === 'threeD') ? handlePress(`https://www.talewallet.com/asset/${nft?.assetId}`) : onClick(metaData, nft) }}
+ className={'rounded-xl mx-2 my-2 bg-white shadow-xl shadow-black/50'}
+ >
+
+ {metaData?.mime_type?.split('/')[0] === 'text' ? (
+ {metaData?.name}
+ ) :
+ metaData?.mime_type?.split('/')[0] === 'image' || metaData?.type === 'image' ? (<>
+
+
+ >
+ ) : metaData?.mime_type?.split('/')[0] === 'video' || metaData?.type === 'video' ? (
+
+ ) :
+ metaData?.mime_type?.split('/')[0] === 'threeD' || metaData?.type === 'threeD' ?
+ //
+
+ Click To View 3D
+
+ :
+ <>>
+ }
+
+ {/*
+ {metaData?.name}
+
+
+ 20
+
+ */}
+
+
+ Price
+ {/* {metaData?.price} Algo */}
+
+
+ {nft?.amount} Algo
+ {/* 2 Algo */}
+
+
+
+
+ {metaData?.name}
+
+
+ )
+ // :
+ //
+ // No NFTs found
+ //
+ }
+ >
+ );
+};
+
+export default AssetItemView;
diff --git a/NFTVerse/MobileApp/components/authorized-view/assets/AssetsView.jsx b/NFTVerse/MobileApp/components/authorized-view/assets/AssetsView.jsx
new file mode 100644
index 00000000..a24bf036
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/assets/AssetsView.jsx
@@ -0,0 +1,98 @@
+import React, { FC, useEffect } from 'react';
+import { FlatList, Text, View } from 'react-native';
+import useAuthorizedHttp from '../../../hooks/use-authorized-http';
+import { useDispatch, useSelector } from 'react-redux';
+import useHttp from '../../../hooks/use-http';
+import AssetItemView from './AssetItemView';
+import NftViewSkeleton from './NftViewSkeleton';
+import { REACT_APP_URL_BLOCKCHAIN_SERVICE, REACT_APP_X_APP_TOKEN } from 'denv';
+
+const AssetsView = ({ navigation }) => {
+ const makeAuthorizedRequest = useAuthorizedHttp();
+ const makeRequest = useHttp();
+ const userId = useSelector((state) => state.app.user.userId);
+ const [nfts, setNfts] = React.useState([]);
+ const [isLoading, setIsLoading] = React.useState(true);
+ const appCtx = useSelector((state) => state.app);
+ const dispatch = useDispatch();
+
+ const loadData = React.useCallback(() => {
+ setIsLoading(true);
+ // ${appCtx.walletAddress[0]?.address}
+ makeAuthorizedRequest(
+ {
+ method: 'get',
+ url: `${REACT_APP_URL_BLOCKCHAIN_SERVICE}/user/${appCtx.walletAddress[0]?.address}/list`,
+ headers: {
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ "X-Auth-Token": appCtx.authToken,
+ "Content-Type": "application/json",
+ }
+ },
+ data => {
+ // setNfts(data.content);
+ let nftArray= [];
+ data.content?.map((item) => {
+ if (item?.params?.total?.length == 1) {
+ nftArray = [...nftArray, item]
+ }
+ })
+ setNfts(nftArray)
+ // dispatch(appActions.setTaleAmount(tokenArray));
+
+ },
+ error => console.log(error),
+ () => setIsLoading(false),
+ );
+ }, [makeRequest]);
+
+ useEffect(loadData, [loadData]);
+
+ const handlePress = React.useCallback(
+ (metaData, nfts) => {
+ navigation && navigation.navigate('AssetDetails', { metaData, nfts });
+ },
+ [navigation],
+ );
+
+ return (
+ // nfts?.length === 0 ? (
+ //
+ // No NFTs
+ //
+ // ) : (
+ <>
+
+ 2 && 'mb-[120px]'}`}
+ numColumns={2}
+ onRefresh={loadData}
+ refreshing={isLoading}
+ data={nfts}
+ extraData={nfts}
+ ListEmptyComponent={(nfts) => (
+ <>
+ {isLoading ?
+
+
+
+
+
+ :
+
+ No NFTs
+
+ }
+ >
+ )}
+ renderItem={({ item, index }) => {
+ return
+ }}
+ />
+
+ >
+ // )
+ )
+};
+
+export default AssetsView;
diff --git a/NFTVerse/MobileApp/components/authorized-view/assets/CollapsableView.tsx b/NFTVerse/MobileApp/components/authorized-view/assets/CollapsableView.tsx
new file mode 100644
index 00000000..a769d854
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/assets/CollapsableView.tsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import { Image, Text, TouchableOpacity, View } from 'react-native';
+
+const CollapsableView: React.FC<{
+ style?: any;
+ className?: string;
+ headerTitle: string;
+ headerImage?: React.ReactNode;
+ body: React.ReactNode;
+}> = ({ style, className, body, headerTitle, headerImage }) => {
+ const [collapsed, setCollapsed] = React.useState(true);
+
+ const toggleCollapsed = React.useCallback(() => setCollapsed(prev => !prev), []);
+
+ return (
+
+
+
+ {headerImage && headerImage}
+ {headerTitle}
+
+
+
+ {body}
+
+ );
+};
+
+export default CollapsableView;
diff --git a/NFTVerse/MobileApp/components/authorized-view/assets/NftViewSkeleton.tsx b/NFTVerse/MobileApp/components/authorized-view/assets/NftViewSkeleton.tsx
new file mode 100644
index 00000000..02062c50
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/assets/NftViewSkeleton.tsx
@@ -0,0 +1,30 @@
+import React from 'react';
+import { View } from 'react-native';
+
+const NftViewSkeleton: React.FC = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default NftViewSkeleton;
diff --git a/NFTVerse/MobileApp/components/authorized-view/profile/Connect.tsx b/NFTVerse/MobileApp/components/authorized-view/profile/Connect.tsx
new file mode 100644
index 00000000..53b09baa
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/profile/Connect.tsx
@@ -0,0 +1,73 @@
+import React from 'react';
+import { Alert, Image, Linking, Pressable, Text, View } from 'react-native';
+
+const data = [
+ {
+ image: require(`../../../assets/authorized-view/instagram.png`),
+ text: 'Instagram',
+ link: 'https://www.instagram.com/onnftverse/',
+ },
+ {
+ image: require('../../../assets/authorized-view/linkedin.png'),
+ text: 'LinkedIn',
+ link: 'https://www.linkedin.com/company/nftverse/',
+ },
+ {
+ image: require('../../../assets/authorized-view/twitter.png'),
+ text: 'Twitter',
+ link: 'https://twitter.com/TaleWallet',
+ },
+ {
+ image: require('../../../assets/authorized-view/facebook.png'),
+ text: 'Facebook',
+ link: 'https://www.facebook.com/onnftverse',
+ },
+ {
+ image: require('../../../assets/authorized-view/discord.png'),
+ text: 'Discord',
+ link: 'https://discord.gg/tbs47P7gDW',
+ },
+ {
+ image: require('../../../assets/authorized-view/info.png'),
+ text: 'Learn more',
+ link: 'https://www.onnftverse.com/',
+ },
+];
+
+const openLink = (url: string) => {
+ Linking.canOpenURL(url).then(res => {
+ if (res) {
+ Linking.openURL(url);
+ } else {
+ Alert.alert('Invalid URL');
+ }
+ });
+};
+
+const Connect = () => {
+ return (
+
+
+ Connect with us
+
+ {data.map((item, index) => (
+ openLink(item.link)}
+ key={index}
+ className={'flex flex-col items-center rounded-lg p-5 bg-[#BBFF0020] w-[45%]'}
+ >
+
+ {item.text}
+
+ ))}
+
+
+ );
+};
+
+export default Connect;
diff --git a/NFTVerse/MobileApp/components/authorized-view/profile/FAQ.tsx b/NFTVerse/MobileApp/components/authorized-view/profile/FAQ.tsx
new file mode 100644
index 00000000..19e2a6cc
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/profile/FAQ.tsx
@@ -0,0 +1,79 @@
+import React,{useState} from 'react';
+import { Image, Text, View,Alert } from 'react-native';
+import TextField from '../../common/TextField';
+import BlackPrimaryButton from '../../common/BlackPrimaryButton';
+import useHttp from '../../../hooks/use-http';
+import { REACT_APP_NFTVERSE_DEV_API, REACT_APP_X_APP_TOKEN } from 'denv';
+
+const FAQ = () => {
+ const makeRequest = useHttp();
+ const [email, setEmail] = useState('');
+ const [query, setQuery] = useState('');
+ const [userId, setUserId] = useState('');
+ const [address, setAddress] = useState('');
+ const [isQueryEmailSent, setIsQueryEmailSent] = useState(false);
+ const sendEmail = React.useCallback(() => {
+ if (email && query) {
+ if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
+ makeRequest(
+ {
+ url: `${REACT_APP_NFTVERSE_DEV_API}/internal/email/send`,
+ data: {
+ "body": `${email} ${userId} ${address} ${query}`,
+ "email": "info@onnftverse.com",
+ "subject": 'NFTVerse Info query Details'
+ },
+ method: "post",
+ headers: {
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ "Content-Type": "application/json",
+ },
+ },
+ (data) => {
+ console.log(data);
+ setIsQueryEmailSent(true);
+ setEmail('');
+ setQuery('');
+ setUserId('');
+ setAddress('');
+ Alert.alert('Your Query Mailed successfully!')
+
+ },
+ (error) => {
+ Alert.alert('Something went worng')
+ }
+ )
+ }
+ else {
+ Alert.alert('Incorrect Email Id')
+ }
+ }
+ else {
+ Alert.alert('Input field cannot be empty')
+ }
+ },[email,query])
+
+ const handleEmailChange = React.useCallback((emailId:string) => {
+ setEmail(emailId);
+ },[email])
+ const handleQueryChange = React.useCallback((queryText:string) => {
+ setQuery(queryText);
+ },[query])
+ return (
+
+
+ Support
+
+ Your Email
+
+
+
+ Your Query
+
+
+ {sendEmail()}}>Submit
+
+ );
+};
+
+export default FAQ;
diff --git a/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/CheckDocuments.tsx b/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/CheckDocuments.tsx
new file mode 100644
index 00000000..78b88cad
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/CheckDocuments.tsx
@@ -0,0 +1,193 @@
+import { NativeStackNavigationProp } from '@react-navigation/native-stack'
+import axios from 'axios'
+import { REACT_APP_NFTVERSE_DEV_API, REACT_APP_URL_BLOCKCHAIN_SERVICE, REACT_APP_X_APP_TOKEN } from 'denv'
+import React, { useCallback, useEffect } from 'react'
+import { View, Text, Image, ScrollView, TouchableOpacity, Alert } from 'react-native'
+import { useDispatch, useSelector } from 'react-redux'
+import useHttp from '../../../../hooks/use-http'
+import { StoreStateType } from '../../../../misc/types'
+import { appActions } from '../../../../store/app-slice'
+import BlackPrimaryButton from '../../../common/BlackPrimaryButton'
+
+
+const CheckDocuments: React.FC<{ navigation: NativeStackNavigationProp }> = ({ navigation }) => {
+ const appCtx = useSelector((state: StoreStateType) => state.app)
+ console.log(appCtx);
+ const makeRequest = useHttp();
+ const dispatch = useDispatch();
+ const handleDocumentNavigate = React.useCallback(() => navigation.navigate('KycVerification'), [navigation]);
+ const handlePictureNavigate = React.useCallback(() => navigation.navigate('KycUploadSelfie'), [navigation]);
+ const handleDocumentUpdate = React.useCallback(() => {
+
+ let url = `${REACT_APP_NFTVERSE_DEV_API}/user/kyc`;
+
+ let config = {
+ url: url,
+ method: "get",
+ headers: {
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ "X-Auth-Token": appCtx.user?.authToken,
+ "Content-Type": "application/json",
+ },
+ }
+ console.log('get', config);
+
+ axios(config)
+ .then((response) => {
+
+ const payload = {
+ "country": appCtx.country,
+ "document": `Front`,
+ "documentUrl": appCtx.frontSide,
+ // "id": result?.id,
+ "otherDocument": `Back`,
+ "otherDocumentUrl": appCtx.backSide,
+ "selfieUrl": appCtx.picture || appCtx.cameraPicture,
+ "userId": appCtx.user?.userId,
+ "verified": false,
+ "rejectionReason": null
+ }
+ let config1 = {
+ url: `${url}${response?.data ? '?reUpload=true' : ''}`,
+ method: response?.data ? "put" : "post",
+ headers: {
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ "X-Auth-Token": appCtx.user?.authToken,
+ "Content-Type": "application/json",
+ },
+ data: payload,
+ }
+ console.log('postput', config1);
+
+ axios(config1)
+ .then((res) => {
+ navigation.navigate('ThankYou');
+ Alert.alert('Documents submitted Successfully')
+ })
+ .catch(() => {
+ Alert.alert('Try again')
+ })
+ })
+ .catch(() => {
+ Alert.alert('Try again');
+ })
+ }, [])
+ const kycData = React.useCallback(() => {
+ let url = `${REACT_APP_NFTVERSE_DEV_API}/user/kyc`;
+
+ let config = {
+ url: url,
+ method: "get",
+ headers: {
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ "X-Auth-Token": appCtx.user?.authToken,
+ "Content-Type": "application/json",
+ },
+ }
+ console.log('get', config);
+
+ axios(config)
+ .then((response) => {
+
+ dispatch(
+ appActions.setCountry(response?.data?.country)
+ )
+ // dispatch(
+ // appActions.setDocument('')
+ // )
+ dispatch(appActions.setFrontSide(response?.data?.documentUrl));
+ dispatch(appActions.setBackSide(response?.data?.otherDocumentUrl));
+ dispatch(appActions.setPicture(response?.data?.selfieUrl));
+ dispatch(appActions.setCameraPicture(''));
+
+ dispatch(appActions.setVerified(response?.data?.verified));
+ dispatch(appActions.setRejection(response?.data?.rejectionReason));
+ navigation.navigate('Wallet')
+ })
+ .catch(() => {
+
+ })
+ }, [navigation])
+
+ useEffect(
+ () =>
+ navigation.addListener('beforeRemove', (e) => {
+
+
+ // Prevent default behavior of leaving the screen
+ e.preventDefault();
+
+ // Prompt the user before leaving the screen
+ Alert.alert(
+ 'Discard changes?',
+ 'You have unsaved changes. Do you want to leave before submitting your E-KYC documents?',
+ [
+ { text: "Don't leave", style: 'cancel', onPress: () => { } },
+ {
+ text: 'Home',
+ style: 'destructive',
+ // If the user confirmed, then we dispatch the action we blocked earlier
+ // This will continue the action that had triggered the removal of the screen
+ onPress: () => {
+ kycData();
+ },
+ },
+ ]
+ );
+ }),
+ [navigation]
+ );
+ return (
+
+ Please check the information below to make sure everything is correct
+ Identity Documents
+
+
+
+
+
+
+
+
+ {appCtx.frontSide &&
+
+ }
+
+
+ Document
+ { handleDocumentNavigate() }} className="">
+
+
+
+
+
+
+
+
+ {(appCtx.cameraPicture || appCtx.picture) &&
+
+ }
+
+
+ Selfie
+ { handlePictureNavigate() }} className="">
+
+
+
+ {/* { navigate('/kyc/upload/selfie') }} /> */}
+
+
+
+ Submit
+
+
+
+
+ )
+}
+export default CheckDocuments
+
+
diff --git a/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/KycTermsAndCondition.tsx b/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/KycTermsAndCondition.tsx
new file mode 100644
index 00000000..62a7af78
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/KycTermsAndCondition.tsx
@@ -0,0 +1,53 @@
+import React, { useState,useEffect } from 'react'
+import { Text } from 'react-native-paper'
+import { View, Image } from 'react-native'
+import BlackPrimaryButton from '../../../common/BlackPrimaryButton'
+import Checkbox from 'expo-checkbox'
+import { ScrollView } from 'react-native-gesture-handler'
+import { useSelector } from 'react-redux'
+import { StoreStateType } from '../../../../misc/types'
+
+export default function KycTermsAndCondition({ navigation }) {
+ const [checked1, setChecked1] = useState(false);
+ const [checked2, setChecked2] = useState(false);
+ const appCtx = useSelector((state: StoreStateType) => state.app)
+
+ useEffect(()=>{
+ console.log(appCtx.verified);
+
+ if(appCtx.verified){
+ navigation.navigate('ThankYou')
+ }
+ else{
+ if(appCtx.frontSide && appCtx.backSide && (appCtx.cameraPicture || appCtx.picture)){
+ navigation.navigate('ThankYou')
+ }
+ }
+},[appCtx.verified])
+ return (
+
+
+ {/* You need to complete your KYC to buy Tale coins and Algos
*/}
+
+
+ Please prepare your identity document and ensure that it is valid before you begin. We also require you to accept our terms and conditions and consent to the processing of your personal data.
+ setChecked1(!checked1)} />By clicking next. I accept terms and Policy
+ setChecked2(!checked2)} />
+
+ I agree to the processing of my data as describe to the content of data processing.
+
+
+
+
+
+
+
+
+
+ {checked1 && checked2 &&
+ { navigation.navigate('KycVerification') }}>Next
+ }
+
+
+ )
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/KycVerification.tsx b/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/KycVerification.tsx
new file mode 100644
index 00000000..05ffb18a
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/KycVerification.tsx
@@ -0,0 +1,294 @@
+import axios from 'axios';
+import React, { useCallback, useEffect, useRef, useState, FC } from 'react';
+import { Image, Text, TouchableOpacity, View, Button, Alert } from 'react-native';
+import SelectDropdown from 'react-native-select-dropdown';
+import { useDispatch, useSelector } from 'react-redux';
+import { StoreStateType } from '../../../../misc/types';
+import DocumentPicker from 'expo-document-picker';
+import * as ImagePicker from 'expo-image-picker';
+import BlackPrimaryButton from '../../../common/BlackPrimaryButton';
+import { ScrollView } from 'react-native-gesture-handler';
+import { appActions } from '../../../../store/app-slice';
+import { REACT_APP_FILE_UPLOAD, REACT_APP_X_APP_TOKEN } from 'denv';
+import useHttp from '../../../../hooks/use-http';
+import { NativeStackNavigationProp } from '@react-navigation/native-stack';
+
+const KycVerification: FC<{ navigation: NativeStackNavigationProp }> = ({ navigation }) => {
+ const appCtx = useSelector((state: StoreStateType) => state.app)
+ const [country, setCountry] = useState([{}]);
+ const [selectedCountry, setSelectedCountry] = useState();
+ const fileRef = useRef();
+ const [image, setImage] = useState();
+ const [backImage, setBackImage] = useState();
+ const [hasGallaryPermission, setHasGallaryPermission] = useState(null);
+ const makeRequest = useHttp();
+
+
+ const handleNext = React.useCallback(() => {
+
+ if (appCtx.country) {
+ if (appCtx.frontSide || image) {
+ if (appCtx.backSide || backImage) {
+ navigation.navigate('KycUploadSelfie'), [navigation]
+ }
+ else {
+ Alert.alert('Document BackSide not uploaded')
+ }
+ }
+ else {
+ Alert.alert('Document FrontSide not uploaded')
+ }
+ } else {
+ Alert.alert('Please select your country')
+ }
+ }, [appCtx.country,appCtx.frontSide,appCtx.backSide]);
+ const dispatch = useDispatch();
+ const handleCountryCode = () => {
+
+ fetch('https://gist.githubusercontent.com/anubhavshrimal/75f6183458db8c453306f93521e93d37/raw/f77e7598a8503f1f70528ae1cbf9f66755698a16/CountryCodes.json', { method: 'get' })
+ .then((response) => {
+ return response.json();
+ })
+ .then((result: any) => {
+ let codeArray: any = [];
+ result.map((res: any) => {
+ codeArray = [...codeArray, res.name]
+ })
+ setCountry(codeArray);
+ })
+ }
+
+ // fileRef?.current?.click();
+ // }
+ // const handleBackChange = useCallback((file:any) => {
+ // console.log('back');
+
+ // if (file) {
+
+ // // setBackSide(file.File);
+ // // dispatch(appActions.setBackSideFile(file))
+ // const objectUrl = URL.createObjectURL(file);
+ // // setBacksidePreview(objectUrl);
+ // const data = new FormData();
+ // data.append('file', file);
+ // data.append('fileName', `Document Back`);
+ // data.append('fileUrl', objectUrl);
+ // let config = {
+ // method: 'post',
+ // url: `${process.env.REACT_APP_REACT_APP_FILE_UPLOAD}/kyc/document/upload`,
+ // headers: {
+ // 'Content-Type': 'multipart/form-data',
+ // 'X-Auth-Token': appCtx.authToken,
+ // "X-App-Token": process.env.REACT_APP_REACT_APP_X_APP_TOKEN,
+ // },
+ // data: data
+ // };
+ // // toast.promise(
+ // // () =>
+ // axios(config)
+ // .then(function (response:any) {
+ // // setLogoUrl(response.data.fileUrl);
+ // // const marketplace = {
+ // // marketplaceId: marketplaceId,
+ // // collectionLogo: response.data.fileUrl
+ // // };
+ // // dispatch(appActions.setBackSide(response.data?.fileUrl))
+
+ // // toast.success('Back Side Uploaded Successfully')
+ // })
+ // .catch(function (error:any) {
+ // // toast.error('Uploading Back Side failed!');
+ // }),
+ // {
+ // pending: 'uploading Back side',
+ // // success: 'Settings updated successfully!',
+ // // error: 'Uh-oh! Something went wrong'
+ // }
+ // // );
+ // return () => URL.revokeObjectURL(objectUrl);
+ // }
+ // }, []);
+ useEffect(() => {
+ (async () => {
+ const galleryStatus = await ImagePicker.requestMediaLibraryPermissionsAsync();
+ setHasGallaryPermission(galleryStatus.status === 'granted');
+ })();
+ handleCountryCode();
+ }, [])
+
+ // const _pickDocument = async () => {
+ // let result = await DocumentPicker.getDocumentAsync({});
+ // // alert(result.uri);
+ // console.log(result);
+ // }
+
+ const _pickImageFront = async () => {
+ let result = await ImagePicker.launchImageLibraryAsync({
+ allowsEditing: true,
+ aspect: [4, 3],
+ mediaTypes: ImagePicker.MediaTypeOptions.Images,
+ opacity: 1,
+ base64: true
+ });
+
+ // alert(result);
+
+ if (!result.cancelled) {
+ // this.setState({ image: result.uri });
+ console.log(result)
+
+ let config = {
+ method: 'post',
+ url: `${REACT_APP_FILE_UPLOAD}/image/upload/base64`,
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Auth-Token': appCtx.authToken,
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ },
+ data: {
+ fileName: 'FrontSide',
+ fileUrl: result.base64,
+ type: 'jpeg'
+ }
+ }
+ axios(config)
+ .then(function (response: any) {
+ console.log(response);
+ setImage(response.data?.fileUrl)
+ dispatch(appActions.setFrontSide(response.data?.fileUrl));
+ })
+ .catch(function (error) {
+ console.log(error);
+
+ // toast.error('Uploading Back Side failed!');
+ })
+
+ }
+ };
+
+ const _pickImageBack = async () => {
+ let result = await ImagePicker.launchImageLibraryAsync({
+ allowsEditing: true,
+ aspect: [4, 3],
+ mediaTypes: ImagePicker.MediaTypeOptions.Images,
+ opacity: 1,
+ base64: true
+ });
+
+ // alert(result);
+ console.log(result)
+
+ if (!result.cancelled) {
+ // this.setState({ image: result.uri });
+
+
+ let config = {
+ method: 'post',
+ url: `${REACT_APP_FILE_UPLOAD}/image/upload/base64`,
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Auth-Token': appCtx.authToken,
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ },
+ data: {
+ fileName: 'BackSide',
+ fileUrl: result.base64,
+ type: 'jpeg'
+ }
+ }
+ axios(config)
+ .then(function (response: any) {
+ console.log(response);
+ setBackImage(response.data?.fileUrl);
+ dispatch(appActions.setBackSide(response.data?.fileUrl));
+ })
+ .catch(function (error) {
+ console.log(error);
+ })
+ }
+ };
+
+ if (hasGallaryPermission === false) {
+ return alert('No Access to Internal Storage')
+ }
+
+
+
+ return (
+
+
+
+ Kyc Verification
+
+
+ Select Country
+ {
+ setSelectedCountry(selectedItem)
+ dispatch(appActions.setCountry(selectedItem))
+ }}
+ buttonTextAfterSelection={(selectedItem, index) => {
+ // text represented after item is selected
+ // if data array is an array of objects then return selectedItem.property to render after item is selected
+ return selectedItem
+ }}
+ rowTextForSelection={(item, index) => {
+ // text represented for each item in dropdown
+ // if data array is an array of objects then return item.property to represent item in dropdown
+ return item
+ }}
+ onChangeSearchInputText={() => {
+
+ }}
+ />
+
+
+ Identity Document
+
+
+ _pickImageFront()}
+
+ // color={'#C1C2C4'}
+ />
+ {appCtx.frontSide ?
+
+ :
+
+ Upload Front Side of your Document
+
+ }
+
+
+ _pickImageBack()}
+ // color={'#C1C2C4'}
+ />
+ {appCtx.backSide ?
+
+ :
+
+ Upload Back Side of your Document
+
+ }
+
+
+
+ { handleNext() }}>{`Next -> Upload Selfie`}
+
+
+
+ );
+};
+
+export default KycVerification;
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/Thankyou.tsx b/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/Thankyou.tsx
new file mode 100644
index 00000000..fedec3c0
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/Thankyou.tsx
@@ -0,0 +1,194 @@
+import { NativeStackNavigationProp } from '@react-navigation/native-stack';
+import axios from 'axios';
+import { REACT_APP_NFTVERSE_DEV_API, REACT_APP_X_APP_TOKEN } from 'denv';
+import React from 'react'
+import { Text, View, Image, Pressable } from 'react-native'
+import { ScrollView } from 'react-native-gesture-handler';
+import { useDispatch, useSelector } from 'react-redux';
+import { StoreStateType } from '../../../../misc/types';
+import { appActions } from '../../../../store/app-slice';
+import BlackPrimaryButton from '../../../common/BlackPrimaryButton'
+
+const ThankYou: React.FC<{ navigation: NativeStackNavigationProp }> = ({ navigation }) => {
+ const appCtx = useSelector((state: StoreStateType) => state.app);
+ const dispatch = useDispatch();
+ React.useEffect(
+ () =>
+ navigation.addListener('beforeRemove', (e) => {
+ e.preventDefault();
+ navigation.navigate('Wallet')
+ }),
+ [navigation]
+ );
+
+ React.useEffect(() => {
+ let url = `${REACT_APP_NFTVERSE_DEV_API}/user/kyc`;
+
+ let config = {
+ url: url,
+ method: "get",
+ headers: {
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ "X-Auth-Token": appCtx.user?.authToken,
+ "Content-Type": "application/json",
+ },
+ }
+ console.log('get', config);
+
+ axios(config)
+ .then((response) => {
+
+ dispatch(
+ appActions.setCountry(response?.data?.country)
+ )
+ // dispatch(
+ // appActions.setDocument('')
+ // )
+ dispatch(appActions.setFrontSide(response?.data?.documentUrl));
+ dispatch(appActions.setBackSide(response?.data?.otherDocumentUrl));
+ dispatch(appActions.setPicture(response?.data?.selfieUrl));
+ dispatch(appActions.setCameraPicture(''));
+
+ dispatch(appActions.setVerified(response?.data?.verified));
+ dispatch(appActions.setRejection(response?.data?.rejectionReason));
+ })
+ .catch(() => {
+
+ })
+ }, [])
+
+
+ return (
+
+ {!appCtx.verified ?
+ appCtx.rejection ?
+ <>
+ Thank you for your patience.
+
+
+
+
+
+ Something wrong with your verification information.We request you to please resubmit your document to complete your KYC
+
+
+ { handleDocumentDownload() }}
+ >
+ {appCtx.frontSide ?
+
+ :
+
+ }
+
+
+ Identity Document
+ {/* { navigate('/kyc/upload/document') }} /> */}
+
+
+
+ appCtx.picture && handleDownload(appCtx.picture)}
+ >
+ {appCtx.picture ?
+
+ :
+
+ }
+
+
+ Picture Uploaded
+ {/* { }} /> */}
+
+
+
+
+
+ Status : Rejected
+ Reason : {appCtx.rejection}
+
+ {
+ navigation.navigate('KycVerification');
+ }}
+ >Resubmit
+
+
+
+ >
+ :
+
+ Thank you
+ We are currently checking your data
+
+
+
+
+
+ The verification status will be updated automatically and can take upto 24 hours
+ When your documents get verified and you get a verified status, you can claim your rewards.
+
+ {appCtx.verified ?
+
+ :
+
+ }
+ - Identity Document
+
+ {appCtx.verified ?
+
+ :
+
+ }
+ - Selfie
+
+
+
+ { navigation.navigate('Wallet') }}>
+ {`Go to Wallet ->`}
+
+
+ :
+ <>
+ {/* Thank you */}
+ Thank you for your patience, your verification is complete
+
+
+
+
+
+ Your verification status is updated !
+
+ {appCtx.verified ?
+
+ :
+
+ }
+ - Identity Document
+
+
+ {appCtx.verified ?
+
+ :
+
+ }
+ - Selfie
+
+
+
+ { navigation.navigate('Wallet') }}>
+ {`Go to Wallet ->`}
+
+
+
+
+ >
+ }
+
+ )
+}
+export default ThankYou
diff --git a/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/UploadSelfie.tsx b/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/UploadSelfie.tsx
new file mode 100644
index 00000000..6c018703
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/profile/Kyc/UploadSelfie.tsx
@@ -0,0 +1,178 @@
+import React, { useEffect, useState } from 'react'
+import { Image, Text, TouchableOpacity, View, Button, ScrollView, Alert } from 'react-native';
+import * as ImagePicker from 'expo-image-picker';
+import BlackPrimaryButton from '../../../common/BlackPrimaryButton';
+import { NativeStackNavigationProp } from '@react-navigation/native-stack';
+import { useDispatch, useSelector } from 'react-redux';
+import { appActions } from '../../../../store/app-slice';
+import { StoreStateType } from '../../../../misc/types';
+import { REACT_APP_FILE_UPLOAD, REACT_APP_X_APP_TOKEN } from 'denv';
+import axios from 'axios';
+
+const UploadSelfie: React.FC<{ navigation: NativeStackNavigationProp }> = ({ navigation }) => {
+ const [cameraPicture, setCameraPicture] = useState();
+ const [picture, setPicture] = useState('');
+ const [capture, setCapture] = useState('');
+ const dispatch = useDispatch();
+ const handleNext = React.useCallback(() => navigation.navigate('CheckDocuments'), [navigation]);
+ const appCtx = useSelector((state: StoreStateType) => state.app)
+
+ const _handleUploadSelfie = async () => {
+ let result = await ImagePicker.launchImageLibraryAsync({
+ allowsEditing: true,
+ aspect: [4, 3],
+ mediaTypes: ImagePicker.MediaTypeOptions.Images,
+ opacity: 1,
+ base64: true
+ });
+
+ if (!result.cancelled) {
+ // this.setState({ image: result.uri });
+
+ let config = {
+ method: 'post',
+ url: `${REACT_APP_FILE_UPLOAD}/image/upload/base64`,
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Auth-Token': appCtx.authToken,
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ },
+ data: {
+ fileName:'selfie',
+ fileUrl: result.base64,
+ type:'jpeg'
+ }
+ }
+ axios(config)
+ .then(function (response: any) {
+ console.log(response);
+
+ dispatch(appActions.setPicture(response.data?.fileUrl));
+ dispatch(appActions.setCameraPicture(''));
+ })
+ .catch(function (error) {
+ console.log(error);
+
+ // toast.error('Uploading Back Side failed!');
+ })
+
+ }
+ };
+
+
+ const launchCamera = React.useCallback(async () => {
+
+ // storageOptions: {
+ // skipBackup: true,
+ // path: 'images',
+ // },
+ // };
+ // ImagePicker.launchCameraAsync(options, (response) => {
+ // console.log('Response = ', response);
+
+ // if (response.didCancel) {
+ // console.log('User cancelled image picker');
+ // } else if (response.error) {
+ // console.log('ImagePicker Error: ', response.error);
+ // } else if (response.customButton) {
+ // console.log('User tapped custom button: ', response.customButton);
+ // alert(response.customButton);
+ // } else {
+ // const source = { uri: response.uri };
+ // console.log('response', JSON.stringify(response));
+ // // this.setState({
+ // // filePath: response,
+ // // fileData: response.data,
+ // // fileUri: response.uri
+ // // });
+ // setPicture(response.uri)
+ // }
+ // });
+ const img = await ImagePicker.launchCameraAsync({
+ quality: 0.7,
+ allowsEditing: false,
+ aspect: [16, 9],
+ base64: true,
+ });
+ console.log(img);
+
+ if (!img.cancelled) {
+ let config = {
+ method: 'post',
+ url: `${REACT_APP_FILE_UPLOAD}/image/upload/base64`,
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Auth-Token': appCtx.authToken,
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ },
+ data: {
+ fileName:'selfie',
+ fileUrl: img.base64,
+ type:'jpeg'
+ }
+ }
+ axios(config)
+ .then(function (response: any) {
+ console.log(response);
+ setCameraPicture(response.data?.fileUrl);
+ dispatch(appActions.setPicture(''));
+ dispatch(appActions.setCameraPicture(response.data?.fileUrl));
+ })
+ .catch(function (error) {
+ console.log(error);
+
+ // toast.error('Uploading Back Side failed!');
+ })
+
+ }
+ // }
+ }, []);
+
+ return (
+
+
+ {/* {!appCtx.picture && */}
+
+
+ launchCamera()}
+ // color={'#C1C2C4'}
+ />
+ {appCtx.cameraPicture ?
+
+ :
+
+ Click above button to Upload your selfie
+
+ }
+
+ {/* } */}
+ OR
+ {/* {!appCtx.cameraPicture && */}
+
+ _handleUploadSelfie()}
+ // color={'#C1C2C4'}
+ />
+ {appCtx.picture ?
+
+ :
+
+ Click above button to Upload your selfie
+
+ }
+
+ {/* } */}
+ {(appCtx.cameraPicture || appCtx.picture) &&
+ handleNext()}>{`Next -> Verify Documents`}
+ }
+
+
+ )
+}
+export default UploadSelfie
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/components/authorized-view/profile/ProfileOptions.jsx b/NFTVerse/MobileApp/components/authorized-view/profile/ProfileOptions.jsx
new file mode 100644
index 00000000..8acc9471
--- /dev/null
+++ b/NFTVerse/MobileApp/components/authorized-view/profile/ProfileOptions.jsx
@@ -0,0 +1,161 @@
+import React, { FC, useCallback } from 'react';
+import { Image, Text, TouchableOpacity, View, Button, Linking, Alert, Pressable } from 'react-native';
+import { useDispatch, useSelector } from 'react-redux';
+import { persistor } from '../../../store/store';
+import { appActions } from '../../../store/app-slice';
+import { ScrollView, Switch } from 'react-native-gesture-handler';
+
+const ProfileOptions = ({ navigation }) => {
+ const email = useSelector((state) => state.app.user.email);
+ const appCtx = useSelector((state) => state.app);
+ const [network, setNetwork] = React.useState (false);
+ const dispatch = useDispatch();
+
+ const navigateToFAQ = React.useCallback(() => navigation.navigate('FAQ'), [navigation]);
+
+ const navigateToConnect = React.useCallback(() => navigation.navigate('Connect'), [navigation]);
+
+ const handleLogout = React.useCallback(
+ () => persistor.purge().then(() => {
+ dispatch(appActions.logout())
+ dispatch(appActions.logout(undefined));
+ dispatch(appActions.updateAuthToken(''));
+ dispatch(appActions.setWalletAddress([{ address: '' }]));
+ dispatch(appActions.updateUser({})
+ );
+ dispatch(
+ appActions.setCountry('')
+ )
+ // dispatch(
+ // appActions.setDocument('')
+ // )
+ dispatch(appActions.setFrontSide(''));
+ dispatch(appActions.setBackSide(''));
+ dispatch(appActions.setPicture(''));
+ dispatch(appActions.setCameraPicture(''));
+
+ dispatch(appActions.setVerified(false));
+ dispatch(appActions.setRejection(null));
+
+ // dispatch(appActions.setMnemonicCode('""'));
+ // dispatch(appActions.setPassword(''));
+ // dispatch(appActions.setRewardData({}));
+ // dispatch(appActions.setMetaData(''));
+ }),
+ [persistor, dispatch],
+ );
+ const handleKyc = React.useCallback(() => {
+ // if(appCtx.user?.email){
+ // if (appCtx.country && (appCtx.frontSide || appCtx.backSide) && (appCtx.picture || appCtx.cameraPicture)) {
+ // navigation.navigate('ThankYou');
+ // }
+ // else {
+ // if (appCtx.verified) {
+ // navigation.navigate('ThankYou');
+ // }
+ // else {
+ // navigation.navigate('kycTermsAndCondition');
+ // }
+ // }
+ // }
+ // else{
+ // navigation.navigate('kycTermsAndCondition');
+ // }
+ navigation.navigate('KycTermsAndCondition');
+ }, [navigation])
+ // const OpenURLButton = ({ url, children }: OpenURLButtonProps) => {
+ const handlePress = useCallback(async (url) => {
+ // Checking if the link is supported for links with custom URL scheme.
+ const supported = await Linking.canOpenURL(url);
+
+ if (supported) {
+ // Opening the link with some app, if the URL scheme is "http" the web link should be opened
+ // by some browser in the mobile
+ await Linking.openURL(url);
+ } else {
+ Alert.alert(`${url} is Invalid !!`);
+ }
+ }, []);
+
+ return (
+
+
+
+
+ {email}
+
+
+
+
+
+ My Profile
+ {/* {setNetwork(!network)}} value={network}> */}
+
+
+
+ {/*
+
+ Support
+ */}
+
+ {/*
+
+ Contact us
+ */}
+
+
+
+
+
+ Logout
+
+ {navigation.navigate('SpinTheWheel')}} className={'flex flex-row items-center gap-x-2 pt- h-[80px] px-3 items-star border-b border-b-gray-300 bg-indigo-900'}>
+
+ Spin The Wheel
+
+ {/*
+
+ Exit the game
+ */}
+
+
+ );
+};
+
+export default ProfileOptions;
diff --git a/NFTVerse/MobileApp/components/common/AlertModal.jsx b/NFTVerse/MobileApp/components/common/AlertModal.jsx
new file mode 100644
index 00000000..9af39f9e
--- /dev/null
+++ b/NFTVerse/MobileApp/components/common/AlertModal.jsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import { Modal, Text, View } from 'react-native';
+import BlackPrimaryButton from './BlackPrimaryButton';
+
+const AlertModal= ({ visible, onClose, children, buttonText, header }) => {
+ return (
+
+
+
+ {header &&
+ {header}
+ }
+ {children}
+
+ {buttonText || 'OK'}
+
+
+
+
+ );
+};
+
+export default AlertModal;
diff --git a/NFTVerse/MobileApp/components/common/BlackPrimaryButton.jsx b/NFTVerse/MobileApp/components/common/BlackPrimaryButton.jsx
new file mode 100644
index 00000000..4558a318
--- /dev/null
+++ b/NFTVerse/MobileApp/components/common/BlackPrimaryButton.jsx
@@ -0,0 +1,28 @@
+import React, { FC } from 'react';
+import { Text, TouchableOpacity, View } from 'react-native';
+import { ActivityIndicator } from 'react-native-paper';
+
+const BlackPrimaryButton = ({ children, onPress, style, className, disabled, primary, loading }) => {
+ return (
+
+
+
+ {children}
+
+ {loading &&
+ {loading && }
+ }
+
+
+ );
+};
+
+export default BlackPrimaryButton;
diff --git a/NFTVerse/MobileApp/components/common/GreenOutlinedButton.jsx b/NFTVerse/MobileApp/components/common/GreenOutlinedButton.jsx
new file mode 100644
index 00000000..5f774570
--- /dev/null
+++ b/NFTVerse/MobileApp/components/common/GreenOutlinedButton.jsx
@@ -0,0 +1,19 @@
+import React, { FC } from 'react';
+import { Pressable, View } from 'react-native';
+
+const GreenOutlinedButton = ({
+ children,
+ onPress,
+ style,
+ className,
+}) => {
+ return (
+
+
+ {children}
+
+
+ );
+};
+
+export default GreenOutlinedButton;
diff --git a/NFTVerse/MobileApp/components/common/TextField.jsx b/NFTVerse/MobileApp/components/common/TextField.jsx
new file mode 100644
index 00000000..d1ace9c1
--- /dev/null
+++ b/NFTVerse/MobileApp/components/common/TextField.jsx
@@ -0,0 +1,16 @@
+import React, { FC } from 'react';
+import { TextInput } from 'react-native';
+
+const TextField = ({ value, style, className, onChange, placeholder, }) => {
+ return (
+ onChange && onChange(e)}
+ />
+ );
+};
+
+export default TextField;
diff --git a/NFTVerse/MobileApp/components/modals/OtpSentModal.jsx b/NFTVerse/MobileApp/components/modals/OtpSentModal.jsx
new file mode 100644
index 00000000..778e2d24
--- /dev/null
+++ b/NFTVerse/MobileApp/components/modals/OtpSentModal.jsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import { Modal, Text, View } from 'react-native';
+import BlackPrimaryButton from '../common/BlackPrimaryButton';
+
+const OtpSentModal = ({ visible, onClose }) => {
+ return (
+
+
+
+ OTP Verification
+ An OTP has been sent to your registered email ID
+
+ Ok
+
+
+
+
+ );
+};
+
+export default OtpSentModal;
diff --git a/NFTVerse/MobileApp/components/modals/ResultModal.jsx b/NFTVerse/MobileApp/components/modals/ResultModal.jsx
new file mode 100644
index 00000000..2219db23
--- /dev/null
+++ b/NFTVerse/MobileApp/components/modals/ResultModal.jsx
@@ -0,0 +1,38 @@
+import React from 'react';
+import { Modal, Text, View, Image, Pressable } from 'react-native';
+import BlackPrimaryButton from '../common/BlackPrimaryButton';
+
+const ResultModal = ({ openModal, setOpenModal, result }) => {
+ const onClose = React.useCallback(
+ () => {
+ setOpenModal(false)
+ },
+ [openModal],
+ )
+ return (
+
+
+
+ <>
+ {!result ?
+ <>
+
+ >
+ :
+ <>
+
+ >
+ }
+
+ Continue
+
+ >
+
+
+
+ );
+};
+
+export default ResultModal;
diff --git a/NFTVerse/MobileApp/components/modals/sendAlgosOrAssetsModal/SendOtpModal.jsx b/NFTVerse/MobileApp/components/modals/sendAlgosOrAssetsModal/SendOtpModal.jsx
new file mode 100644
index 00000000..105d867d
--- /dev/null
+++ b/NFTVerse/MobileApp/components/modals/sendAlgosOrAssetsModal/SendOtpModal.jsx
@@ -0,0 +1,328 @@
+
+import axios from 'axios';
+import { REACT_APP_NFTVERSE_DEV_API, REACT_APP_TAIL_COIN_TOKEN, REACT_APP_URL_BLOCKCHAIN_SERVICE } from 'denv';
+import React from 'react';
+import { Modal, Text, View, Alert, Image, Keyboard, Pressable } from 'react-native';
+import { TextInput, TouchableOpacity } from 'react-native-gesture-handler';
+import { useDispatch, useSelector } from 'react-redux';
+import useHttp from '../../../hooks/use-http';
+import useFetchToken from '../../../hooks/useFetchToken';
+import AlertModal from '../../common/AlertModal';
+import BlackPrimaryButton from '../../common/BlackPrimaryButton';
+import OtpSentModal from '../OtpSentModal';
+
+const SendOtpModal = ({ visible, onClose, option, amount, address, navigation, setVisible }) => {
+ const [emailSent, setEmailSent] = React.useState(false);
+ const [loading, setLoading] = React.useState(false);
+ const appCtx = useSelector((state) => state.app);
+ const [email, setEmail] = React.useState(appCtx.user?.email);
+ console.log(appCtx);
+ const toggleEmailSent = React.useCallback(() => setEmailSent(prev => !prev), []);
+ const [resendOtp, setResendOtp] = React.useState(false);
+ const { optedIn } = useFetchToken();
+ const [alert, setAlert] = React.useState(false);
+ const [message, setMessage] = React.useState('');
+
+ const handleSendOtp = React.useCallback(() => {
+ if (!email) {
+ Alert.alert('Please enter your email');
+ return;
+ }
+ if (!/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(email)) {
+ Alert.alert('Please enter a valid email');
+ return;
+ }
+
+ setLoading(true);
+ makeRequest(
+ {
+ url: `${REACT_APP_NFTVERSE_DEV_API}/otp/send?type=login`,
+ data: { email },
+ method: 'post',
+ headers: {
+ 'X-App-Token': '123',
+ 'Content-Type': 'application/json',
+ },
+ },
+ (data) => {
+ toggleEmailSent()
+
+ },
+ () => {
+ setMessage('Something went wrong !!!')
+ setAlert(true);
+ },
+ () => setLoading(false),
+ );
+ }, [email]);
+
+ const [otp, setOtp] = React.useState({
+ first: '',
+ second: '',
+ third: '',
+ fourth: '',
+ fifth: '',
+ sixth: '',
+ });
+
+ const makeRequest = useHttp();
+
+ const dispatch = useDispatch();
+
+ const secondInputRef = React.useRef(null);
+ const thirdInputRef = React.useRef(null);
+ const fourthInputRef = React.useRef(null);
+ const fifthInputRef = React.useRef(null);
+ const sixthInputRef = React.useRef(null);
+
+ const handleOtpChange = React.useCallback((name, value) => {
+ setOtp(prev => ({ ...prev, [name]: value }));
+ if (name === 'first' && value.length === 1) {
+ secondInputRef.current?.focus();
+ }
+ if (name === 'second' && value.length === 1) {
+ thirdInputRef.current?.focus();
+ }
+ if (name === 'third' && value.length === 1) {
+ fourthInputRef.current?.focus();
+ }
+ if (name === 'fourth' && value.length === 1) {
+ fifthInputRef.current?.focus();
+ }
+ if (name === 'fifth' && value.length === 1) {
+ sixthInputRef.current?.focus();
+ }
+ }, []);
+
+ const handleOtpSubmit = React.useCallback(() => {
+ const otpText = Object.values(otp).join('');
+ if (!/\d{6}/.test(otpText)) {
+ Alert.alert('Please enter a valid OTP');
+ return;
+ }
+
+ setLoading(true);
+
+ let config = {
+ url: `${REACT_APP_URL_BLOCKCHAIN_SERVICE}/token/transfer`,
+ data: {
+ "email": email, "otp": otpText,
+ "blockchainFtId": option === 'tale' ? REACT_APP_TAIL_COIN_TOKEN : 0,
+ "buyerUserAddress": address,
+ "amount": option === 'tale' ? parseFloat(amount) * 100 : parseFloat(amount) * 1000000
+ },
+ method: "post",
+ headers: {
+ "Content-Type": "application/json",
+ "X-Auth-Token": appCtx.authToken
+ }
+ }
+ console.log(config);
+ if ((optedIn && option === 'tale') || option === 'algo') {
+
+
+ axios(config)
+ .then((res) => {
+ console.log(res.data);
+
+ setLoading(false);
+ // Alert.alert('Transfer Successfull');
+ setMessage('Transfer Successfull')
+ setAlert(true);
+ navigation.navigate('Wallet');
+ })
+ .catch((error) => {
+ console.log(error);
+
+ // Alert.alert("OTP entered is incorrect !");
+ setMessage('OTP entered is incorrect !')
+ setAlert(true);
+ setLoading(false);
+ })
+ }
+ else {
+ // Alert.alert('Recievers account need to optIn tale coin asset')
+ setMessage('Recievers account need to optIn tale coin asset')
+ setAlert(true);
+ }
+ }, [otp]);
+
+ React.useEffect(() => {
+ if (Object.values(otp).every(value => value.length === 1)) Keyboard.dismiss();
+ }, [otp]);
+
+ const handleModalClose = React.useCallback(() => {
+ setVisible(false);
+ }, [visible])
+ const handleResendOtp = React.useCallback(() => {
+ let header = {};
+
+ makeRequest(
+ {
+ url: `${REACT_APP_NFTVERSE_DEV_API}/otp/send?type=wallet_login&resend=true`,
+ data: { "email": email },
+ method: "post",
+ },
+ (data) => {
+ Alert.alert('OTP Sent SuccesFully!')
+ // setReSendOtp(true);
+ // distance1 = 0;
+ // setOtp1('');
+ setOtp({
+ first: '',
+ second: '',
+ third: '',
+ fourth: '',
+ fifth: '',
+ sixth: '',
+ });
+ if (data.message === 'Success' && data.status === true) {
+ setResendOtp(true);
+ // setLoader(false)
+ }
+ },
+ () => { }
+ )
+ }, [])
+
+ return (
+
+
+
+
+ {!emailSent ?
+
+
+ {
+
+ if (!emailSent) {
+ handleModalClose();
+ }
+ }}>x
+
+
+ {/* */}
+
+ Email verification
+
+
+
+
+
+
+
+ Send OTP
+
+
+ :
+
+
+ {
+ setEmailSent(prev => !prev)
+ }}
+ >
+ x
+
+
+
+ {/* Welcome to NFTVerse */}
+
+ OTP verification
+ Please enter the verification code sent to your mail
+
+ handleOtpChange('first', value)}
+ autoFocus
+ onSubmitEditing={() => secondInputRef.current?.focus()}
+ />
+ handleOtpChange('second', value)}
+ ref={secondInputRef}
+ onSubmitEditing={() => thirdInputRef.current?.focus()}
+ />
+ handleOtpChange('third', value)}
+ ref={thirdInputRef}
+ onSubmitEditing={() => fourthInputRef.current?.focus()}
+ />
+ handleOtpChange('fourth', value)}
+ ref={fourthInputRef}
+ />
+ handleOtpChange('fifth', value)}
+ ref={fifthInputRef}
+ />
+ handleOtpChange('sixth', value)}
+ ref={sixthInputRef}
+ />
+
+
+
+ Submit
+
+
+ Didn't receive the OTP?
+
+ {!resendOtp ?
+ { handleResendOtp() }}>Resend OTP
+ :
+ { }}>Resend successfull
+ }
+
+
+
+ }
+
+
+
+
+ .
+ { setAlert(false) }}>{message}
+
+ );
+};
+
+export default SendOtpModal;
diff --git a/NFTVerse/MobileApp/env.d.ts b/NFTVerse/MobileApp/env.d.ts
new file mode 100644
index 00000000..ec49f6ee
--- /dev/null
+++ b/NFTVerse/MobileApp/env.d.ts
@@ -0,0 +1,15 @@
+declare module 'denv' {
+ export const REACT_APP_URL_BLOCKCHAIN_SERVICE: string;
+ export const REACT_APP_URL_MARKETPLACE_SERVICE: string;
+ export const REACT_APP_URL_NFTVERSE_ASSETS: string;
+ export const REACT_APP_NFTVERSE_DEV_API: string;
+ export const REACT_APP_MARKETPLACE_DOMAIN: string;
+ export const REACT_APP_GATEWAY_IPFS: string;
+ export const REACT_APP_FILE_UPLOAD:string;
+ export const REACT_APP_X_APP_TOKEN=string;
+ export const REACT_APP_TAIL_COIN_TOKEN=string;
+ export const REACT_APP_ALGORAND_TRANSACTION = string;
+ export const REACT_APP_GATEWAY_ALGOEXPLORER=string;
+ export const REACT_APP_ALGOEXPLORER_ADDRESS = string;
+ export const REACT_APP_NFT_REACT_APP_FILE_UPLOAD = string;
+}
diff --git a/NFTVerse/MobileApp/hooks/use-authorized-http.js b/NFTVerse/MobileApp/hooks/use-authorized-http.js
new file mode 100644
index 00000000..a6dc8f6a
--- /dev/null
+++ b/NFTVerse/MobileApp/hooks/use-authorized-http.js
@@ -0,0 +1,34 @@
+import { useCallback } from 'react';
+import axios from 'axios';
+import { useSelector } from 'react-redux';
+import { REACT_APP_X_APP_TOKEN } from 'denv';
+
+const useAuthorizedHttp = () => {
+ const authToken = useSelector((state) => state.app.user.authToken);
+
+ return useCallback(
+ (requestOptions, successCallback, errorCallback, completeCallback) =>
+ axios({
+ method: requestOptions.method ? requestOptions.method.toLowerCase() : 'get',
+ url: requestOptions.url,
+ data: requestOptions.data ? requestOptions.data : null,
+ headers: {
+ ...requestOptions.headers,
+ 'X-Auth-Token': authToken,
+ 'X-App-Token': REACT_APP_X_APP_TOKEN
+ },
+ })
+ .then((response) => {
+ return Promise.resolve().then(() => successCallback && successCallback(response.data));
+ })
+ .catch(error => {
+ return Promise.reject().then(() => errorCallback && errorCallback(error));
+ })
+ .finally(() => {
+ completeCallback && completeCallback();
+ }),
+ [],
+ );
+};
+
+export default useAuthorizedHttp;
diff --git a/NFTVerse/MobileApp/hooks/use-http.js b/NFTVerse/MobileApp/hooks/use-http.js
new file mode 100644
index 00000000..e2cc034b
--- /dev/null
+++ b/NFTVerse/MobileApp/hooks/use-http.js
@@ -0,0 +1,26 @@
+import { useCallback } from 'react';
+import axios from 'axios';
+
+const useHttp = () => {
+ return useCallback(
+ (requestOptions, successCallback, errorCallback, completeCallback) =>
+ axios({
+ method: requestOptions.method ? requestOptions.method.toLowerCase() : 'get',
+ url: requestOptions.url,
+ data: requestOptions.data ? requestOptions.data : null,
+ headers: requestOptions.headers ? requestOptions.headers : undefined,
+ })
+ .then((response) => {
+ return Promise.resolve().then(() => successCallback && successCallback(response.data));
+ })
+ .catch(error => {
+ return Promise.reject().then(() => errorCallback && errorCallback(error));
+ })
+ .finally(() => {
+ completeCallback && completeCallback();
+ }),
+ [],
+ );
+};
+
+export default useHttp;
diff --git a/NFTVerse/MobileApp/hooks/useFetchToken.jsx b/NFTVerse/MobileApp/hooks/useFetchToken.jsx
new file mode 100644
index 00000000..fd51c928
--- /dev/null
+++ b/NFTVerse/MobileApp/hooks/useFetchToken.jsx
@@ -0,0 +1,57 @@
+import { REACT_APP_TAIL_COIN_TOKEN, REACT_APP_URL_BLOCKCHAIN_SERVICE, REACT_APP_X_APP_TOKEN } from 'denv';
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux';
+import { appActions } from '../store/app-slice';
+import useAuthorizedHttp from './use-authorized-http';
+
+
+export default function useFetchToken() {
+ const makeAuthorizedRequest = useAuthorizedHttp();
+ const appCtx = useSelector((state) => state.app)
+ const dispatch = useDispatch();
+ const [tokenAmount,setTokenAmount] = React.useState(0);
+ const [optedIn,setOptedIn] = React.useState(false);
+
+
+ const fetch=()=>{
+ makeAuthorizedRequest(
+ {
+ method: 'get',
+ url: `${REACT_APP_URL_BLOCKCHAIN_SERVICE}/user/${appCtx.walletAddress[0]?.address}/list`,
+ headers: {
+ "X-App-Token": REACT_APP_X_APP_TOKEN,
+ "X-Auth-Token": appCtx.authToken,
+ "Content-Type": "application/json",
+ }
+ },
+ (data) => {
+ console.log(data);
+ let tokenArray= [];
+ data.content?.map((item) => {
+ if (item.total?.lentgh > 1) {
+ return [...tokenArray, item]
+ }
+ if(item.assetId === REACT_APP_TAIL_COIN_TOKEN){
+ setTokenAmount(item?.amount/100);
+ setOptedIn(true);
+ }
+ })
+ console.log(tokenArray);
+
+ dispatch(appActions.setTaleAmount(tokenArray));
+
+ },
+ () => console.log(),
+ );
+ }
+ React.useEffect(() => {
+ // ${appCtx?.walletAddress[0].address}
+ fetch();
+ }, []);
+ return{
+ tokenAmount,
+ fetch,
+ optedIn,
+ setOptedIn
+ }
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/hooks/usePushNotification.jsx b/NFTVerse/MobileApp/hooks/usePushNotification.jsx
new file mode 100644
index 00000000..5f3da4b6
--- /dev/null
+++ b/NFTVerse/MobileApp/hooks/usePushNotification.jsx
@@ -0,0 +1,113 @@
+import { useState, useEffect, useRef } from 'react';
+import { Text, View, Button, Platform } from 'react-native';
+import * as Device from 'expo-device';
+import * as Notifications from 'expo-notifications';
+
+Notifications.setNotificationHandler({
+ handleNotification: async () => ({
+ shouldShowAlert: true,
+ shouldPlaySound: true,
+ shouldSetBadge: true,
+
+ }),
+});
+
+// Can use this function below OR use Expo's Push Notification Tool from: https://expo.dev/notifications
+async function sendPushNotification(expoPushToken) {
+ const message = {
+ to: expoPushToken,
+ sound: 'default',
+ title: 'Welcome to Tale wallet',
+ body: 'Complete E-KYC to claim 100 Tale coin',
+ data: { someData: 'goes here' },
+ };
+
+
+ fetch('https://exp.host/--/api/v2/push/send', {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Accept-encoding': 'gzip, deflate',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(message),
+ });
+}
+
+async function registerForPushNotificationsAsync() {
+ let token;
+ if (Device.isDevice) {
+ const { status: existingStatus } = await Notifications.getPermissionsAsync();
+ let finalStatus = existingStatus;
+ if (existingStatus !== 'granted') {
+ const { status } = await Notifications.requestPermissionsAsync();
+ finalStatus = status;
+ }
+ if (finalStatus !== 'granted') {
+ alert('Failed to get push token for push notification!');
+ return;
+ }
+ token = (await Notifications.getExpoPushTokenAsync()).data;
+ console.log(token);
+ } else {
+ alert('Must use physical device for Push Notifications');
+ }
+
+ if (Platform.OS === 'android') {
+ Notifications.setNotificationChannelAsync('default', {
+ name: 'default',
+ importance: Notifications.AndroidImportance.MAX,
+ vibrationPattern: [0, 250, 250, 250],
+ lightColor: '#FF231F7C',
+ });
+ }
+
+ return token;
+}
+
+export default function useFetchNotification() {
+ const [expoPushToken, setExpoPushToken] = useState('');
+ const [notification, setNotification] = useState(false);
+ const notificationListener = useRef();
+ const responseListener = useRef();
+
+ useEffect(() => {
+ registerForPushNotificationsAsync().then(token => setExpoPushToken(token));
+
+ notificationListener.current = Notifications.addNotificationReceivedListener(noti => {
+ setNotification(noti);
+ });
+
+ responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
+ console.log(response);
+ });
+
+ // return () => {
+ Notifications.removeNotificationSubscription(notificationListener.current);
+ Notifications.removeNotificationSubscription(responseListener.current);
+ // };
+ }, [expoPushToken]);
+
+ return{
+ expoPushToken,
+ notification,
+ sendPushNotification,
+
+ }
+ // return (
+ //
+ // Your expo push token: {expoPushToken}
+ //
+ // Title: {notification && notification.request.content.title}
+ // Body: {notification && notification.request.content.body}
+ // Data: {notification && JSON.stringify(notification.request.content.data)}
+ //
+ // {
+ // await sendPushNotification(expoPushToken);
+ // }}
+ // />
+ //
+ // );
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/index.js b/NFTVerse/MobileApp/index.js
new file mode 100644
index 00000000..1d6e981e
--- /dev/null
+++ b/NFTVerse/MobileApp/index.js
@@ -0,0 +1,8 @@
+import { registerRootComponent } from 'expo';
+
+import App from './App';
+
+// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
+// It also ensures that whether you load the app in Expo Go or in a native build,
+// the environment is set up appropriately
+registerRootComponent(App);
diff --git a/NFTVerse/MobileApp/metro.config.js b/NFTVerse/MobileApp/metro.config.js
new file mode 100644
index 00000000..9430b0f9
--- /dev/null
+++ b/NFTVerse/MobileApp/metro.config.js
@@ -0,0 +1,4 @@
+// Learn more https://docs.expo.io/guides/customizing-metro
+const { getDefaultConfig } = require('expo/metro-config');
+
+module.exports = getDefaultConfig(__dirname);
diff --git a/NFTVerse/MobileApp/package.json b/NFTVerse/MobileApp/package.json
new file mode 100644
index 00000000..a7c7436d
--- /dev/null
+++ b/NFTVerse/MobileApp/package.json
@@ -0,0 +1,51 @@
+{
+ "name": "cricktales",
+ "version": "1.0.0",
+ "scripts": {
+ "start": "expo start",
+ "android": "expo run:android",
+ "ios": "expo run:ios",
+ "web": "expo start --web",
+ "eject": "expo eject",
+ "test": "jest --watchAll",
+ "build": "eas build -p android --profile preview",
+ "link": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/",
+ "doc": "expo-cli doctor",
+ "docDep": "expo-cli doctor --fix-dependencies",
+ "release-build": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res",
+ "push": "expo push:android:upload --api-key AAAA8YuiTWM:APA91bEu-IlAA1jVdgP7TIdH3_g9d7U8Je0O34brjJ-euNXpQQZLl4dLux9HPgtQByAkm-YqcN6xsmk3fvPeEfVDDTi-b22FtPG6W8D6ux6_YrjYUTlVrQZixJby_MvwF1WlhA7J20ws",
+ "credentials": "eas credentials"
+ },
+ "dependencies": {
+ "@react-native-async-storage/async-storage": "^1.17.11",
+ "@react-navigation/bottom-tabs": "^6.5.7",
+ "@react-navigation/native": "^6.1.6",
+ "@react-navigation/native-stack": "^6.9.12",
+ "@reduxjs/toolkit": "^1.9.3",
+ "@types/react": "~18.0.27",
+ "axios": "^1.3.4",
+ "expo": "~48.0.4",
+ "expo-av": "^13.2.1",
+ "expo-clipboard": "^4.1.1",
+ "expo-device": "^5.2.1",
+ "expo-notifications": "^0.18.1",
+ "expo-splash-screen": "~0.18.1",
+ "expo-status-bar": "~1.4.4",
+ "nativewind": "^2.0.11",
+ "react": "18.2.0",
+ "react-native": "0.71.3",
+ "react-native-dotenv": "^3.4.8",
+ "react-native-gesture-handler": "^2.5.0",
+ "react-native-keyboard-aware-scroll-view": "^0.9.5",
+ "react-native-paper": "^5.2.0",
+ "react-redux": "^8.0.5",
+ "redux-persist": "^6.0.0",
+ "typescript": "^4.9.4",
+ "yarn": "^1.22.19"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.20.0",
+ "tailwindcss": "^3.2.7"
+ },
+ "private": true
+}
diff --git a/NFTVerse/MobileApp/screens/AuthLanding.jsx b/NFTVerse/MobileApp/screens/AuthLanding.jsx
new file mode 100644
index 00000000..a08c32f2
--- /dev/null
+++ b/NFTVerse/MobileApp/screens/AuthLanding.jsx
@@ -0,0 +1,44 @@
+import React, { FC } from 'react';
+import { Image, ImageBackground, SafeAreaView, Text, View } from 'react-native';
+import { NativeStackNavigationProp } from '@react-navigation/native-stack';
+import GreenOutlinedButton from '../components/common/GreenOutlinedButton';
+import BlackPrimaryButton from '../components/common/BlackPrimaryButton';
+import { ScrollView } from 'react-native-gesture-handler';
+
+const AuthLanding = ({ navigation }) => {
+ const handleNavigateToEmailAuth = React.useCallback(() => {
+ navigation.navigate('EmailAuth');
+ }, [navigation]);
+
+ return (
+
+
+
+
+
+
+ Welcome to Cric Tales
+
+ Sign In
+
+
+ Create account
+
+ {/*
+ Create Account
+
+
+ Already have an Account
+ */}
+
+
+ Powered By Tale Wallet
+ {/* {navigation.navigate('TAC')}}>Terms of Service and Privacy Policy */}
+
+
+
+
+ );
+};
+
+export default AuthLanding;
diff --git a/NFTVerse/MobileApp/screens/AuthorizedView.jsx b/NFTVerse/MobileApp/screens/AuthorizedView.jsx
new file mode 100644
index 00000000..2ba170b4
--- /dev/null
+++ b/NFTVerse/MobileApp/screens/AuthorizedView.jsx
@@ -0,0 +1,86 @@
+import React, { FC } from 'react';
+import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
+import { Image } from 'react-native';
+import Contest from '../components/Pages/Contest';
+import CustomTabBar from '../components/authorized-view/CustomTabBar';
+import Header from '../components/authorized-view/Header';
+import Wallet from '../components/Pages/Wallet';
+import Marketplace from '../components/Pages/Marketplace';
+
+const Tab = createBottomTabNavigator();
+
+const AuthorizedView = ({ navigation }) => {
+ return (
+ }
+ >
+ ,
+ tabBarIcon: ({ focused }) =>
+ focused ? (
+
+ ) : (
+
+ ),
+ }}
+ name="Contest"
+ component={Contest}
+ />
+ ,
+ tabBarIcon: ({ focused }) =>
+ focused ? (
+
+ ) : (
+
+ ),
+ }}
+ name="Marketplace"
+ component={Marketplace}
+ />
+
+ ,
+
+ tabBarIcon: ({ focused }) =>
+ focused ? (
+
+ ) : (
+
+ ),
+ }}
+ name="Wallet"
+ component={Wallet}
+ />
+
+ );
+};
+
+export default AuthorizedView;
diff --git a/NFTVerse/MobileApp/screens/EmailAuth.jsx b/NFTVerse/MobileApp/screens/EmailAuth.jsx
new file mode 100644
index 00000000..c8bfd592
--- /dev/null
+++ b/NFTVerse/MobileApp/screens/EmailAuth.jsx
@@ -0,0 +1,110 @@
+import React from 'react';
+import { Alert, Image, Text, TextInput, View, ImageBackground } from 'react-native';
+import BlackPrimaryButton from '../components/common/BlackPrimaryButton';
+import OtpSentModal from '../components/modals/OtpSentModal';
+import { NativeStackNavigationProp } from '@react-navigation/native-stack';
+import { appActions } from '../store/app-slice';
+import { useDispatch, useSelector } from 'react-redux';
+import { ScrollView } from 'react-native-gesture-handler';
+import { ActivityIndicator } from 'react-native-paper';
+import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
+import useHttp from '../hooks/use-http';
+import { REACT_APP_NFTVERSE_DEV_API } from 'denv';
+
+const EmailAuth = ({ navigation }) => {
+ const [emailSent, setEmailSent] = React.useState(false);
+ const [email, setEmail] = React.useState('');
+ const [loading, setLoading] = React.useState(false);
+ const appCtx = useSelector((state) => state.app);
+ const makeRequest = useHttp();
+ const dispatch = useDispatch();
+ const toggleEmailSent = React.useCallback(() => setEmailSent(prev => !prev), []);
+
+ const handleNavigateToOtp = React.useCallback(() => {
+ toggleEmailSent();
+ navigation.navigate('SubmitOTP', {
+ email,
+ });
+ }, [navigation, toggleEmailSent, email]);
+
+ const handleSendOtp = React.useCallback(() => {
+ console.log(REACT_APP_NFTVERSE_DEV_API);
+
+ if (!email) {
+ Alert.alert('Please enter your email');
+ return;
+ }
+ if (!/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(email)) {
+ Alert.alert('Please enter a valid email');
+ return;
+ }
+
+ setLoading(true);
+ makeRequest(
+ {
+ url: `${REACT_APP_NFTVERSE_DEV_API}/otp/send?type=login`,
+ data: { email },
+ method: 'post',
+ headers: {
+ 'X-App-Token': '123',
+ 'Content-Type': 'application/json',
+ },
+ },
+ (data) => {
+ console.log(data);
+
+ toggleEmailSent()
+ },
+ () => Alert.alert('Something went wrong'),
+ () => setLoading(false),
+ );
+ }, [navigation, toggleEmailSent, email]);
+
+ return (
+ <>
+
+
+ {
+ // scroll = ref
+ // }}
+ className={'flex flex-end flex-col gap-y-10 min-h-screen'}
+ contentContainerStyle={{ flex: 1, alignItems: 'center' }}
+ // behavior="height"
+ enableOnAndroid={true}
+ // resetScrollToCoords={{x:0,y:0}}
+ enableAutomaticScroll={true}
+ >
+
+
+ Welcome to Crick Tales
+
+
+
+
+
+
+
+ Send OTP
+
+
+
+
+ >
+ );
+};
+
+export default EmailAuth;
diff --git a/NFTVerse/MobileApp/screens/Onboarding.jsx b/NFTVerse/MobileApp/screens/Onboarding.jsx
new file mode 100644
index 00000000..5f812578
--- /dev/null
+++ b/NFTVerse/MobileApp/screens/Onboarding.jsx
@@ -0,0 +1,46 @@
+import React, { FC } from 'react';
+import { Dimensions, SafeAreaView, ScrollView, View } from 'react-native';
+
+const Onboarding = ({ navigation }) => {
+ const { width } = Dimensions.get('window');
+ const [slider, setSlider] = React.useState({ currentPage: 0 });
+
+ const setSliderPage = (event) => {
+ const { currentPage } = slider;
+ const { x } = event.nativeEvent.contentOffset;
+ const indexOfNextScreen = Math.round(x / width);
+ if (indexOfNextScreen !== currentPage) {
+ setSlider({
+ ...slider,
+ currentPage: indexOfNextScreen,
+ });
+ }
+ };
+
+ return (
+
+
+
+
+
+
+ {Array.from(Array(3).keys()).map((key, index) => (
+
+ ))}
+
+
+ );
+};
+
+export default Onboarding;
diff --git a/NFTVerse/MobileApp/screens/SubmitOTP.jsx b/NFTVerse/MobileApp/screens/SubmitOTP.jsx
new file mode 100644
index 00000000..736e3ca8
--- /dev/null
+++ b/NFTVerse/MobileApp/screens/SubmitOTP.jsx
@@ -0,0 +1,232 @@
+import React from 'react';
+import { Alert, Image, Keyboard, Pressable, Text, TextInput, ToastAndroid, View, ImageBackground, KeyboardAvoidingView } from 'react-native';
+import BlackPrimaryButton from '../components/common/BlackPrimaryButton';
+import useHttp from '../hooks/use-http';
+import { useDispatch } from 'react-redux';
+import { appActions } from '../store/app-slice';
+import { ScrollView } from 'react-native-gesture-handler';
+import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
+import axios from 'axios';
+import * as Device from 'expo-device';
+import { REACT_APP_NFTVERSE_DEV_API } from 'denv';
+
+const SubmitOTP = ({ route }) => {
+ const [otp, setOtp] = React.useState({
+ first: '',
+ second: '',
+ third: '',
+ fourth: '',
+ fifth: '',
+ sixth: '',
+ });
+ const [loading, setLoading] = React.useState(false);
+ const [resendOtp, setResendOtp] = React.useState(false);
+
+ const makeRequest = useHttp();
+
+ const dispatch = useDispatch();
+
+ const secondInputRef = React.useRef(null);
+ const thirdInputRef = React.useRef(null);
+ const fourthInputRef = React.useRef(null);
+ const fifthInputRef = React.useRef(null);
+ const sixthInputRef = React.useRef(null);
+
+ const handleOtpChange = React.useCallback((name, value) => {
+ setOtp(prev => ({ ...prev, [name]: value }));
+ if (name === 'first' && value.length === 1) {
+ secondInputRef.current?.focus();
+ }
+ if (name === 'second' && value.length === 1) {
+ thirdInputRef.current?.focus();
+ }
+ if (name === 'third' && value.length === 1) {
+ fourthInputRef.current?.focus();
+ }
+ if (name === 'fourth' && value.length === 1) {
+ fifthInputRef.current?.focus();
+ }
+ if (name === 'fifth' && value.length === 1) {
+ sixthInputRef.current?.focus();
+ }
+ }, []);
+
+ const handleOtpSubmit = React.useCallback(() => {
+ setLoading(true);
+ const otpText = Object.values(otp).join('');
+ if (!/\d{6}/.test(otpText)) {
+ ToastAndroid.show('Please enter a valid OTP', ToastAndroid.SHORT);
+ setLoading(false)
+ return;
+ }
+ let config={
+ method: 'post',
+ url: `${REACT_APP_NFTVERSE_DEV_API}/otp/verify?type=login`,
+ data: {
+ email: route.params.email,
+ otp: otpText,
+ userDevice:{
+ device:Device.brand,
+ deviceId:Device.osBuildId,
+ // firebaseId:'',
+ }
+ },
+ headers: {
+ 'X-App-Token': '123',
+ 'Content-Type': 'application/json',
+ },
+ }
+ console.log(config);
+
+ axios(config)
+ .then((res)=>{
+ let data=res.data;
+ ToastAndroid.show('OTP verified successfully', ToastAndroid.SHORT);
+ dispatch(appActions.updateUser(data));
+ dispatch(appActions.updateAuthToken(data.authToken))
+ dispatch(appActions.login());
+ setLoading(false)
+ })
+ .catch(()=>{
+ setLoading(false)
+ })
+
+ }, [otp]);
+
+
+ React.useEffect(() => {
+ if (Object.values(otp).every(value => value.length === 1)) Keyboard.dismiss();
+ }, [otp]);
+
+ const handleResendOtp = React.useCallback(() => {
+ let header = {};
+
+ makeRequest(
+ {
+ url: `${REACT_APP_NFTVERSE_DEV_API}/otp/send?type=wallet_login&resend=true`,
+ data: { "email": route.params.email },
+ method: "post",
+ },
+ (data) => {
+ Alert.alert('OTP Sent SuccesFully!')
+ // setReSendOtp(true);
+ // distance1 = 0;
+ // setOtp1('');
+ setOtp({
+ first: '',
+ second: '',
+ third: '',
+ fourth: '',
+ fifth: '',
+ sixth: '',
+ });
+ if (data.message === 'Success' && data.status === true) {
+ setResendOtp(true);
+ setLoading(false)
+ }
+ },
+ () => { setLoading(false)}
+ )
+ }, [])
+
+ return (
+
+
+ {
+ // scroll = ref
+ // }}
+ className={'flex flex-end flex-col gap-y-10 min-h-screen'}
+ contentContainerStyle={{ flex:1,alignItems: 'center' }}
+ // behavior="height"
+ enableOnAndroid={true}
+ // resetScrollToCoords={{x:0,y:0}}
+ enableAutomaticScroll={true}
+ >
+
+ Welcome to Crick Tales
+
+ OTP verification
+ Please enter the verification code sent to your mail
+
+ handleOtpChange('first', value)}
+ autoFocus
+ onSubmitEditing={() => secondInputRef.current?.focus()}
+ />
+ handleOtpChange('second', value)}
+ ref={secondInputRef}
+ onSubmitEditing={() => thirdInputRef.current?.focus()}
+ />
+ handleOtpChange('third', value)}
+ ref={thirdInputRef}
+ onSubmitEditing={() => fourthInputRef.current?.focus()}
+ />
+ handleOtpChange('fourth', value)}
+ ref={fourthInputRef}
+ />
+ handleOtpChange('fifth', value)}
+ ref={fifthInputRef}
+ />
+ handleOtpChange('sixth', value)}
+ ref={sixthInputRef}
+ />
+
+
+
+ Submit
+
+
+ Didn't receive the OTP?
+
+ {!resendOtp ?
+ { handleResendOtp() }}>Resend OTP
+ :
+ { }}>Resend successfull
+ }
+
+
+
+
+
+ );
+};
+
+export default SubmitOTP;
diff --git a/NFTVerse/MobileApp/store/app-slice.ts b/NFTVerse/MobileApp/store/app-slice.ts
new file mode 100644
index 00000000..15be348d
--- /dev/null
+++ b/NFTVerse/MobileApp/store/app-slice.ts
@@ -0,0 +1,88 @@
+import { createSlice, } from '@reduxjs/toolkit';
+
+const appSliceInitialState = {
+ user: {
+ userId: null,
+ firstName: null,
+ lastName: null,
+ email: null,
+ mobile: null,
+ avatar: null,
+ authToken: null,
+ userName: null,
+ bio: null,
+ gender: null,
+ },
+ isLoggedIn: false,
+ walletAddress: [{ address: '' }],
+ authToken: '',
+ frontSide: '',
+ backSide: '',
+ picture: '',
+ cameraPicture: '',
+ country: '',
+ verified: false,
+ rejection: null,
+ taleAmount: 0,
+ nft:'',
+};
+
+const appSlice = createSlice({
+ name: 'app',
+ initialState: appSliceInitialState,
+ reducers: {
+ login(state) {
+ state.isLoggedIn = true;
+ },
+ logout(state) {
+ state.isLoggedIn = false;
+ },
+ updateUser(state, action) {
+ state.user.userId = action.payload.userId;
+ state.user.firstName = action.payload.firstName;
+ state.user.lastName = action.payload.lastName;
+ state.user.email = action.payload.email;
+ state.user.mobile = action.payload.mobile;
+ state.user.avatar = action.payload.avatar;
+ state.user.authToken = action.payload.authToken;
+ state.user.userName = action.payload.userName;
+ state.user.bio = action.payload.bio;
+ },
+ setWalletAddress(state, action) {
+ state.walletAddress = action.payload;
+ },
+ updateAuthToken(state, action) {
+ state.authToken = action.payload;
+ },
+ setFrontSide(state, action) {
+ state.frontSide = action.payload;
+ },
+ setBackSide(state, action) {
+ state.backSide = action.payload;
+ },
+ setCountry(state, action) {
+ state.country = action.payload;
+ },
+ setPicture(state, action) {
+ state.picture = action.payload;
+ },
+ setCameraPicture(state, action) {
+ state.cameraPicture = action.payload;
+ },
+ setVerified(state, action) {
+ state.verified = action.payload;
+ },
+ setRejection(state, action) {
+ state.rejection = action.payload;
+ },
+ setTaleAmount(state, action) {
+ state.taleAmount = action.payload;
+ },
+ setNft(state, action){
+ state.nft = action.payload;
+ }
+ },
+});
+
+export const appActions = appSlice.actions;
+export const appReducer = appSlice.reducer;
diff --git a/NFTVerse/MobileApp/store/store.ts b/NFTVerse/MobileApp/store/store.ts
new file mode 100644
index 00000000..464cf37d
--- /dev/null
+++ b/NFTVerse/MobileApp/store/store.ts
@@ -0,0 +1,32 @@
+import { appReducer } from './app-slice';
+import { combineReducers, configureStore } from '@reduxjs/toolkit';
+import { FLUSH, PAUSE, PERSIST, persistReducer, persistStore, PURGE, REGISTER, REHYDRATE } from 'redux-persist';
+import AsyncStorage from '@react-native-async-storage/async-storage';
+
+const rootPersistConfig = {
+ key: 'nftversewallet-root',
+ storage: AsyncStorage,
+};
+
+const appPersistConfig = {
+ key: 'nftversewallet-app',
+ storage: AsyncStorage,
+};
+
+const rootReducer = combineReducers({
+ app: persistReducer(appPersistConfig, appReducer),
+});
+
+const store = configureStore({
+ reducer: persistReducer(rootPersistConfig, rootReducer),
+ middleware: getDefaultMiddleware =>
+ getDefaultMiddleware({
+ serializableCheck: {
+ ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
+ },
+ }),
+});
+
+export const persistor = persistStore(store);
+export default store;
+export type RootDispatch = ReturnType;
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/tailwind.config.js b/NFTVerse/MobileApp/tailwind.config.js
new file mode 100644
index 00000000..97137cfb
--- /dev/null
+++ b/NFTVerse/MobileApp/tailwind.config.js
@@ -0,0 +1,13 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ["./App.{js,jsx,ts,tsx}", './components/**/*.{js,jsx,ts,tsx}', './screens/**/*.{js,jsx,ts,tsx}'],
+ theme: {
+ extend: {
+ colors: {
+ neon: '#BBFF00',
+ black: '#0C0C0C'
+ }
+ },
+ },
+ plugins: [],
+}
\ No newline at end of file
diff --git a/NFTVerse/MobileApp/tsconfig.json b/NFTVerse/MobileApp/tsconfig.json
new file mode 100644
index 00000000..1d1f77d5
--- /dev/null
+++ b/NFTVerse/MobileApp/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "expo/tsconfig.base",
+ "compilerOptions": {
+ "jsx": "react",
+ "strict": true
+ },
+ "typeRoots": [
+ "./types"
+ ]
+}
diff --git a/NFTVerse/README.MD b/NFTVerse/README.MD
new file mode 100644
index 00000000..b60a460b
--- /dev/null
+++ b/NFTVerse/README.MD
@@ -0,0 +1,50 @@
+CricTales:
+Contracts deployed on Testnet
+Address: https://testnet.flowscan.org/account/0x2e0e1fc45f23609e
+
+Contracts folder - All the smart contract
+Transactions folder - All the transactions needed for blockchain(to mint token, to transfer token)
+Scripts folder: All the read request from blockchain
+WalletPlugin: javascript library for wallet integration on any web2 apps/website
+Mobile App - CricTales Game mobile App
+
+Problem statement: Creating digital twins of ICC merchandise and loyalty program by creating a decentralised Fan Token (CRICK Token) that can be mined by doing different activities across different ICC apps and events and creating a real/virtual world utility for those tokens.
+
+Solution: SDK for digital twins and loyalty program. Code is inside WalletPlugin folder. The wallet plugin can be integrated on any web 2.0 apps where users can create and manage their crypto assets (mainly for cricToken and crictales NFTs).
+Utility of Token and NFT: A card game where users can stake their cric tokens to play against other users and win rewards. Source code can be found inside Mobile App folder.
+APK for testing: https://drive.google.com/file/d/1eCxpjtmaMfYt4oZ-0w9AN1M7TA-9f1xb/view?usp=sharing
+
+Game Play!
+In crictales game the user needs to create the deck of 5,10,15 etc NFT cards of the cricket player whose stats they think can help them win this game. To Get these cards users need to purchase them through various sites like cricktose etc.
+
+
+
+How to play this game ?
+
+Step 1 - Visit our game app and login using your email address. Once you logged in you will come across this below mentioned screen.
+
+
+Step 2 - Once you come across this screen you can see all the ongoing contests and the card requirements. Click on the “play Now” button on any of the contests which you want to play.
+If you have required cards you can enter in the game and follow the steps & start playing if you don't have cards you need to go to the NFT cards marketplace to buy them and then can enter in the game.
+
+Step - 3 Once you meet the requirements of the game you will be redirected to this screen where you need to create a deck and participate in the game by clicking on ”create” button with those deck of Players NFT cards. You can also view the potential rewards over there.
+
+Step - 4 You need to click on the create deck option and you will be redirected to the screen mentioned below. From There you can select your favourite cards to create the custom deck for the game.
+
+
+Step - 5 Once you select all the required number of cards (say 5 ) then click on the “select 5 cards” button and you will be redirected to the below mentioned screen where you can customize the name of your deck and the display image of the deck
+
+Step - 6 Once you fill the deck info click on “create now” then the deck will be created,and you will be redirected to the initial screen where you can see the custom deck on the top of the screen (as shown in the image below). You just need to click & select the “theme1” deck i.e the custom deck & proceed ahead to play the game by clicking on “join the contest”.
+
+
+Step - 7 Once you Join the contest this below mentioned screen will appear where you need to select either “head” or tail. . A coin toss is then held to determine the winner, who gets the first chance to throw a card in the game. Which will look something like below mentioned screen and a pop-up message appears when you win/loose the toss.
+
+
+
+Step - 8 Once you win the toss you need to select the cards and then the particular stats of those cards & then throw similarly your opponent will also do and the stats will get compared and whose stats will be greater will win that round. Similarly the Next round will happen like this only.
+
+
+To play the game, You must select a card from their deck and choose the stat with which they want to throw the card. For example In the following image, the user has selected the "total matches played" stat and decides to throw the card. If the stat of the thrown card is greater than the opponent's, the user wins the round.
+
+
+So if your stats is greater then you will win and a congratulation message screen will appear shown above and then proceed ahead to play the next round in a similar way.
diff --git a/NFTVerse/WalletPlugin/README.MD b/NFTVerse/WalletPlugin/README.MD
new file mode 100644
index 00000000..dbcde648
--- /dev/null
+++ b/NFTVerse/WalletPlugin/README.MD
@@ -0,0 +1,9 @@
+To add wallet interface on any html page, just put this script in the page
+```
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git a/NFTVerse/WalletPlugin/css/otp_login.css b/NFTVerse/WalletPlugin/css/otp_login.css
new file mode 100644
index 00000000..8d75f21d
--- /dev/null
+++ b/NFTVerse/WalletPlugin/css/otp_login.css
@@ -0,0 +1,3 @@
+.main{
+ width: 300px;
+}
\ No newline at end of file
diff --git a/NFTVerse/WalletPlugin/images/avatar.png b/NFTVerse/WalletPlugin/images/avatar.png
new file mode 100755
index 00000000..e1741c24
Binary files /dev/null and b/NFTVerse/WalletPlugin/images/avatar.png differ
diff --git a/NFTVerse/WalletPlugin/images/copy.png b/NFTVerse/WalletPlugin/images/copy.png
new file mode 100644
index 00000000..9ee8d1c8
Binary files /dev/null and b/NFTVerse/WalletPlugin/images/copy.png differ
diff --git a/NFTVerse/WalletPlugin/images/ellipse.svg b/NFTVerse/WalletPlugin/images/ellipse.svg
new file mode 100644
index 00000000..8276d2ca
--- /dev/null
+++ b/NFTVerse/WalletPlugin/images/ellipse.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/NFTVerse/WalletPlugin/images/flow.png b/NFTVerse/WalletPlugin/images/flow.png
new file mode 100644
index 00000000..3469a283
Binary files /dev/null and b/NFTVerse/WalletPlugin/images/flow.png differ
diff --git a/NFTVerse/WalletPlugin/images/icon-128.png b/NFTVerse/WalletPlugin/images/icon-128.png
new file mode 100644
index 00000000..48941f0a
Binary files /dev/null and b/NFTVerse/WalletPlugin/images/icon-128.png differ
diff --git a/NFTVerse/WalletPlugin/images/icon-16.png b/NFTVerse/WalletPlugin/images/icon-16.png
new file mode 100644
index 00000000..84c1f982
Binary files /dev/null and b/NFTVerse/WalletPlugin/images/icon-16.png differ
diff --git a/NFTVerse/WalletPlugin/images/icon-48.png b/NFTVerse/WalletPlugin/images/icon-48.png
new file mode 100644
index 00000000..879d65b9
Binary files /dev/null and b/NFTVerse/WalletPlugin/images/icon-48.png differ
diff --git a/NFTVerse/WalletPlugin/images/loader.gif b/NFTVerse/WalletPlugin/images/loader.gif
new file mode 100755
index 00000000..bdc85166
Binary files /dev/null and b/NFTVerse/WalletPlugin/images/loader.gif differ
diff --git a/NFTVerse/WalletPlugin/images/mail.svg b/NFTVerse/WalletPlugin/images/mail.svg
new file mode 100644
index 00000000..719b4229
--- /dev/null
+++ b/NFTVerse/WalletPlugin/images/mail.svg
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NFTVerse/WalletPlugin/images/profile-icons/Kyc.svg b/NFTVerse/WalletPlugin/images/profile-icons/Kyc.svg
new file mode 100644
index 00000000..5e0b8ac6
--- /dev/null
+++ b/NFTVerse/WalletPlugin/images/profile-icons/Kyc.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NFTVerse/WalletPlugin/images/profile-icons/accountdetail.svg b/NFTVerse/WalletPlugin/images/profile-icons/accountdetail.svg
new file mode 100644
index 00000000..6c0573ee
--- /dev/null
+++ b/NFTVerse/WalletPlugin/images/profile-icons/accountdetail.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/NFTVerse/WalletPlugin/images/profile-icons/algoscan.svg b/NFTVerse/WalletPlugin/images/profile-icons/algoscan.svg
new file mode 100644
index 00000000..6cb1602b
--- /dev/null
+++ b/NFTVerse/WalletPlugin/images/profile-icons/algoscan.svg
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NFTVerse/WalletPlugin/images/profile-icons/lock.svg b/NFTVerse/WalletPlugin/images/profile-icons/lock.svg
new file mode 100644
index 00000000..c31285d0
--- /dev/null
+++ b/NFTVerse/WalletPlugin/images/profile-icons/lock.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/NFTVerse/WalletPlugin/images/profile-icons/support.png b/NFTVerse/WalletPlugin/images/profile-icons/support.png
new file mode 100644
index 00000000..0ff09f59
Binary files /dev/null and b/NFTVerse/WalletPlugin/images/profile-icons/support.png differ
diff --git a/NFTVerse/WalletPlugin/images/profile.svg b/NFTVerse/WalletPlugin/images/profile.svg
new file mode 100644
index 00000000..aa40e172
--- /dev/null
+++ b/NFTVerse/WalletPlugin/images/profile.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/NFTVerse/WalletPlugin/images/talewallet.png b/NFTVerse/WalletPlugin/images/talewallet.png
new file mode 100644
index 00000000..e87ead68
Binary files /dev/null and b/NFTVerse/WalletPlugin/images/talewallet.png differ
diff --git a/NFTVerse/WalletPlugin/images/talewallet.svg b/NFTVerse/WalletPlugin/images/talewallet.svg
new file mode 100644
index 00000000..f83bfb9b
--- /dev/null
+++ b/NFTVerse/WalletPlugin/images/talewallet.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/NFTVerse/WalletPlugin/images/testnet.png b/NFTVerse/WalletPlugin/images/testnet.png
new file mode 100644
index 00000000..5e928598
Binary files /dev/null and b/NFTVerse/WalletPlugin/images/testnet.png differ
diff --git a/NFTVerse/WalletPlugin/index.html b/NFTVerse/WalletPlugin/index.html
new file mode 100644
index 00000000..39d673ac
--- /dev/null
+++ b/NFTVerse/WalletPlugin/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+ Title
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NFTVerse/WalletPlugin/talewallet.css b/NFTVerse/WalletPlugin/talewallet.css
new file mode 100644
index 00000000..b91ba5f9
--- /dev/null
+++ b/NFTVerse/WalletPlugin/talewallet.css
@@ -0,0 +1,608 @@
+/* Bordered form */
+:root{
+ --taile-color:#bf00ff;
+}
+form {
+ border: 3px solid #f1f1f1;
+}
+
+/* Full-width inputs */
+input[type=text], input[type=password] {
+ width: 100%;
+ padding: 12px 20px;
+ /* display: inline-block; */
+ border: 1px solid #ccc;
+ box-sizing: border-box;
+ background-color: inherit;
+}
+
+/* .box-shadow-1{
+ box-shadow: rgb(204, 219, 232) 3px 3px 6px 0px inset, rgba(255, 255, 255, 0.5) -3px -3px 6px 1px inset;
+
+} */
+
+/* .shadow-1{
+
+ box-shadow: rgb(204, 219, 232) 3px 3px 6px 0px inset, rgba(255, 255, 255, 0.5) -3px -3px 6px 1px inset;
+} */
+
+.border-none{
+ border: none !important;
+}
+.border-slate{
+ border: 1px solid #bdb8b8;
+}
+.border-radius-10{
+ border-radius: 10px;
+}
+.email-input-container{
+ border-radius: 10px;
+ background:#f5f5f5;
+ overflow: hidden;
+}
+
+.email-input-container img{
+ width: 40px;
+ height: 40px;
+ object-fit: contain;
+}
+.outline-none{
+ outline: none;
+}
+.w-full{
+ width: 100%;
+}
+.w-40{
+ width: 30px;
+}
+.d-50{
+ width: 50px;
+ height: 50px;
+}
+.d-150{
+ width: 150px;
+ height: 150px;
+}
+.w-100{
+ width: 100px;
+}
+.w-1000{
+ width: 1000px;
+}
+.w-50{
+ width: 50px;
+}
+.h-100{
+ height: 100px;
+}
+.h-40{
+ height: 30px;
+}
+.py-10{
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+.px-30{
+ padding-left:30px;
+ padding-right: 30px;
+}
+.px-10{
+ padding-left: 10px;
+ padding-right: 10px;
+}
+.p-10{
+ padding: 10px;
+}
+.gap-5{
+ gap: 5px;
+}
+.gap-20{
+ gap: 20px;
+}
+
+.gap-100{
+ gap:100px;
+}
+.text-center{
+ text-align: center;
+}
+.text-ellipsis{
+ text-overflow: ellipsis;
+}
+.font-bold{
+ font-weight: 600;
+}
+.font-semibold{
+ font-weight: 500;
+}
+.text-2xl{
+ font-size: 32px;
+}
+.text-lg{
+ font-size: 20px;
+}
+
+.text-medium{
+ font-size: 16px;
+}
+.text-start{
+ text-align: start;
+}
+.font-14{
+ font-size: 14px;
+}
+.text-tale{
+ color: var(--taile-color);
+}
+.text-warning{
+ color: #ff0000;
+}
+/* Set a style for all buttons */
+/* button {
+ background-color: #4CAF50;
+ color: white;
+ padding: 14px 20px;
+ margin: 8px 0;
+ border: none;
+ cursor: pointer;
+ width: 100%;
+} */
+.create-account-actions{
+ display: flex ;
+ flex-direction: column;
+ gap: 15px;
+}
+.manage-account-details{
+ display: flex;
+ flex-direction: column;
+ gap:20px;
+}
+.algo-network{
+ border-radius: 99999px;
+ color: black;
+ background: white;
+ padding: 10px 20px;
+ position: relative;
+ top: -10px;
+
+ border: 1px solid #bbff00;
+}
+.btn{
+ border-radius: 99999px;
+ color: #bbff00;
+ width: 100%;
+ padding: 15px 0;
+ cursor: pointer;
+ border: 1px solid #bbff00;
+ transition: .2s ease;
+
+}
+
+.activity-border{
+ width: 100%;
+ height: 2px;
+ background: #aaa6a6;
+ position: absolute;
+ bottom: 0;
+}
+
+.primary-btn{
+ background-color: #0c0c0c;
+
+}
+.primary-btn:hover{
+ background-color: #bbff00;
+ color:#0c0c0c ;
+
+}
+.secondary-btn{
+ background-color: #ffffff;
+ color: black;
+}
+.secondary-btn:hover{
+ background-color: #bbff00;
+ color: #ffffff;
+}
+.activity-button{
+ border: none;
+ cursor: pointer;
+ font-size: 16px;
+ background-color: #e5e5e5;
+ padding: 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+.activity-selected{
+ border-bottom: 2px solid #bbff00;
+}
+
+button:disabled {
+ cursor: auto;
+ background-color:gray;
+}
+
+/* Add a hover effect for buttons */
+/* button:hover {
+ opacity: 0.8;
+} */
+
+/* Extra style for the cancel button (red) */
+.cancelbtn {
+ width: auto;
+ padding: 10px 18px;
+ background-color: #f44336;
+}
+
+/* Center the avatar image inside this container */
+.imgcontainer {
+ text-align: center;
+ margin: 24px 0 12px 0;
+}
+
+/* Avatar image */
+img.avatar {
+ width: 100px;
+ border-radius: 50%;
+}
+.justify-end{
+ justify-content: flex-end;
+}
+.justify-between{
+ justify-content: space-between;
+}
+.justify-center{
+ justify-content: center;
+}
+.justify-evenly{
+ justify-content: space-evenly;
+}
+.justify-around{
+ justify-content: space-around;
+}
+img.avatar1 {
+ width: 30px;
+ border-radius: 50%;
+}
+
+.flex{
+ display: flex;
+
+}
+.hidden{
+ display: none ;
+}
+.flex-wrap{
+ flex-wrap: wrap;
+}
+.object-contain{
+ object-fit: contain;
+}
+
+.text-xl{
+ font-size: 28px;
+}
+.flex-col{
+ flex-direction: column;
+}
+.items-start{
+ align-items: flex-start;
+}
+.items-center{
+ align-items: center;
+}
+.gap-5{
+ gap: 5px;
+}
+.gap-10{
+ gap: 10px;
+}
+.gap-40{
+ gap: 40px;
+}
+.mt-20{
+ margin-top: 20px;
+}
+.mt-10{
+ margin-top: 10px;
+}
+.my-20{
+ margin: 20px 0;
+}
+.mx-20{
+ margin: 0 20px;
+}
+/* position */
+.relative{
+ position: relative;
+}
+.absolute{
+ position: absolute;
+}
+.fixed{
+ position: fixed;
+}
+.left-10{
+ left: 10px;
+}
+.z-10{
+ z-index: 10;
+}
+/* Add padding to containers */
+/* .container {
+ padding: 16px;
+} */
+
+/* The "Forgot password" text */
+span.psw {
+ float: right;
+ padding-top: 16px;
+}
+.asset-image{
+ width: 120px;
+ height: 150px;
+ object-fit: contain;
+}
+.asset-container{
+ width: 120px;
+ height: 180px;
+ border: 1px solid gray;
+ /* border-radius: 10px; */
+ overflow: hidden;
+ color: black;
+ font-weight: 600;
+ background: white;
+
+}
+.break-word{
+ word-wrap: break-word;
+}
+.gap-y-10{
+ column-gap: 10px;
+}
+/* Change styles for span and cancel button on extra small screens */
+@media screen and (max-width: 300px) {
+ span.psw {
+ display: block;
+ float: none;
+ }
+ .cancelbtn {
+ width: 100%;
+ }
+}
+
+#buy-btn{
+ padding: 10px 0;
+ width: 80px;
+}
+#sell-btn{
+ padding: 10px 0;
+ width: 80px;
+}
+#modal-container{
+ width: 300px;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.7);
+ z-index: 100;
+ position: fixed;
+ top:0px;
+ font-size: 14px;
+
+
+}
+
+/* back UI */
+.back-s1{
+ width:10px;
+ height:3px;
+ background:black;
+ transform:rotate(135deg)
+}
+.back-s2{
+ position:relative;
+ left:2px;
+ width:20px;
+ height:3px;
+ background:black;
+}
+.back-s3{
+ width:10px;
+ height:3px;
+ background:black;
+ transform:rotate(45deg)
+}
+
+.profile-modal{
+ position: absolute;
+ width: 210px;
+ background-color: #f1f1f2;
+ border-radius: 10px;
+ right: 5px;
+ top: 60px;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ padding: 10px 0;
+}
+
+.modal-items-container{
+ display: flex;
+ border-radius: 30px;
+ padding: 10px 0;
+ justify-content: flex-start;
+ align-items: center;
+ gap: 10px;
+ cursor: pointer;
+ padding-left: 10px;
+ transition: .2s ease;
+ box-shadow: rgb(204, 219, 232) 3px 3px 6px 0px inset, rgba(255, 255, 255, 0.5) -3px -3px 6px 1px inset;
+}
+
+.modal-items-container:hover{
+ background: #fcfafa;
+}
+
+.main{
+ width: 300px;
+ text-align: center;
+ min-height: 550px;
+ /* padding: 10px; */
+
+}
+#opt-in-option:disabled{
+ background: none;
+ color: #0c0c0c;
+}
+.wallet-address-container{
+ /* border: 1px solid; */
+ padding: 10px;
+ border-radius: 10px;
+ box-shadow: rgb(204, 219, 232) 3px 3px 6px 0px inset, rgba(255, 255, 255, 0.5) -3px -3px 6px 1px inset;
+
+}
+.cursor-pointer{
+ cursor: pointer;
+}
+.token-container{
+ padding:10px;
+ display: flex;
+ justify-content: space-between;
+ gap: 5px;
+ font-weight: bold;
+ align-items: center;
+ border: 1px solid rgb(176, 172, 172);
+ border-radius: 9000px;
+ width: 80%;
+}
+
+.overflow-x-scroll{
+ overflow-x: scroll;
+}
+.limit-words-overflow{
+ width: 100px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.activity-item-container{
+ margin: 5px;
+ padding: 10px;
+ --tw-bg-opacity: 1;
+ background-color: rgb(243 232 255/var(--tw-bg-opacity));
+ --tw-border-opacity: 1;
+ /* border-color: rgb(233 213 255/var(--tw-border-opacity)); */
+ border: 1px solid rgb(233 213 255/var(--tw-border-opacity));
+ width: 100%;
+ border-radius: 0.75rem;
+ align-items: center;
+ display: grid;
+ -webkit-box-shadow: 0 10px 6px -6px #777;
+ -moz-box-shadow: 0 10px 6px -6px #777;
+ box-shadow: 0 10px 6px -6px #777;
+ grid-template-columns: repeat(9,minmax(0,1fr));
+}
+body{
+ border-radius: 40px;
+ margin: 0;
+ background-color: #f1f1f2;
+}
+a{
+ text-decoration: none;
+ color: cornflowerblue;
+ cursor: pointer;
+}
+li{
+ margin-bottom: 10px;
+}
+ol{
+ padding-left: 15px;
+}
+#rebuttals {
+ text-align: left;
+ margin-top: 40px;
+}
+#wallet_div{
+ padding: 10px 10px;
+ width: 40%;
+ margin-left: 30%;
+ border: 1px solid #e5e5e5;
+}
+.img-icon{
+ width: 15px;
+ height: 15px;
+ object-fit: contain;
+}
+/* .btn{
+ border: none;
+ display: inline-block;
+ padding: 8px 16px;
+ vertical-align: middle;
+ overflow: hidden;
+ text-decoration: none;
+ color: inherit;
+ background-color: inherit;
+ text-align: center;
+ cursor: pointer;
+ white-space: nowrap;
+} */
+.button1 {
+ color: #FFFFFF;
+ background-color: #f0ad4e;
+ box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
+}
+.checkmark {
+ display:inline-block;
+ width: 22px;
+ height:22px;
+ -ms-transform: rotate(45deg); /* IE 9 */
+ -webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */
+ transform: rotate(45deg);
+}
+
+.checkmark_circle {
+ position: absolute;
+ width:22px;
+ height:22px;
+ background-color: green;
+ border-radius:11px;
+ left:0;
+ top:0;
+}
+.checkmark_stem {
+ position: absolute;
+ width:3px;
+ height:9px;
+ background-color:#fff;
+ left:11px;
+ top:6px;
+}
+
+.checkmark_kick {
+ position: absolute;
+ width:3px;
+ height:3px;
+ background-color:#fff;
+ left:8px;
+ top:12px;
+}
+.cross_mark{
+ height: 22px;
+ width: 22px;
+ background-color: #ff0000;
+ border-radius: 50%;
+ text-align: center;
+ font-size: 21px;
+ padding-left: 4px;
+ padding-right: 4px;
+ color: white;
+ font-family: monospace;
+}
+.transparencyli{
+ padding-top: 10px;
+ padding-bottom: 10px;
+ border-bottom: 1px solid #e5e5e5;
+}
+.transparencyul{
+ list-style-type: none;
+ padding-left: 0px;
+ text-align: left;
+}
\ No newline at end of file
diff --git a/NFTVerse/WalletPlugin/talewallet.js b/NFTVerse/WalletPlugin/talewallet.js
new file mode 100644
index 00000000..20d8121e
--- /dev/null
+++ b/NFTVerse/WalletPlugin/talewallet.js
@@ -0,0 +1,230 @@
+WALLET_NAME = "ICC Wallet"
+NFTVERSE_DEV_API = "https://us-dev.api.onnftverse.com/v1"
+BLOCKCHAIN_SERVICE = "https://bs-dev.api.onnftverse.com/v1"
+app_token = 123
+
+function loginUI() {
+ document.getElementById('wallet_div').innerHTML = `
+
+
+
+
+
Welcome to `+WALLET_NAME+`
+
Veirfy your email address
+
+
`;
+ var link = document.getElementById('sbt_email_otp_btn');
+ // onClick's logic below:
+ if(link) {
+ link.addEventListener('click', function () {
+ sendOTP(document.getElementById('otp_email_address').value);
+ });
+ }
+}
+
+function validateEmail(email) {
+ const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+ return re.test(String(email).toLowerCase());
+}
+
+function sendOTP(email) {
+ if(!validateEmail(email)){
+ document.getElementById("sb_rb_error").innerHTML="
Email id is expected "
+ } else{
+ let config = {
+
+ method:"post",
+ headers:{
+ "X-App-Token": app_token,
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ email:email
+ })
+ }
+
+ fetch(`${NFTVERSE_DEV_API}/otp/send?type=login`,config).then(
+ (res) =>{
+ document.getElementById('email_address_input').innerHTML = `
+
+
+
Submit Otp
+
In future you will be able to access your account using this email and OTP
+
`;
+ document.getElementById("sb_rb_error").innerHTML=""
+ const submitOtpBtn = document.getElementById("submit_otp_btn");
+ submitOtpBtn.addEventListener('click', function () {
+ verifyOtp(email, document.getElementById('input_otp').value);
+ });
+ }
+ )
+ }
+}
+
+function verifyOtp(email,otp){
+ console.log(otp)
+ if(!otp){
+ document.getElementById("sb_rb_error").innerHTML="Otp is expected "
+ }else{
+ let config = {
+
+ method:"post",
+ headers:{
+ "X-App-Token": app_token,
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ email:email,
+ otp:otp
+ })
+ }
+ fetch(`${NFTVERSE_DEV_API}/otp/verify?type=login`,config)
+ .then((res) => res.json())
+ .then(res => {
+ getOrSetupWallet(res.userId, res.authToken);
+ })
+ .catch(rej => document.getElementById("sb_rb_error").innerHTML="Wrong otp " )
+ }
+}
+function getOrSetupWallet(userId, authToken){
+ localStorage.setItem("wallet_authToken", authToken)
+ localStorage.setItem("userId", userId)
+ let config = {
+
+ method:"get",
+ headers:{
+ "X-Auth-Token": authToken ,
+ "Content-Type": "application/json",
+ }
+ }
+
+ fetch(`${BLOCKCHAIN_SERVICE}/user/blockchain/account?blockchain=FLOW`,config)
+ .then(res => res.json())
+ .then(res => {
+
+ const talewallet = res?.filter(wallet => wallet.wallet ==="TALEWALLET");
+ if(talewallet?.length === 0){
+ setUpTaleWallet(authToken);
+ }
+ else{
+ localStorage.setItem("tale_wallet_address",talewallet[0].address)
+ showWalletUI(talewallet[0].address)
+ }
+ }
+ )
+ .catch(rej => document.getElementById("sb_rb_error").innerHTML="Having trouble getting account try again later " )
+}
+
+function setUpTaleWallet(authToken){
+ let config = {
+ method:"post",
+ headers:{
+ "X-Auth-Token": authToken,
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ blockchain: "FLOW",
+ wallet: "TALEWALLET",
+ marketplaceAddress: 0,
+
+ })
+ }
+ fetch(`${BLOCKCHAIN_SERVICE}/user/blockchain/wallet/setup`,config)
+ .then(res => res.json())
+ .then(res =>{
+ localStorage.setItem("tale_wallet_address",res.address)
+ document.getElementById('wallet_div').innerHTML = '';
+ showWalletUI(res.address)
+
+ })
+ .catch(rej => console.log(rej))
+
+}
+function showWalletUI(tale_wallet_address){
+ document.getElementById("wallet_div").innerHTML = `
+
+
+
+
+
+
+
Testnet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
${tale_wallet_address}
+
+
+
+
+
+
+
+
fetching ...
+
+
+ Earn More
+ Sell
+
+
+ `;
+ fetchTokenBalance(tale_wallet_address)
+ fetchNFTs(tale_wallet_address)
+}
+
+function fetchTokenBalance(address){
+ document.getElementById("wallet_balance").innerHTML =`100 Cric Token`
+}
+function fetchNFTs(address){
+ var imageSrc='https://nftverse-dev.mypinata.cloud/ipfs/QmaKWGkJPY5QFFGW4NjLdC1LEfAzGMjp4fLWowE4qfSYtg';
+ var name = "MS Dhoni"
+ var c = ` `;
+ c = c + `
+
+
+
+
+
${name}
+
+ `;
+ document.getElementById("wallet_asset_container").innerHTML = c+ "
"
+}
+document.addEventListener("DOMContentLoaded", () => {
+ console.log("Hello World!");
+ var authToken = localStorage.getItem("authToken")
+ var tale_wallet_address = localStorage.getItem("tale_wallet_address")
+ if(tale_wallet_address){
+ showWalletUI(tale_wallet_address)
+ } else {
+ loginUI();
+ }
+});
\ No newline at end of file
diff --git a/NFTVerse/contracts/CricNFT.cdc b/NFTVerse/contracts/CricNFT.cdc
new file mode 100644
index 00000000..b9bb8038
--- /dev/null
+++ b/NFTVerse/contracts/CricNFT.cdc
@@ -0,0 +1,345 @@
+import NonFungibleToken from 0x631e88ae7f1d7c20
+import MetadataViews from 0x631e88ae7f1d7c20
+
+pub contract CricNFT: NonFungibleToken {
+
+ /// Total supply of CricNFTs in existence
+ pub var totalSupply: UInt64
+
+ /// The event that is emitted when the contract is created
+ pub event ContractInitialized()
+
+ /// The event that is emitted when an NFT is withdrawn from a Collection
+ pub event Withdraw(id: UInt64, from: Address?)
+
+ /// The event that is emitted when an NFT is deposited to a Collection
+ pub event Deposit(id: UInt64, to: Address?)
+
+ /// Storage and Public Paths
+ pub let CollectionStoragePath: StoragePath
+ pub let CollectionPublicPath: PublicPath
+ pub let MinterStoragePath: StoragePath
+
+ /// The core resource that represents a Non Fungible Token.
+ /// New instances will be created using the NFTMinter resource
+ /// and stored in the Collection resource
+ ///
+ pub resource NFT: NonFungibleToken.INFT, MetadataViews.Resolver {
+
+ /// The unique ID that each NFT has
+ pub let id: UInt64
+
+ /// Metadata fields
+ pub let name: String
+ pub let description: String
+ pub let thumbnail: String
+ access(self) let royalties: [MetadataViews.Royalty]
+ access(self) let metadata: {String: AnyStruct}
+
+ init(
+ id: UInt64,
+ name: String,
+ description: String,
+ thumbnail: String,
+ royalties: [MetadataViews.Royalty],
+ metadata: {String: AnyStruct},
+ ) {
+ self.id = id
+ self.name = name
+ self.description = description
+ self.thumbnail = thumbnail
+ self.royalties = royalties
+ self.metadata = metadata
+ }
+
+ /// Function that returns all the Metadata Views implemented by a Non Fungible Token
+ ///
+ /// @return An array of Types defining the implemented views. This value will be used by
+ /// developers to know which parameter to pass to the resolveView() method.
+ ///
+ pub fun getViews(): [Type] {
+ return [
+ Type(),
+ Type(),
+ Type(),
+ Type(),
+ Type(),
+ Type(),
+ Type(),
+ Type()
+ ]
+ }
+
+ /// Function that resolves a metadata view for this token.
+ ///
+ /// @param view: The Type of the desired view.
+ /// @return A structure representing the requested view.
+ ///
+ pub fun resolveView(_ view: Type): AnyStruct? {
+ switch view {
+ case Type():
+ return MetadataViews.Display(
+ name: self.name,
+ description: self.description,
+ thumbnail: MetadataViews.HTTPFile(
+ url: self.thumbnail
+ )
+ )
+ case Type():
+ // There is no max number of NFTs that can be minted from this contract
+ // so the max edition field value is set to nil
+ let editionInfo = MetadataViews.Edition(name: "Cric NFT Edition", number: self.id, max: nil)
+ let editionList: [MetadataViews.Edition] = [editionInfo]
+ return MetadataViews.Editions(
+ editionList
+ )
+ case Type():
+ return MetadataViews.Serial(
+ self.id
+ )
+ case Type():
+ return MetadataViews.Royalties(
+ self.royalties
+ )
+ case Type():
+ return MetadataViews.ExternalURL("https://crictales.dev.onnftverse.com/".concat(self.id.toString()))
+ case Type():
+ return MetadataViews.NFTCollectionData(
+ storagePath: CricNFT.CollectionStoragePath,
+ publicPath: CricNFT.CollectionPublicPath,
+ providerPath: /private/cricNFTCollection,
+ publicCollection: Type<&CricNFT.Collection{CricNFT.CricNFTCollectionPublic}>(),
+ publicLinkedType: Type<&CricNFT.Collection{CricNFT.CricNFTCollectionPublic,NonFungibleToken.CollectionPublic,NonFungibleToken.Receiver,MetadataViews.ResolverCollection}>(),
+ providerLinkedType: Type<&CricNFT.Collection{CricNFT.CricNFTCollectionPublic,NonFungibleToken.CollectionPublic,NonFungibleToken.Provider,MetadataViews.ResolverCollection}>(),
+ createEmptyCollectionFunction: (fun (): @NonFungibleToken.Collection {
+ return <-CricNFT.createEmptyCollection()
+ })
+ )
+ case Type():
+ let media = MetadataViews.Media(
+ file: MetadataViews.HTTPFile(
+ url: "https://assets.website-files.com/5f6294c0c7a8cdd643b1c820/5f6294c0c7a8cda55cb1c936_Flow_Wordmark.svg"
+ ),
+ mediaType: "image/svg+xml"
+ )
+ return MetadataViews.NFTCollectionDisplay(
+ name: "The Cric Collection",
+ description: "NFT collection of cricket cards.",
+ externalURL: MetadataViews.ExternalURL("https://crictales.dev.onnftverse.com"),
+ squareImage: media,
+ bannerImage: media,
+ socials: {
+ "twitter": MetadataViews.ExternalURL("https://twitter.com/onnftverse")
+ }
+ )
+ case Type():
+ // exclude mintedTime and foo to show other uses of Traits
+ let excludedTraits = ["mintedTime", "foo"]
+ let traitsView = MetadataViews.dictToTraits(dict: self.metadata, excludedNames: excludedTraits)
+
+ // mintedTime is a unix timestamp, we should mark it with a displayType so platforms know how to show it.
+ let mintedTimeTrait = MetadataViews.Trait(name: "mintedTime", value: self.metadata["mintedTime"]!, displayType: "Date", rarity: nil)
+ traitsView.addTrait(mintedTimeTrait)
+
+ // foo is a trait with its own rarity
+ let fooTraitRarity = MetadataViews.Rarity(score: 10.0, max: 100.0, description: "Common")
+ let fooTrait = MetadataViews.Trait(name: "foo", value: self.metadata["foo"], displayType: nil, rarity: fooTraitRarity)
+ traitsView.addTrait(fooTrait)
+
+ return traitsView
+
+ }
+ return nil
+ }
+ }
+
+ /// Defines the methods that are particular to this NFT contract collection
+ ///
+ pub resource interface CricNFTCollectionPublic {
+ pub fun deposit(token: @NonFungibleToken.NFT)
+ pub fun getIDs(): [UInt64]
+ pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT
+ pub fun borrowCricNFT(id: UInt64): &CricNFT.NFT? {
+ post {
+ (result == nil) || (result?.id == id):
+ "Cannot borrow CricNFT reference: the ID of the returned reference is incorrect"
+ }
+ }
+ }
+
+ /// The resource that will be holding the NFTs inside any account.
+ /// In order to be able to manage NFTs any account will need to create
+ /// an empty collection first
+ ///
+ pub resource Collection: CricNFTCollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, MetadataViews.ResolverCollection {
+ // dictionary of NFT conforming tokens
+ // NFT is a resource type with an `UInt64` ID field
+ pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT}
+
+ init () {
+ self.ownedNFTs <- {}
+ }
+
+ /// Removes an NFT from the collection and moves it to the caller
+ ///
+ /// @param withdrawID: The ID of the NFT that wants to be withdrawn
+ /// @return The NFT resource that has been taken out of the collection
+ ///
+ pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT {
+ let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT")
+
+ emit Withdraw(id: token.id, from: self.owner?.address)
+
+ return <-token
+ }
+
+ /// Adds an NFT to the collections dictionary and adds the ID to the id array
+ ///
+ /// @param token: The NFT resource to be included in the collection
+ ///
+ pub fun deposit(token: @NonFungibleToken.NFT) {
+ let token <- token as! @CricNFT.NFT
+
+ let id: UInt64 = token.id
+
+ // add the new token to the dictionary which removes the old one
+ let oldToken <- self.ownedNFTs[id] <- token
+
+ emit Deposit(id: id, to: self.owner?.address)
+
+ destroy oldToken
+ }
+
+ /// Helper method for getting the collection IDs
+ ///
+ /// @return An array containing the IDs of the NFTs in the collection
+ ///
+ pub fun getIDs(): [UInt64] {
+ return self.ownedNFTs.keys
+ }
+
+ /// Gets a reference to an NFT in the collection so that
+ /// the caller can read its metadata and call its methods
+ ///
+ /// @param id: The ID of the wanted NFT
+ /// @return A reference to the wanted NFT resource
+ ///
+ pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT {
+ return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)!
+ }
+
+ /// Gets a reference to an NFT in the collection so that
+ /// the caller can read its metadata and call its methods
+ ///
+ /// @param id: The ID of the wanted NFT
+ /// @return A reference to the wanted NFT resource
+ ///
+ pub fun borrowCricNFT(id: UInt64): &CricNFT.NFT? {
+ if self.ownedNFTs[id] != nil {
+ // Create an authorized reference to allow downcasting
+ let ref = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
+ return ref as! &CricNFT.NFT
+ }
+
+ return nil
+ }
+
+ /// Gets a reference to the NFT only conforming to the `{MetadataViews.Resolver}`
+ /// interface so that the caller can retrieve the views that the NFT
+ /// is implementing and resolve them
+ ///
+ /// @param id: The ID of the wanted NFT
+ /// @return The resource reference conforming to the Resolver interface
+ ///
+ pub fun borrowViewResolver(id: UInt64): &AnyResource{MetadataViews.Resolver} {
+ let nft = (&self.ownedNFTs[id] as auth &NonFungibleToken.NFT?)!
+ let cricNFT = nft as! &CricNFT.NFT
+ return cricNFT as &AnyResource{MetadataViews.Resolver}
+ }
+
+ destroy() {
+ destroy self.ownedNFTs
+ }
+ }
+
+ /// Allows anyone to create a new empty collection
+ ///
+ /// @return The new Collection resource
+ ///
+ pub fun createEmptyCollection(): @NonFungibleToken.Collection {
+ return <- create Collection()
+ }
+
+ /// Resource that an admin or something similar would own to be
+ /// able to mint new NFTs
+ ///
+ pub resource NFTMinter {
+
+ /// Mints a new NFT with a new ID and deposit it in the
+ /// recipients collection using their collection reference
+ ///
+ /// @param recipient: A capability to the collection where the new NFT will be deposited
+ /// @param name: The name for the NFT metadata
+ /// @param description: The description for the NFT metadata
+ /// @param thumbnail: The thumbnail for the NFT metadata
+ /// @param royalties: An array of Royalty structs, see MetadataViews docs
+ ///
+ pub fun mintNFT(
+ recipient: &{NonFungibleToken.CollectionPublic},
+ name: String,
+ description: String,
+ thumbnail: String,
+ royalties: [MetadataViews.Royalty]
+ ) {
+ let metadata: {String: AnyStruct} = {}
+ let currentBlock = getCurrentBlock()
+ metadata["mintedBlock"] = currentBlock.height
+ metadata["mintedTime"] = currentBlock.timestamp
+ metadata["minter"] = recipient.owner!.address
+
+ // this piece of metadata will be used to show embedding rarity into a trait
+ metadata["foo"] = "bar"
+
+ // create a new NFT
+ var newNFT <- create NFT(
+ id: CricNFT.totalSupply,
+ name: name,
+ description: description,
+ thumbnail: thumbnail,
+ royalties: royalties,
+ metadata: metadata,
+ )
+
+ // deposit it in the recipient's account using their reference
+ recipient.deposit(token: <-newNFT)
+
+ CricNFT.totalSupply = CricNFT.totalSupply + UInt64(1)
+ }
+ }
+
+ init() {
+ // Initialize the total supply
+ self.totalSupply = 0
+
+ // Set the named paths
+ self.CollectionStoragePath = /storage/cricNFTCollection
+ self.CollectionPublicPath = /public/cricNFTCollection
+ self.MinterStoragePath = /storage/cricNFTMinter
+
+ // Create a Collection resource and save it to storage
+ let collection <- create Collection()
+ self.account.save(<-collection, to: self.CollectionStoragePath)
+
+ // create a public capability for the collection
+ self.account.link<&CricNFT.Collection{NonFungibleToken.CollectionPublic, CricNFT.CricNFTCollectionPublic, MetadataViews.ResolverCollection}>(
+ self.CollectionPublicPath,
+ target: self.CollectionStoragePath
+ )
+
+ // Create a Minter resource and save it to storage
+ let minter <- create NFTMinter()
+ self.account.save(<-minter, to: self.MinterStoragePath)
+
+ emit ContractInitialized()
+ }
+}
diff --git a/NFTVerse/contracts/CricToken.cdc b/NFTVerse/contracts/CricToken.cdc
new file mode 100644
index 00000000..3af0a60c
--- /dev/null
+++ b/NFTVerse/contracts/CricToken.cdc
@@ -0,0 +1,230 @@
+import FungibleToken from 0x9a0766d93b6608b7
+
+pub contract CricToken: FungibleToken {
+
+ /// Total supply of CricTokens in existence
+ pub var totalSupply: UFix64
+
+ /// Storage and Public Paths
+ pub let VaultStoragePath: StoragePath
+ pub let ReceiverPublicPath: PublicPath
+ pub let BalancePublicPath: PublicPath
+ pub let AdminStoragePath: StoragePath
+
+ /// TokensInitialized
+ ///
+ /// The event that is emitted when the contract is created
+ pub event TokensInitialized(initialSupply: UFix64)
+
+ /// TokensWithdrawn
+ ///
+ /// The event that is emitted when tokens are withdrawn from a Vault
+ pub event TokensWithdrawn(amount: UFix64, from: Address?)
+
+ /// TokensDeposited
+ ///
+ /// The event that is emitted when tokens are deposited to a Vault
+ pub event TokensDeposited(amount: UFix64, to: Address?)
+
+ /// TokensMinted
+ ///
+ /// The event that is emitted when new tokens are minted
+ pub event TokensMinted(amount: UFix64)
+
+ /// TokensBurned
+ ///
+ /// The event that is emitted when tokens are destroyed
+ pub event TokensBurned(amount: UFix64)
+
+ /// MinterCreated
+ ///
+ /// The event that is emitted when a new minter resource is created
+ pub event MinterCreated(allowedAmount: UFix64)
+
+ /// BurnerCreated
+ ///
+ /// The event that is emitted when a new burner resource is created
+ pub event BurnerCreated()
+
+ /// Vault
+ ///
+ /// Each user stores an instance of only the Vault in their storage
+ /// The functions in the Vault and governed by the pre and post conditions
+ /// in FungibleToken when they are called.
+ /// The checks happen at runtime whenever a function is called.
+ ///
+ /// Resources can only be created in the context of the contract that they
+ /// are defined in, so there is no way for a malicious user to create Vaults
+ /// out of thin air. A special Minter resource needs to be defined to mint
+ /// new tokens.
+ ///
+ pub resource Vault: FungibleToken.Provider, FungibleToken.Receiver, FungibleToken.Balance {
+
+ /// The total balance of this vault
+ pub var balance: UFix64
+
+ // initialize the balance at resource creation time
+ init(balance: UFix64) {
+ self.balance = balance
+ }
+
+ /// withdraw
+ ///
+ /// Function that takes an amount as an argument
+ /// and withdraws that amount from the Vault.
+ ///
+ /// It creates a new temporary Vault that is used to hold
+ /// the money that is being transferred. It returns the newly
+ /// created Vault to the context that called so it can be deposited
+ /// elsewhere.
+ ///
+ pub fun withdraw(amount: UFix64): @FungibleToken.Vault {
+ self.balance = self.balance - amount
+ emit TokensWithdrawn(amount: amount, from: self.owner?.address)
+ return <-create Vault(balance: amount)
+ }
+
+ /// deposit
+ ///
+ /// Function that takes a Vault object as an argument and adds
+ /// its balance to the balance of the owners Vault.
+ ///
+ /// It is allowed to destroy the sent Vault because the Vault
+ /// was a temporary holder of the tokens. The Vault's balance has
+ /// been consumed and therefore can be destroyed.
+ ///
+ pub fun deposit(from: @FungibleToken.Vault) {
+ let vault <- from as! @CricToken.Vault
+ self.balance = self.balance + vault.balance
+ emit TokensDeposited(amount: vault.balance, to: self.owner?.address)
+ vault.balance = 0.0
+ destroy vault
+ }
+
+ destroy() {
+ if self.balance > 0.0 {
+ CricToken.totalSupply = CricToken.totalSupply - self.balance
+ }
+ }
+ }
+
+ /// createEmptyVault
+ ///
+ /// Function that creates a new Vault with a balance of zero
+ /// and returns it to the calling context. A user must call this function
+ /// and store the returned Vault in their storage in order to allow their
+ /// account to be able to receive deposits of this token type.
+ ///
+ pub fun createEmptyVault(): @Vault {
+ return <-create Vault(balance: 0.0)
+ }
+
+ pub resource Administrator {
+
+ /// createNewMinter
+ ///
+ /// Function that creates and returns a new minter resource
+ ///
+ pub fun createNewMinter(allowedAmount: UFix64): @Minter {
+ emit MinterCreated(allowedAmount: allowedAmount)
+ return <-create Minter(allowedAmount: allowedAmount)
+ }
+
+ /// createNewBurner
+ ///
+ /// Function that creates and returns a new burner resource
+ ///
+ pub fun createNewBurner(): @Burner {
+ emit BurnerCreated()
+ return <-create Burner()
+ }
+ }
+
+ /// Minter
+ ///
+ /// Resource object that token admin accounts can hold to mint new tokens.
+ ///
+ pub resource Minter {
+
+ /// The amount of tokens that the minter is allowed to mint
+ pub var allowedAmount: UFix64
+
+ /// mintTokens
+ ///
+ /// Function that mints new tokens, adds them to the total supply,
+ /// and returns them to the calling context.
+ ///
+ pub fun mintTokens(amount: UFix64): @CricToken.Vault {
+ pre {
+ amount > 0.0: "Amount minted must be greater than zero"
+ amount <= self.allowedAmount: "Amount minted must be less than the allowed amount"
+ }
+ CricToken.totalSupply = CricToken.totalSupply + amount
+ self.allowedAmount = self.allowedAmount - amount
+ emit TokensMinted(amount: amount)
+ return <-create Vault(balance: amount)
+ }
+
+ init(allowedAmount: UFix64) {
+ self.allowedAmount = allowedAmount
+ }
+ }
+
+ /// Burner
+ ///
+ /// Resource object that token admin accounts can hold to burn tokens.
+ ///
+ pub resource Burner {
+
+ /// burnTokens
+ ///
+ /// Function that destroys a Vault instance, effectively burning the tokens.
+ ///
+ /// Note: the burned tokens are automatically subtracted from the
+ /// total supply in the Vault destructor.
+ ///
+ pub fun burnTokens(from: @FungibleToken.Vault) {
+ let vault <- from as! @CricToken.Vault
+ let amount = vault.balance
+ destroy vault
+ emit TokensBurned(amount: amount)
+ }
+ }
+
+ init() {
+ self.totalSupply = 1000.0
+
+ self.VaultStoragePath = /storage/cricTokenVault
+ self.ReceiverPublicPath = /public/cricTokenReceiver
+ self.BalancePublicPath = /public/cricTokenBalance
+ self.AdminStoragePath = /storage/cricTokenAdmin
+
+ // Create the Vault with the total supply of tokens and save it in storage
+ //
+ let vault <- create Vault(balance: self.totalSupply)
+ self.account.save(<-vault, to: self.VaultStoragePath)
+
+ // Create a public capability to the stored Vault that only exposes
+ // the `deposit` method through the `Receiver` interface
+ //
+ self.account.link<&{FungibleToken.Receiver}>(
+ self.ReceiverPublicPath,
+ target: self.VaultStoragePath
+ )
+
+ // Create a public capability to the stored Vault that only exposes
+ // the `balance` field through the `Balance` interface
+ //
+ self.account.link<&CricToken.Vault{FungibleToken.Balance}>(
+ self.BalancePublicPath,
+ target: self.VaultStoragePath
+ )
+
+ let admin <- create Administrator()
+ self.account.save(<-admin, to: self.AdminStoragePath)
+
+ // Emit an event that shows that the contract was initialized
+ //
+ emit TokensInitialized(initialSupply: self.totalSupply)
+ }
+}
\ No newline at end of file
diff --git a/NFTVerse/scripts/GetCricTokenBalance.cdc b/NFTVerse/scripts/GetCricTokenBalance.cdc
new file mode 100644
index 00000000..e514aff8
--- /dev/null
+++ b/NFTVerse/scripts/GetCricTokenBalance.cdc
@@ -0,0 +1,14 @@
+
+import FungibleToken from 0x9a0766d93b6608b7
+import CricToken from 0x2e0e1fc45f23609e
+
+// This script reads the balance field of an account's CricToken Balance
+
+pub fun main(): UFix64 {
+ let acct = getAccount(0x2fb7ab62360c973e)
+ let vaultRef = acct.getCapability(CricToken.BalancePublicPath)
+ .borrow<&CricToken.Vault{FungibleToken.Balance}>()
+ ?? panic("Could not borrow Balance reference to the Vault")
+
+ return vaultRef.balance
+}
\ No newline at end of file
diff --git a/NFTVerse/scripts/GetCricTokenSupply.cdc b/NFTVerse/scripts/GetCricTokenSupply.cdc
new file mode 100644
index 00000000..242ba1a8
--- /dev/null
+++ b/NFTVerse/scripts/GetCricTokenSupply.cdc
@@ -0,0 +1,13 @@
+// This script reads the total supply field
+// of the crictoken smart contract
+
+import CricToken from 0x2e0e1fc45f23609e
+
+pub fun main(): UFix64 {
+
+ let supply = NFTVerseToken.totalSupply
+
+ log(supply)
+
+ return supply
+}
\ No newline at end of file
diff --git a/NFTVerse/transactions/CreateAccount.cdc b/NFTVerse/transactions/CreateAccount.cdc
new file mode 100644
index 00000000..a4f78c74
--- /dev/null
+++ b/NFTVerse/transactions/CreateAccount.cdc
@@ -0,0 +1,6 @@
+transaction(publicKey: String) {
+ prepare(signer: AuthAccount) {
+
+ let account = AuthAccount(payer: signer)
+ }
+}
\ No newline at end of file
diff --git a/NFTVerse/transactions/MintCricToken.cdc b/NFTVerse/transactions/MintCricToken.cdc
new file mode 100644
index 00000000..853a9966
--- /dev/null
+++ b/NFTVerse/transactions/MintCricToken.cdc
@@ -0,0 +1,47 @@
+// This transaction is a template for a transaction to allow
+// anyone to add a Vault resource to their account so that
+// they can use the NFTVerseToken
+
+import FungibleToken from 0x9a0766d93b6608b7
+import CricToken from 0x2e0e1fc45f23609e
+
+transaction() {
+ /// Reference to the Example Token Admin Resource object
+ let tokenAdmin: &CricToken.Administrator
+
+ /// Reference to the Fungible Token Receiver of the recipient
+ let tokenReceiver: &{FungibleToken.Receiver}
+
+ /// The total supply of tokens before the burn
+ let supplyBefore: UFix64
+
+ prepare(signer: AuthAccount) {
+ self.supplyBefore = CricToken.totalSupply
+
+ // Borrow a reference to the admin object
+ self.tokenAdmin = signer.borrow<&CricToken.Administrator>(from: CricToken.AdminStoragePath)
+ ?? panic("Signer is not the token admin")
+
+ // Get the account of the recipient and borrow a reference to their receiver
+ self.tokenReceiver = getAccount(0x2e0e1fc45f23609e)
+ .getCapability(CricToken.ReceiverPublicPath)
+ .borrow<&{FungibleToken.Receiver}>()
+ ?? panic("Unable to borrow receiver reference")
+ }
+
+ execute {
+
+ // Create a minter and mint tokens
+ let minter <- self.tokenAdmin.createNewMinter(allowedAmount: 100000000.00)
+ let mintedVault <- minter.mintTokens(amount: 100000000.00)
+
+ // Deposit them to the receiever
+ self.tokenReceiver.deposit(from: <-mintedVault)
+
+ destroy minter
+ }
+
+ post {
+ CricToken.totalSupply == self.supplyBefore + 100000000.00: "The total supply must be increased by the amount"
+ }
+}
diff --git a/NFTVerse/transactions/SetupVaultForCricToken.cdc b/NFTVerse/transactions/SetupVaultForCricToken.cdc
new file mode 100644
index 00000000..dbc1ef7f
--- /dev/null
+++ b/NFTVerse/transactions/SetupVaultForCricToken.cdc
@@ -0,0 +1,41 @@
+// This transaction is a template for a transaction to allow
+// anyone to add a Vault resource to their account so that
+// they can use the CricToken
+
+import FungibleToken from 0x9a0766d93b6608b7
+import CricToken from 0x2e0e1fc45f23609e
+
+// This transaction is a template for a transaction to allow
+// anyone to add a Vault resource to their account so that
+// they can use the CricToken
+
+transaction {
+
+ prepare(signer: AuthAccount) {
+
+ // Return early if the account already stores a CricToken Vault
+ if signer.borrow<&CricToken.Vault>(from: CricToken.VaultStoragePath) != nil {
+ return
+ }
+
+ // Create a new CricToken Vault and put it in storage
+ signer.save(
+ <-CricToken.createEmptyVault(),
+ to: CricToken.VaultStoragePath
+ )
+
+ // Create a public capability to the Vault that only exposes
+ // the deposit function through the Receiver interface
+ signer.link<&CricToken.Vault{FungibleToken.Receiver}>(
+ CricToken.ReceiverPublicPath,
+ target: CricToken.VaultStoragePath
+ )
+
+ // Create a public capability to the Vault that only exposes
+ // the balance field through the Balance interface
+ signer.link<&CricToken.Vault{FungibleToken.Balance}>(
+ CricToken.BalancePublicPath,
+ target: CricToken.VaultStoragePath
+ )
+ }
+}
\ No newline at end of file
diff --git a/NFTVerse/transactions/TransferCricToken.cdc b/NFTVerse/transactions/TransferCricToken.cdc
new file mode 100644
index 00000000..2036e94e
--- /dev/null
+++ b/NFTVerse/transactions/TransferCricToken.cdc
@@ -0,0 +1,39 @@
+// This transaction is a template for a transaction that
+// could be used by anyone to send tokens to another account
+// that has been set up to receive tokens.
+//
+// The withdraw amount and the account from getAccount
+// would be the parameters to the transaction
+
+import FungibleToken from 0x9a0766d93b6608b7
+import CricToken from 0x2e0e1fc45f23609e
+
+transaction() {
+
+ // The Vault resource that holds the tokens that are being transferred
+ let sentVault: @FungibleToken.Vault
+
+ prepare(signer: AuthAccount) {
+
+ // Get a reference to the signer's stored vault
+ let vaultRef = signer.borrow<&CricToken.Vault>(from: CricToken.VaultStoragePath)
+ ?? panic("Could not borrow reference to the owner's Vault!")
+
+ // Withdraw tokens from the signer's stored vault
+ self.sentVault <- vaultRef.withdraw(amount: 1000.00)
+ }
+
+ execute {
+
+ // Get the recipient's public account object
+ let recipient = getAccount(0x6276f4cb9f8e0ff2)
+
+ // Get a reference to the recipient's Receiver
+ let receiverRef = recipient.getCapability(CricToken.ReceiverPublicPath)
+ .borrow<&{FungibleToken.Receiver}>()
+ ?? panic("Could not borrow receiver reference to the recipient's Vault")
+
+ // Deposit the withdrawn tokens in the recipient's receiver
+ receiverRef.deposit(from: <-self.sentVault)
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 04eafd41..26fc8058 100644
--- a/README.md
+++ b/README.md
@@ -6,9 +6,49 @@ Follow the following steps to submit your code base.
1. **Upload** your code base and videos to the repository.
1. Create a **pull request** to this repository. Make sure you raise your **pull request** as per your **team name**.
1. You can also add you team details in the README.md of your forked repository
-For Example:
+ For Example:
### Team Information
------------
-###### Team Name -
-###### Track -
+###### Team Name - NFTVerse
+###### Track - Web3 and blockchain
###### Brief Description and Snapshots -
+Problem statement: Creating digital twins of ICC merchandise and loyalty program by creating a decentralised Fan Token (CRICK Token) that can be mined by doing different activities across different ICC apps and events and creating a real/virtual world utility for those tokens.
+
+Solution: SDK for digital twins and loyalty program. Code is inside WalletPlugin folder. The wallet plugin can be integrated on any web 2.0 apps where users can create and manage their crypto assets (mainly for cricToken and crictales NFTs).
+Utility of Token and NFT: A card game where users can stake their cric tokens to play against other users and win rewards. Source code can be found inside Mobile App folder.
+APK for testing: https://drive.google.com/file/d/1eCxpjtmaMfYt4oZ-0w9AN1M7TA-9f1xb/view?usp=sharing
+
+Game Play!
+In crictales game the user needs to create the deck of 5,10,15 etc NFT cards of the cricket player whose stats they think can help them win this game. To Get these cards users need to purchase them through various sites like cricktose etc.
+
+
+
+How to play this game ?
+
+Step 1 - Visit our game app and login using your email address. Once you logged in you will come across this below mentioned screen.
+
+
+Step 2 - Once you come across this screen you can see all the ongoing contests and the card requirements. Click on the “play Now” button on any of the contests which you want to play.
+If you have required cards you can enter in the game and follow the steps & start playing if you don't have cards you need to go to the NFT cards marketplace to buy them and then can enter in the game.
+
+Step - 3 Once you meet the requirements of the game you will be redirected to this screen where you need to create a deck and participate in the game by clicking on ”create” button with those deck of Players NFT cards. You can also view the potential rewards over there.
+
+Step - 4 You need to click on the create deck option and you will be redirected to the screen mentioned below. From There you can select your favourite cards to create the custom deck for the game.
+
+
+Step - 5 Once you select all the required number of cards (say 5 ) then click on the “select 5 cards” button and you will be redirected to the below mentioned screen where you can customize the name of your deck and the display image of the deck
+
+Step - 6 Once you fill the deck info click on “create now” then the deck will be created,and you will be redirected to the initial screen where you can see the custom deck on the top of the screen (as shown in the image below). You just need to click & select the “theme1” deck i.e the custom deck & proceed ahead to play the game by clicking on “join the contest”.
+
+
+Step - 7 Once you Join the contest this below mentioned screen will appear where you need to select either “head” or tail. . A coin toss is then held to determine the winner, who gets the first chance to throw a card in the game. Which will look something like below mentioned screen and a pop-up message appears when you win/loose the toss.
+
+
+
+Step - 8 Once you win the toss you need to select the cards and then the particular stats of those cards & then throw similarly your opponent will also do and the stats will get compared and whose stats will be greater will win that round. Similarly the Next round will happen like this only.
+
+
+To play the game, You must select a card from their deck and choose the stat with which they want to throw the card. For example In the following image, the user has selected the "total matches played" stat and decides to throw the card. If the stat of the thrown card is greater than the opponent's, the user wins the round.
+
+
+So if your stats is greater then you will win and a congratulation message screen will appear shown above and then proceed ahead to play the next round in a similar way.