diff --git a/app/src/main/java/carbon/crypto/com/carbon/Application.java b/app/src/main/java/carbon/crypto/com/carbon/Application.java index 8fbba97..2b24444 100644 --- a/app/src/main/java/carbon/crypto/com/carbon/Application.java +++ b/app/src/main/java/carbon/crypto/com/carbon/Application.java @@ -1,689 +1,6 @@ package carbon.crypto.com.carbon; -import android.app.Activity; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.support.annotation.NonNull; -import android.support.multidex.MultiDex; -import android.util.Log; -import android.widget.Toast; +public class Application{ -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.net.URI; -import java.net.URISyntaxException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; -import java.util.concurrent.TimeUnit; - -import butterknife.ButterKnife; -import de.bitshares_munich.autobahn.WebSocketConnection; -import de.bitshares_munich.autobahn.WebSocketException; -import de.bitshares_munich.interfaces.AssetDelegate; -import de.bitshares_munich.interfaces.IAccount; -import de.bitshares_munich.interfaces.IAccountID; -import de.bitshares_munich.interfaces.IAccountObject; -import de.bitshares_munich.interfaces.IAssetObject; -import de.bitshares_munich.interfaces.IBalancesDelegate; -import de.bitshares_munich.interfaces.IExchangeRate; -import de.bitshares_munich.interfaces.IRelativeHistory; -import de.bitshares_munich.interfaces.ITransactionObject; -import de.bitshares_munich.smartcoinswallet.Constants; - -/** - * Created by qasim on 5/9/16. - */ -public class Application extends android.app.Application implements de.bitshares_munich.autobahn.WebSocket.WebSocketConnectionObserver, - android.app.Application.ActivityLifecycleCallbacks { - public static Context context; - public static String blockHead = ""; - public static int refBlockNum; - public static long refBlockPrefix; - public static long blockTime; - public static String urlsSocketConnection[] = - { - "wss://bitshares.openledger.info/ws", // Openledger node - "wss://eu.openledger.info/ws", // Openledger EU node - "ws://128.0.69.157:8090", // Henry node - "ws://128.0.69.157:8091", // Henry node - "wss://de.blockpay.ch/node" // German node - }; - public static String faucetUrl = "http://128.0.69.157:5000"; - public static String monitorAccountId; - public static int nodeIndex = 0; - public static Boolean isReady = false; - static IAccount iAccount; - static IExchangeRate iExchangeRate; - static IBalancesDelegate iBalancesDelegate_transactionActivity; - static IBalancesDelegate iBalancesDelegate_ereceiptActivity; - static IBalancesDelegate iBalancesDelegate_assetsActivity; - static AssetDelegate iAssetDelegate; - static IAccountID iAccountID; - static ITransactionObject iTransactionObject; - static IAccountObject iAccountObject; - static IAssetObject iAssetObject; - static IRelativeHistory iRelativeHistory; - static String connectedSocket; - private static String TAG = "Application"; - private static Activity currentActivity; - private static Handler warningHandler = new Handler(); - private static boolean mIsConnected = false; - private static WebSocketConnection mConnection; - private static URI mServerURI; - /** - * Constant used to specify how long will the app wait for another activity to go through its starting life - * cycle events before create the lock pin screen. - *
- * This is used as a means to detect whether or not the user has left the app.
- */
- private final int LOCK_DELAY = 10000;
- Handler connectionHandler = new Handler();
- /* Attribute used to indicate that funds must be updated (primarilly used at SendScreen and BalanceFragments */
- private boolean mUpdateFunds = false;
- /* Internal attribute used to keep track of the application state */
- private boolean mAppLock = true;
- /**
- * Handler instance used to schedule tasks back to the main thread
- */
- private Handler mHandler;
- /**
- * Runnable that will set to lock the app with the PIN.
- */
- private Runnable lockApp = new Runnable() {
- @Override
- public void run() {
- mAppLock = true;
- Log.i(TAG, "App Locked");
- }
- };
-
- public static Activity getCurrentActivity() {
- return Application.currentActivity;
- }
-
- public static void setCurrentActivity(Activity _activity) {
- Application.currentActivity = _activity;
- }
-
- public static void registerCallback(IAccount callbackClass) {
- iAccount = callbackClass;
- }
-
- public static void registerCallbackIAccountID(IAccountID callbackClass) {
- iAccountID = callbackClass;
- }
-
- public static void registerExchangeRateCallback(IExchangeRate callbackClass) {
- iExchangeRate = callbackClass;
- }
-
- public static void registerBalancesDelegateTransaction(IBalancesDelegate callbackClass) {
- iBalancesDelegate_transactionActivity = callbackClass;
- }
-
- public static void registerBalancesDelegateEReceipt(IBalancesDelegate callbackClass) {
- iBalancesDelegate_ereceiptActivity = callbackClass;
- }
-
- public static void registerBalancesDelegateAssets(IBalancesDelegate callbackClass) {
- iBalancesDelegate_assetsActivity = callbackClass;
- }
-
- public static void registerAssetDelegate(AssetDelegate callbackClass) {
- iAssetDelegate = callbackClass;
- }
-
- public static void registerTransactionObject(ITransactionObject callbackClass) {
- iTransactionObject = callbackClass;
- }
-
- public static void registerAccountObjectCallback(IAccountObject callbackClass) {
- iAccountObject = callbackClass;
- }
-
- public static void registerAssetObjectCallback(IAssetObject callbackClass) {
- iAssetObject = callbackClass;
- }
-
- public static void registerRelativeHistoryCallback(IRelativeHistory callbackClass) {
- iRelativeHistory = callbackClass;
- }
-
- private static void showWarningMessage(final String myEx) {
- if (getCurrentActivity() != null) {
- Log.d("exception websocket", "inside again");
- getCurrentActivity().runOnUiThread(new Runnable() {
- public void run() {
- Toast.makeText(context, "Your system does not supports new SSL ciphering. Error : " + myEx, Toast.LENGTH_LONG).show();
- }
- });
- }
- }
-
- public static void stringTextRecievedWs(String s) {
- try {
- JSONObject jsonObject = new JSONObject(s);
-
- if (jsonObject.has("id")) {
- int id = jsonObject.getInt("id");
- Log.d(TAG, "Got response. id: " + id);
- if (id == 1) {
- if (s.contains("true")) {
- Application.send(context.getString(R.string.database_indentifier));
- } else {
- Application.send(context.getString(R.string.login_api));
- }
- } else if (id == 2) {
- Helper.storeIntSharePref(context, context.getString(R.string.sharePref_database), jsonObject.getInt("result"));
- Application.send(context.getString(R.string.network_broadcast_identifier));
- } else if (id == 3) {
- Helper.storeIntSharePref(context, context.getString(R.string.sharePref_network_broadcast), jsonObject.getInt("result"));
- Application.send(context.getString(R.string.history_identifier));
- } else if (id == 4) {
- Helper.storeIntSharePref(context, context.getString(R.string.sharePref_history), jsonObject.getInt("result"));
- Application.send(context.getString(R.string.subscribe_callback));
- isReady = true;
- } else if (id == 6) {
- if (iAccount != null) {
- iAccount.checkAccount(jsonObject);
- }
- } else if (id == 100 || id == 200) {
- JSONArray jsonArray = (JSONArray) jsonObject.get("result");
- JSONObject obj = new JSONObject();
- if (jsonArray.length() != 0) {
- obj = (JSONObject) jsonArray.get(1);
- }
- iExchangeRate.callback_exchange_rate(obj, id);
- } else if (id == 8) {
- if (iBalancesDelegate_transactionActivity != null) {
- iBalancesDelegate_transactionActivity.OnUpdate(s, id);
- }
- } else if (id == 20) {
- if (iBalancesDelegate_transactionActivity != null) {
- iBalancesDelegate_transactionActivity.OnUpdate(s, id);
- }
- } else if (id == 21) {
- if (iBalancesDelegate_transactionActivity != null) {
- iBalancesDelegate_transactionActivity.OnUpdate(s, id);
- }
- } else if (id == 22) {
- if (iBalancesDelegate_transactionActivity != null) {
- iBalancesDelegate_transactionActivity.OnUpdate(s, id);
- }
- } else if (id == 23) {
- if (iBalancesDelegate_transactionActivity != null) {
- iBalancesDelegate_transactionActivity.OnUpdate(s, id);
- }
- } else if (id == 12) {
- if (iTransactionObject != null) {
- iTransactionObject.checkTransactionObject(jsonObject);
- }
- } else if (id == 13) {
- if (iAccountObject != null) {
- iAccountObject.accountObjectCallback(jsonObject);
- }
- } else if (id == 14) {
- if (iAssetObject != null) {
- iAssetObject.assetObjectCallback(jsonObject);
- }
- } else if (id == 9) {
- if (iBalancesDelegate_transactionActivity != null) {
- iBalancesDelegate_transactionActivity.OnUpdate(s, id);
- }
- } else if (id == 10) {
- if (iBalancesDelegate_transactionActivity != null) {
- iBalancesDelegate_transactionActivity.OnUpdate(s, id);
- }
- } else if (id == 11) {
- if (iBalancesDelegate_transactionActivity != null) {
- iBalancesDelegate_transactionActivity.OnUpdate(s, id);
- }
- } else if (id == 99) {
- if (iBalancesDelegate_assetsActivity != null) {
- iBalancesDelegate_assetsActivity.OnUpdate(s, id);
- }
- } else if (id == 999) {
- if (iBalancesDelegate_assetsActivity != null) {
- iBalancesDelegate_assetsActivity.OnUpdate(s, id);
- }
- } else if (id == 15) {
- if (iAssetDelegate != null) {
- iAssetDelegate.getLifetime(s, id);
- }
- } else if (id == 151) {
- if (iAccountID != null) {
- iAccountID.accountId(s);
- }
- } else if (id == 160 || id == 161) {
- if (iRelativeHistory != null) {
- iRelativeHistory.relativeHistoryCallback(jsonObject);
- }
- } else if (id == 17) {
- } else if (id == 18) {
- if (iBalancesDelegate_ereceiptActivity != null) {
- iBalancesDelegate_ereceiptActivity.OnUpdate(s, id);
- }
- } else if (id == 19) {
- if (iBalancesDelegate_ereceiptActivity != null) {
- iBalancesDelegate_ereceiptActivity.OnUpdate(s, id);
- }
- }
- } else if (jsonObject.has("method")) {
- if (jsonObject.getString("method").equals("notice")) {
- if (jsonObject.has("params")) {
- int id = jsonObject.getJSONArray("params").getInt(0);
- JSONArray values = jsonObject.getJSONArray("params").getJSONArray(1);
-
- if (id == 7) {
- headBlockNumber(values.toString());
-
- if (monitorAccountId != null && !monitorAccountId.isEmpty() && values.toString().contains(monitorAccountId)) {
- if (iAssetDelegate != null) {
- iAssetDelegate.loadAll();
- }
- Log.d("Notice Update", values.toString());
- }
- } else {
- Log.d("other notice", values.toString());
- }
-
- }
- }
- }
-
-
- } catch (JSONException e) {
-
- }
- }
-
- private static void sendInitialSocket(final Context context) {
-
- if (Application.mIsConnected) {
- Application.send(context.getString(R.string.login_api));
- }
- }
-
- private static String headBlockNumber(String json) {
- final String BLOCK_REFERENCE_ID = "head_block_id";
- final String HEAD_BLOCK_NUMBER = "head_block_number";
- final String TIME = "time";
- try {
- JSONArray array = new JSONArray(json);
- String rawBlockId = "";
- String blockNumber = "";
- if (array.length() == 1) {
- JSONArray subArray = array.getJSONArray(0);
- for (int i = 0; i < subArray.length(); i++) {
- if (subArray.get(i) instanceof JSONObject) {
- JSONObject element = (JSONObject) subArray.get(i);
- if (element.has(BLOCK_REFERENCE_ID)) {
- rawBlockId = element.getString(BLOCK_REFERENCE_ID);
- }
- if (element.has(HEAD_BLOCK_NUMBER)) {
- blockNumber = element.getString(HEAD_BLOCK_NUMBER);
- }
- if (element.has(TIME)) {
- SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
- try {
- Date date = simpleDateFormat.parse(element.getString(TIME));
- blockTime = date.getTime() / 1000;
- } catch (ParseException e) {
- Log.e(TAG, "ParseException while trying to parse time. time string: " + element.getString(TIME));
- }
- }
- } else {
- String element = (String) subArray.get(i);
- Log.d(TAG, "Could not cast string: " + element);
- }
- }
- if (rawBlockId.equals("")) {
- return blockHead;
- }
- // Setting block number
- blockHead = "block# " + blockNumber;
-
- // Setting reference block number (lower 16 bits of block number)
- refBlockNum = Integer.valueOf(blockNumber) & 0xffff;
-
- // Setting block prefix
- String hashData = rawBlockId.substring(8, 16);
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < 8; i = i + 2) {
- builder.append(hashData.substring(6 - i, 8 - i));
- }
- refBlockPrefix = Long.parseLong(builder.toString(), 16);
- }
- } catch (JSONException e) {
- Log.e(TAG, "JSONException at headBlockNumber");
- }
- return blockHead;
- }
-
-
- //WebSocketConnection
-
- public static void send(String message) {
- if (mIsConnected) {
- mConnection.sendTextMessage(message);
- }
- }
-
- public static void disconnect() {
- Log.i("internetBlockpay", "Disconnect");
- if (mConnection != null) {
- mConnection.disconnect();
- }
- }
-
- @NonNull
- public static Boolean isConnected() {
- return mConnection != null && (mConnection.isConnected());
- }
-
- public static void timeStamp() {
-
- Helper.storeBoolianSharePref(context, "account_can_create", false);
- setTimeStamp();
-
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
-
- Helper.storeBoolianSharePref(context, "account_can_create", true);
-
- }
- }, 10 * 60000);
- }
-
- @NonNull
- public static Boolean accountCanCreate() {
- return Helper.fetchBoolianSharePref(context, "account_can_create");
- }
-
- static void setTimeStamp() {
- Calendar c = Calendar.getInstance();
- long time = c.getTimeInMillis();
- Helper.storeLongSharePref(context, "account_create_timestamp", time);
- }
-
- static void getTimeStamp() {
- try {
- Calendar c = Calendar.getInstance();
- long currentTime = c.getTimeInMillis();
- ;
- long oldTime = Helper.fetchLongSharePref(context, "account_create_timestamp");
- long diff = currentTime - oldTime;
- if (diff < TimeUnit.MINUTES.toMillis(10)) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- Helper.storeBoolianSharePref(context, "account_can_create", true);
- }
- }, TimeUnit.MINUTES.toMillis(10) - diff);
- } else {
- Helper.storeBoolianSharePref(context, "account_can_create", true);
- }
- } catch (Exception e) {
- Helper.storeBoolianSharePref(context, "account_can_create", true);
- }
- }
-
- /*
- * Return the state of the application(If locked or not).
- */
- public Boolean getLock() {
- return mAppLock;
- }
-
- /*
- * Set the state of the application(If locked or not).
- */
- public void setLock(Boolean value) {
- mAppLock = value;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- MultiDex.install(this);
- ButterKnife.setDebug(true);
- context = getApplicationContext();
- blockHead = "";
-
- mHandler = new Handler();
- /*
- * Registering this class as a listener to all activitie's callback cycle events, in order to
- * better estimate when the user has left the app and it is safe to lock the app or not
- */
- registerActivityLifecycleCallbacks(this);
-
-
- //SETUP LOCALE AND DEFAULT PREFERENCES
-
- //Setup Country
- String country = Helper.fetchStringSharePref(getApplicationContext(), getString(R.string.pref_country), "");
- //If not at preferences yet it will setup device country or constant default
- //(It is expected that this "if" will be executed only one time, at first start up)
- if (country.equals("")) {
- Log.w(TAG, "Could not resolve country information, trying with the telephony manager");
- //If the locale mechanism fails to give us a country, we try
- //to get it from the TelephonyManager.
- country = Helper.getDeviceCountry(getApplicationContext());
- //If device don't respond with any country set it to the default (app constant)
- if (country == null || country.equals("")) {
- Log.w(TAG, "Could not resolve country information again, falling back to the default");
- country = Constants.DEFAULT_COUNTRY_CODE;
- }
- }
- Helper.setCountry(getApplicationContext(), country);
-
- //Setup Language
- String language = Helper.fetchStringSharePref(getApplicationContext(), getString(R.string.pref_language));
- //If app language preferences aren't set, set default as device/os language (telephony language)
- //(It is expected that this "if" will be executed only one time, at first start up)
- if (language.equals("")) {
- language = Locale.getDefault().getLanguage();
- //Just checking if we still don't have a language setup in the locale, in which
- //case we fallback to english as the default (the app constant .
- if (language.equals("")) {
- Log.w(TAG, "Could not resolve language information, falling back to english");
- language = Constants.DEFAULT_LANGUAGE_CODE;
- }
- }
- Helper.setLanguage(getApplicationContext(), language);
-
-
- //Check automatically close app behavior (after 3 min) is set and if not, put true by default
- Boolean closeAppPref = Helper.checkSharedPref(getApplicationContext(), "close_bitshare");
- if (!closeAppPref) {
- Helper.storeBoolianSharePref(getApplicationContext(), "close_bitshare", true);
- }
-
-
- init();
- accountCreateInit();
- }
-
- public void init() {
- new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
- @Override
- public void run() {
- if (mConnection == null) {
- mConnection = new WebSocketConnection();
- checkConnection();
- }
- }
- }, 1000);
-
- }
-
- private void webSocketConnection() {
- isReady = false;
- new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
- @Override
- public void run() {
- nodeIndex = nodeIndex % urlsSocketConnection.length;
-
- Log.i(TAG, "preparing to connect to:" + urlsSocketConnection[nodeIndex]);
-
- connect(urlsSocketConnection[nodeIndex]);
- nodeIndex++;
-
- }
- }, 500);
-
- }
-
- @Override
- public void onOpen() {
- Log.i("internetBlockpay", "open internet");
- mIsConnected = true;
-// Toast.makeText(context, getResources().getString(R.string.connected_to)+ ": "+connectedSocket,Toast.LENGTH_SHORT).show();
- sendInitialSocket(context);
- }
-
- public void checkConnection() {
- connectionHandler.removeCallbacksAndMessages(null);
- connectionHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
-
- if (checkInternetConnection()) {
- {
- webSocketConnection();
- }
- } else {
- connectionHandler.postDelayed(this, 500);
- }
-
- }
- }, 500);
- }
-
- @Override
- public void onClose(WebSocketCloseNotification code, String reason) {
- Log.i("internetBlockpay", "close internet");
- mIsConnected = false;
- checkConnection();
- }
-
- @Override
- public void onTextMessage(String payload) {
- stringTextRecievedWs(payload);
- }
-
- @Override
- public void onRawTextMessage(byte[] payload) {
- }
-
- @Override
- public void onBinaryMessage(byte[] payload) {
- }
-
- private void connect(String node) {
- Log.i("internetBlockpay", "connecting to internet");
- Log.i("Connect", "connect(String node) called");
- try {
- if (!mIsConnected) {
- Log.i("Connect", "Inside when not mIsConnected");
- mServerURI = new URI(node);
- connectedSocket = node;
- mConnection.connect(mServerURI, this);
- }
- } catch (URISyntaxException e) {
- String message = e.getLocalizedMessage();
- Log.i("Connect", "Inside catch block when not mIsConnected, got exception, msg is:" + message);
- checkConnection();
- } catch (WebSocketException e) {
- String message = e.getLocalizedMessage();
- Log.i("Connect", "Inside catch block when not mIsConnected, got exception, msg is:" + message);
- if (!mIsConnected) {
- checkConnection();
- }
- }
- }
-
- Boolean checkInternetConnection() {
- ConnectivityManager cm =
- (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-
- NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
- return activeNetwork != null &&
- activeNetwork.isConnectedOrConnecting();
- }
-
- void accountCreateInit() {
- if (Helper.containKeySharePref(context, "account_can_create")) {
- if (!accountCanCreate()) {
- getTimeStamp();
- }
- } else {
- Helper.storeBoolianSharePref(context, "account_can_create", true);
- }
- }
-
- /*
- * Get attribute used to indicate if UI should update the funds or not after an update (Send funds primarily)
- *
- * @return The boolean value of update UI state
- */
- public boolean getUpdateFunds() {
- return this.mUpdateFunds;
- }
-
- /*
- * Set attribute used to indicate if UI should update the funds or not after an update (Send funds primarily)
- *
- * @param update The boolean value of update UI state
- */
- public void setUpdateFunds(boolean update) {
- this.mUpdateFunds = update;
- }
-
- @Override
- public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
- mHandler.removeCallbacks(this.lockApp);
- }
-
- @Override
- public void onActivityStarted(Activity activity) {
- mHandler.removeCallbacks(this.lockApp);
- }
-
- @Override
- public void onActivityResumed(Activity activity) {
- mHandler.removeCallbacks(this.lockApp);
- Application.setCurrentActivity(activity);
- }
-
- @Override
- public void onActivityPaused(Activity activity) {
- //Call the handler only if app is not already locked
- if (!mAppLock) {
- mHandler.postDelayed(this.lockApp, LOCK_DELAY);
- }
- }
-
- @Override
- public void onActivityStopped(Activity activity) {
- }
-
- @Override
- public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
- }
-
- @Override
- public void onActivityDestroyed(Activity activity) {
- }
}
diff --git a/app/src/main/res/anim/animation.xml b/app/src/main/res/anim/animation.xml
new file mode 100644
index 0000000..1ca457a
--- /dev/null
+++ b/app/src/main/res/anim/animation.xml
@@ -0,0 +1,8 @@
+
+ Smartcoins Wallet Terms and Conditions of Use The following terminology applies to these Terms and Conditions of Use (our “Terms”), the Privacy and Transparency Statement, and any and all other agreements between you and us: “Client”, “Customer”, “User”, “You” and “Your” refers to you, the person accessing the Smartcoins Wallet software application (“App”) and accepting our Terms. “The Company”, “BitShares”, “BitShares Munich”, “Our”, “Ourselves”, “We” and “Us” collectively refers to the App and to its owners, operators, developers, contractors, directors, officers, employees, agents, insurers, suppliers, and attorneys. “Party” refers to either you or Us. In these Terms, unless otherwise specified, words importing the singular include the plural and vice versa and words importing gender include all genders. “Digital asset”, “asset”, “coin”, “cryptocurrency”, “good”, “ledger entry”, “altcoin” and “token” refer to blockchain-based software ledger data entries. By using the App, you represent and warrant that you are: We reserve the right to terminate your access to the App for any reason, including but not limited to breaches of our Terms, in our sole and absolute discretion. Use of the App is void where prohibited by applicable law. 1. Terms By accessing the App, you agree to be bound by our Terms, all applicable laws and regulations, and you agree that you are responsible for compliance with, and that you are compliant with applicable law. If you do not agree with any of our Terms, you are prohibited from using or accessing the App; your only recourse is to stop using the App. Any use of the App is your deemed acceptance of our Terms as they may be modified and amended from time to time. The materials contained in the App are protected by applicable copyright and trademark laws and treaties. You should check back often in case our Terms undergo changes. By accepting our Terms, you expressly allow Us to export data outside of the jurisdiction in which you reside or are located when you access the App. 2. Limitations Use of the App may carry financial risk, and is to be used as an experimental software utility only. In no event shall We be liable or responsible for any damages, claims, applications, losses, injuries, delays, accidents, costs, business interruption costs, or other expenses (including, without limitation, attorneys’ fees or the costs of any claim or suit), nor for any incidental, direct, indirect, general, special, punitive, exemplary, or consequential damages, loss of goodwill or business profits, loss of cryptocurrency or digital assets, work stoppage, data loss, computer or device failure or malfunction, or any other commercial or other losses directly or indirectly arising out of or related to: our Terms; the Privacy and Transparency Statement; any service We provide; the use of the App; any use of your digital assets or cryptocurrency with the App by any other party not authorized by you (collectively, all of the foregoing items shall be referred to herein as “Losses”). We are hereby released by you from liability for any and all Losses. We disclaim any and all warranties or guarantees, including any warranty of merchantability and warranty of fitness for any particular purpose. The foregoing limitations of liability shall apply whether the alleged liability or Losses are based on contract, negligence, tort, strict liability, or any other basis, even if We have been advised of or should have known of the possibility of such losses and damages, and without regard to the success or effectiveness of other remedies. Notwithstanding anything else in our Terms, in no event shall the combined aggregate liability for any Loss hereunder exceed 50.00€. 3. Prices, Exchange Rates, and Confirmations Cryptocurrency and digital assets are highly experimental and risky. Our App attempts to provide accurate price and exchange rate information, but this information is highly volatile and can change quickly without users necessarily being aware of these changes. For normal orders (i.e., not “Specific Amount” orders), the exchange rate you receive is calculated at the time your payment is accepted. Due to blockchain specifications, your payment is typically considered “accepted” at one block confirmation. We may occasionally accept a payment with zero confirmations, though this decision is at Our sole discretion. It is important to note that a payment being broadcast to the blockchain network does not constitute an acceptance by Us of that payment. Users who are sensitive to the exchange rate they receive should use Our “Amount” feature, which guarantees an exchange rate for a specified period of time. The User’s payment must be received by Us within that period in order to receive the guaranteed exchange rate. Please contact Us for more information on exchange rates. 4. Returns and Refund Policy Cryptocurrencies, tokens, and digital assets are, by their nature, generally irreversible, and their exchange rates are highly volatile and transitory. Once the User’s asset has been transmitted to the User’s address, no refund is possible, even if the wrong address was provided to the App. All sales after transmission are final. 5. Governing Law These Terms are governed by the laws of Munich, Germany, and any and all laws applicable therein. 6. Prohibited Jurisdictions It is prohibited to use or access cryptocurrencies and/or Digital assets from certain jurisdictions. Transactions from Users in these jurisdictions are prohibited. By accessing the App or any services therein, you represent and warrant that you are not physically located in a prohibited jurisdiction. 7. Permissible Use The App and all its services may be used only as a mechanism of software ledger entry translation between the User and the BitShares blockchain. You are prohibited from using the App for the purpose of translating ledger entries with other parties, with the exception of explicit payment for goods and services. 8. Terms of Use Modifications We may revise our Terms at any time and without notice to you or third parties. By using the App, you agree to be bound by the then-current version of our Terms. We reserve the right to make any changes retroactive. 9. Costs From time to time, We may need to spend time dealing with issues brought to Us by customers. Where any customer issue is not caused by our negligence or oversight, We reserve the right to recover reasonable administrative costs spent addressing the customer issue. Privacy and Transparency Statement We respect the privacy of Users of Our App by not requesting any information that is unnecessary for the use of the service or to comport with our obligations under applicable law. We also do not in any way obscure the information that it does request or obtain. Due to the inherent transparency of blockchains, transactions to and from the App are public and easily correlated. Utilizing the App to obscure transactions or assets in any way is futile. Law enforcement has full access to blockchain information that goes in or out of the BitShares network. You accept that We will comply willingly with all legal requests for information from it. We reserve the right to provide information to law enforcement personnel and other third parties to answer inquiries; to respond to legal process; to respond to the order of a court of competent jurisdiction and those exercising the court’s authority; and, to protect Ourselves and our users.
+ Copyright 2017 BitShares Munich IVS Registered in Kingdom of Denmark Company registration no.: CVR-NR 37 62 63 76 attn: Vintervej 119, 1.1., Hasle, 8210 Aarhus V. , Denmark. If you agree to these terms and conditions, please tap on the green button below.