commit d59bf30ef00ff0bdc21aa6e2cef944b4ae32a00f Author: Yaser Date: Thu Aug 13 19:42:08 2026 +0330 Initial commit diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f929732 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +Dockerfile +.dockerignore +.git +.gitignore +LICENSE +README diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..b439449 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,31 @@ +kind: pipeline +name: default + +steps: +- name: Run rspec + image: ruby:2.6.5 + commands: + - gem install bundler + - bundle + - bundle exec rspec + when: + event: + - pull_request +- name: Bump and tag + image: quay.io/openware/sdk-tools:0.0.3 + environment: + BRANCH_NAME: ${DRONE_BRANCH} + REPO_NAME: ${DRONE_REPO} + BOT_USERNAME: kite-bot + BOT_NAME: Kite Bot + BOT_EMAIL: kite-bot@heliostech.fr + GITHUB_API_KEY: + from_secret: kite_bot_key + commands: + - BUNDLE_GEMFILE=/sdk/Gemfile bundle exec rake --rakefile=/sdk/Rakefile release:push + when: + event: [push] + branch: [master] + +image_pull_secrets: + - dockerconfigjson diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..9ae09d9 --- /dev/null +++ b/.env.example @@ -0,0 +1,9 @@ +# Generated by `rake render:config` — do not edit manually. +# Copy from .env.example on first setup, then run render:config. +COMPOSE_PROJECT_NAME=fibitex +# Linux/macOS: use colon. Windows: use semicolon (see Docs/06-setup-local.md). +COMPOSE_FILE=compose/app.yaml:compose/backend.yaml:compose/gateway.yaml:compose/proxy.yaml:compose/daemons.yaml:compose/frontend.yaml:compose/cryptonodes.yaml:compose/arke.yaml:compose/superset.yaml:compose/monitoring.yaml +PEATIO_RAILS_VAULT_TOKEN=changeme +PEATIO_CRYPTO_VAULT_TOKEN=changeme +PEATIO_UPSTREAM_VAULT_TOKEN=changeme +PEATIO_MATCHING_VAULT_TOKEN=changeme diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1cb61ef --- /dev/null +++ b/.gitignore @@ -0,0 +1,28 @@ +config/acme.json +config/frontend/*.js +config/gateway/mapping.yaml +config/peatio/management_api_v1.yml +config/barong/management_api.yml +config/finex/* +config/toolbox.yaml +config/traefik.toml +config/*.env +config/secrets/* +!config/secrets/.gitkeep +config/peatio/seed/* +!config/peatio/seed/.gitkeep +!config/peatio/seed/markets.yml +!config/peatio/seed/currencies.yml +config/applogic/* +!config/applogic/.gitkeep +config/app.local.yml +config/app.staging.yml +config/app.production.yml +config/vault-secrets.yml +.env +vendor/ +!vendor/.gitkeep +.terraform/ +*.tfvars +terraform.tfstate* +!data/parity/.gitkeep diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..5e83cda --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# CodeStream ignored files +/codestream.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/alvandp.iml b/.idea/alvandp.iml new file mode 100644 index 0000000..941cab5 --- /dev/null +++ b/.idea/alvandp.iml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..20d1ffc --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..b252d9a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..c99d2e7 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..f6ab44e --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +ruby-2.6.6 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9e8ef07 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM ruby:2.6.1 + +ENV APP_HOME=/home/app + +ARG UID=1000 +ARG GID=1000 + +RUN groupadd -r --gid ${GID} app \ + && useradd --system --create-home --home ${APP_HOME} --shell /sbin/nologin --no-log-init \ + --gid ${GID} --uid ${UID} app + +USER app +WORKDIR $APP_HOME + +COPY --chown=app:app . . + +RUN bundle install --jobs=$(nproc) --deployment diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..052ea72 --- /dev/null +++ b/Gemfile @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } + +ruby '~>2.6' + +gem 'rake' +gem 'sshkey' # SSH key generation gem + +# webhook server deps +gem 'bump' +gem 'rack' +gem 'sinatra' +gem 'puma' +gem 'rspec' +gem 'jwt' +gem 'faraday' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..885c5da --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,59 @@ +GEM + remote: https://rubygems.org/ + specs: + bump (0.9.0) + diff-lcs (1.3) + faraday (1.0.0) + multipart-post (>= 1.2, < 3) + jwt (2.2.1) + multipart-post (2.1.1) + mustermann (1.1.1) + ruby2_keywords (~> 0.0.1) + nio4r (2.5.2) + puma (4.3.3) + nio4r (~> 2.0) + rack (2.2.2) + rack-protection (2.0.8.1) + rack + rake (13.0.1) + rspec (3.9.0) + rspec-core (~> 3.9.0) + rspec-expectations (~> 3.9.0) + rspec-mocks (~> 3.9.0) + rspec-core (3.9.1) + rspec-support (~> 3.9.1) + rspec-expectations (3.9.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.9.0) + rspec-mocks (3.9.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.9.0) + rspec-support (3.9.2) + ruby2_keywords (0.0.2) + sinatra (2.0.8.1) + mustermann (~> 1.0) + rack (~> 2.0) + rack-protection (= 2.0.8.1) + tilt (~> 2.0) + sshkey (2.0.0) + tilt (2.0.10) + +PLATFORMS + ruby + +DEPENDENCIES + bump + faraday + jwt + puma + rack + rake + rspec + sinatra + sshkey + +RUBY VERSION + ruby 2.6.3p62 + +BUNDLED WITH + 2.1.4 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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 + + http://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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3a5f22f --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +
+ +# Alvand-P — ارکستراسیون Fibitex + +**Alvand-P** فورک [OpenDAX](https://github.com/openware/opendax) برای صرافی **Fibitex** است: compose، Vault، Traefik، و render قالب‌ها. + +| OpenDAX | Fibitex | +|---------|---------| +| OpenDAX | Alvand-P | +| Peatio | [Dena](../Dena/) | +| Barong | [Dalan](../Dalan/) | +| BaseApp | [Gereh](../Gereh/) / [Shahoo](../Shahoo/) | + +## پیش‌نیازها + +- Docker Compose v2، Ruby 2.6 + Bundler +- Linux/macOS (staging: Ubuntu) یا Windows + Docker Desktop +- Vault unseal keys (staging/production) + +## راه‌اندازی سریع + +
+ +```bash +cd Alvand-P +bundle install +cp config/app.local.yml.example config/app.local.yml # لوکال +rake render:config +rake service:all +``` + +
+ +لوکال Windows: [`start-fibitex.bat`](../start-fibitex.bat) از ریشه Main code. + +Staging: [`Docs/Fibitex-staging-deploy.md`](../Docs/Fibitex-staging-deploy.md) + +## مستندات + +| سند | موضوع | +|-----|--------| +| [`Docs/Fibitex-staging-deploy.md`](../Docs/Fibitex-staging-deploy.md) | Deploy staging (منبع حقیقت) | +| [`Docs/06-setup-local.md`](../Docs/06-setup-local.md) | لوکال Docker | +| [`Docs/07-setup-server.md`](../Docs/07-setup-server.md) | Production | +| [`Docs/05-alvand-p-platform.md`](../Docs/05-alvand-p-platform.md) | معماری Alvand-P | +| [`Docs/QA-troubleshooting.md`](Docs/QA-troubleshooting.md) | عیب‌یابی عملیاتی | +| [`Docs/troubleshoot-barong-authz.md`](Docs/troubleshoot-barong-authz.md) | Barong authz | +| [`Docs/ubuntu-install.md`](Docs/ubuntu-install.md) | نصب Ubuntu | +| [`Docs/README.md`](../Docs/README.md) | فهرست مرکزی | + +## دستورات پرکاربرد + +
+ +```bash +rake render:config +rake service:all +docker compose -p fibitex up -d --force-recreate # بعد از تغییر logging +rake vault:load_policies + +rake service:monitoring # all monitoring service up +``` + +
+ +## Log rotation + +Templateهای compose tierهای `noisy` (10m×3) و `quiet` (5m×2) دارند. بعد از تغییر: `render:config` + `--force-recreate`. جزئیات: Fibitex staging deploy §۸.۳. + +--- + +
+ +
+OpenDAX upstream README (مرجع) + +![Cryptocurrency Exchange Platform - OpenDAX](https://github.com/openware/meta/raw/main/images/github_opendax.png) + +OpenDAX is an open-source cloud-native multi-service platform for building a Blockchain/FinTech exchange. + +See upstream: https://github.com/openware/opendax + +
diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..c534ba5 --- /dev/null +++ b/Rakefile @@ -0,0 +1,15 @@ +require 'yaml' +require 'base64' +require 'erb' +require_relative 'lib/opendax/config_loader' + +CONFIG_PATH = 'config/app.yml'.freeze +UTILS_PATH = 'config/utils.yml'.freeze + +@config = Opendax::ConfigLoader.load +@utils = YAML.load_file(UTILS_PATH) + +# Add your own tasks in files placed in lib/tasks ending in .rake +Dir.glob('lib/tasks/*.rake').each do |task| + load task +end diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..920c3bd --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.57 diff --git a/bin/check_member_balance.rb b/bin/check_member_balance.rb new file mode 100644 index 0000000..a591e0b --- /dev/null +++ b/bin/check_member_balance.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +email = ENV.fetch('EMAIL', 'admin@barong.io') + +member = Member.find_by(email: email) +unless member + puts 'STATUS=NO_MEMBER' + exit 1 +end + +puts "STATUS=OK uid=#{member.uid} id=#{member.id}" + +%w[usdt btc cad].each do |currency| + account = member.accounts.find_by(currency_id: currency) + next unless account + + puts "ACCOUNT #{currency} balance=#{account.balance} locked=#{account.locked}" +end diff --git a/bin/check_order.rb b/bin/check_order.rb new file mode 100644 index 0000000..858872c --- /dev/null +++ b/bin/check_order.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +order = Order.find(ENV.fetch('ORDER_ID', '1')) +puts "ORDER id=#{order.id} state=#{order.state} price=#{order.price} volume=#{order.volume} origin_volume=#{order.origin_volume}" diff --git a/bin/check_test_balances.rb b/bin/check_test_balances.rb new file mode 100644 index 0000000..0ef5102 --- /dev/null +++ b/bin/check_test_balances.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +puts '--- currencies ---' +%w[irt cad usdt].each do |cid| + c = Currency.find_by(id: cid) + puts "#{cid} visible=#{c&.visible} type=#{c&.type}" if c +end + +%w[user@test.com bot@test.com admin@test.com].each do |email| + member = Member.find_by(email: email) + unless member + puts "MISSING #{email}" + next + end + + sample = member.accounts.where('balance > 0').limit(3).map { |a| "#{a.currency_id}=#{a.balance}" }.join(', ') + fiat = %w[irt cad].map { |c| a = member.accounts.find_by(currency_id: c); "#{c}=#{a&.balance || 0}" }.join(' ') + total = member.accounts.where('balance > 0').count + puts "#{email} uid=#{member.uid} nonzero=#{total} fiat=[#{fiat}] sample=#{sample}" +end diff --git a/bin/create_admin_user.rb b/bin/create_admin_user.rb new file mode 100644 index 0000000..5e9e91d --- /dev/null +++ b/bin/create_admin_user.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +email = ENV.fetch('ADMIN_EMAIL', 'admin@test.com') +password = ENV.fetch('ADMIN_PASSWORD', '123qwe!@#QWE') + +user = User.find_or_initialize_by(email: email) +user.password = password +user.role = 'superadmin' +user.state = 'active' +user.level = 3 +user.otp = false + +if user.save + Level.where(id: 1..Level::LEVEL_ID_BOUNDS[user.level.to_s].to_i).find_each do |level| + user.labels.find_or_create_by!(key: level.key, scope: 'private') do |label| + label.value = level.value + end + end + puts "OK email=#{user.email} uid=#{user.uid} state=#{user.state} level=#{user.level}" +else + puts "ERR #{user.errors.full_messages.join(', ')}" + exit 1 +end diff --git a/bin/install.sh b/bin/install.sh new file mode 100644 index 0000000..8b5d0a2 --- /dev/null +++ b/bin/install.sh @@ -0,0 +1,56 @@ +#!/bin/bash -x + +COMPOSE_VERSION="1.23.2" +COMPOSE_URL="https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" + +# Opendax bootstrap script +install_core() { + sudo bash < /etc/docker/daemon.json +EOS +} + +# Docker installation +install_docker() { + curl -fsSL https://get.docker.com/ | bash + sudo bash < webhook.service +sed -i s#OPENDAX_DIRECTORY#${PWD}#g webhook.service + +echo "Generated Secret: ${SECRET}" + +sudo mv ./webhook.service /etc/systemd/system/webhook.service +sudo systemctl daemon-reload +sudo systemctl start webhook diff --git a/bin/quick-test.sh b/bin/quick-test.sh new file mode 100644 index 0000000..2f61338 --- /dev/null +++ b/bin/quick-test.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +http --session barong POST http://www.app.local/api/v2/barong/identity/sessions email='iron@man.io' password='0lDHd9ufs9t@' +http --session barong GET http://www.app.local/api/v2/barong/resource/users/me +http --session barong GET http://www.app.local/api/v2/peatio/account/balances diff --git a/bin/seed_test_balances.rb b/bin/seed_test_balances.rb new file mode 100644 index 0000000..31f388f --- /dev/null +++ b/bin/seed_test_balances.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +# Credits test user balances in Peatio (Dena). +# Run: bundle exec rails runner lib/seed_test_balances.rb + +require 'yaml' +require 'json' +require 'bigdecimal' + +def test_seed_enabled? + ENV.fetch('FIBITEX_SEED_TEST_USERS', 'true') != 'false' +end + +unless test_seed_enabled? + puts 'SKIP seed_test_balances (FIBITEX_SEED_TEST_USERS=false)' + exit 0 +end + +config_path = [ + ENV['TEST_USERS_CONFIG'], + File.expand_path('../config/test_users.yml', __dir__), + '/opt/peatio/config/test_users.yml' +].compact.find { |p| File.exist?(p) } + +unless config_path + puts "ERR missing config: #{config_path}" + exit 1 +end + +config = YAML.safe_load(File.read(config_path)) +fiat_ids = %w[irt cad] + +def min_order_amounts_by_currency + mins = {} + Market.find_each do |market| + next unless market.state == 'enabled' + + amount = market.min_amount.to_d + next if amount <= 0 + + cur = market.base_unit + mins[cur] = mins[cur] ? [mins[cur], amount].min : amount + end + mins +end + +def ensure_member!(entry, barong_role: 'member') + email = entry['email'] + uid = entry['uid'] + member = Member.find_or_initialize_by(email: email) + member.uid = uid if uid.present? + member.role = barong_role + member.level = entry['level'] || 0 + member.state = 'active' + member.group = entry['peatio_group'] || 'vip-0' + member.save! + member +end + +def sync_account_balance!(account, target) + target = target.to_d + current = account.balance.to_d + return if current == target + + diff = target - current + if diff > 0 + account.plus_funds!(diff) + puts "CREDIT #{account.member.email} #{account.currency_id}=#{target} (added #{diff})" + elsif diff < 0 && account.respond_to?(:sub_funds!) && account.balance.to_d >= -diff + account.sub_funds!(-diff) + puts "DEBIT #{account.member.email} #{account.currency_id}=#{target} (removed #{-diff})" + else + account.update!(balance: target) + puts "SET #{account.member.email} #{account.currency_id}=#{target} (was #{current})" + end +end + +min_orders = min_order_amounts_by_currency + +(config['users'] || []).each do |entry| + email = entry['email'] + member = ensure_member!(entry, barong_role: entry['role'] == 'superadmin' ? 'superadmin' : 'member') + coin_fixed = (entry['coin_fixed'] || {}).transform_keys(&:to_s) + + Currency.find_each do |currency| + amount = + if fiat_ids.include?(currency.id) + BigDecimal(entry['fiat_balance'].to_s) + elsif coin_fixed.key?(currency.id) + BigDecimal(coin_fixed[currency.id].to_s) + else + base_min = min_orders[currency.id] || currency.min_deposit_amount.to_d + base_min = BigDecimal('1') if base_min <= 0 + base_min * BigDecimal(entry['coin_multiplier'].to_s) + end + + account = member.get_account(currency) + sync_account_balance!(account, amount) + end +end + +puts 'DONE seed_test_balances' + +(config['users'] || []).each do |entry| + member = Member.find_by(email: entry['email']) + next unless member + + nonzero = member.accounts.where('balance > 0').count + puts "SUMMARY #{entry['email']} currencies_with_balance=#{nonzero}" +end diff --git a/bin/seed_test_users.rb b/bin/seed_test_users.rb new file mode 100644 index 0000000..5298d6c --- /dev/null +++ b/bin/seed_test_users.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +# Creates / updates Fibitex test users in Barong (Dalan). +# Run: bundle exec rails runner lib/seed_test_users.rb +# Guard: set FIBITEX_SEED_TEST_USERS=false to skip. + +require 'yaml' + +require 'json' + +def test_seed_enabled? + ENV.fetch('FIBITEX_SEED_TEST_USERS', 'true') != 'false' +end + +unless test_seed_enabled? + puts 'SKIP seed_test_users (FIBITEX_SEED_TEST_USERS=false)' + exit 0 +end + +config_path = ENV.fetch( + 'TEST_USERS_CONFIG', + File.expand_path('../config/test_users.yml', __dir__) +) + +unless File.exist?(config_path) + puts "ERR missing config: #{config_path}" + exit 1 +end + +config = YAML.safe_load(File.read(config_path)) +fiat_ids = %w[irt cad] + +def apply_kyc_labels!(user, kyc_mode) + Label.where(user_id: user.id, scope: 'private').delete_all + + case kyc_mode.to_s + when 'zero' + bound = Level::LEVEL_ID_BOUNDS['0'].to_i + when 'full' + bound = Level::LEVEL_ID_BOUNDS[user.level.to_s].to_i + else + bound = Level::LEVEL_ID_BOUNDS[user.level.to_s].to_i + end + + Level.where(id: 1..bound).find_each do |level| + user.labels.create!(key: level.key, value: level.value, scope: 'private') + end + + user.update!(level: Level.what_level(user.kyc_info[:points])) if kyc_mode.to_s == 'full' +end + +def sync_user_level!(user, target_level) + return if target_level.nil? + + user.update!(level: target_level.to_i) +end + +def remove_user!(email) + user = User.find_by(email: email) + return unless user + + Label.where(user_id: user.id).delete_all + User.where(id: user.id).delete_all + puts "REMOVED #{email}" +end + +(config['remove_emails'] || []).each do |email| + remove_user!(email) +end + +(config['users'] || []).each do |entry| + email = entry['email'] + user = User.find_or_initialize_by(email: email) + + user.uid = entry['uid'] if entry['uid'].present? && user.uid.blank? + user.password = entry['password'] + user.role = entry['role'] + user.state = entry['state'] || 'active' + user.level = entry['level'] || 0 + user.otp = false + + if user.save + apply_kyc_labels!(user, entry['kyc']) + sync_user_level!(user, entry['level']) + puts "OK #{email} uid=#{user.uid} role=#{user.role} level=#{user.level} kyc=#{entry['kyc']}" + else + puts "ERR #{email}: #{user.errors.full_messages.join(', ')}" + exit 1 + end +end + +File.write( + File.join(Dir.tmpdir, 'fibitex_test_user_uids.json'), + JSON.pretty_generate( + (config['users'] || []).map { |u| { 'email' => u['email'], 'uid' => User.find_by!(email: u['email']).uid } } + ) +) + +puts 'DONE seed_test_users' diff --git a/bin/set-env.sh b/bin/set-env.sh new file mode 100644 index 0000000..5a91fa5 --- /dev/null +++ b/bin/set-env.sh @@ -0,0 +1,3 @@ +export UID=$(id -u) +export GID=$(id -g) +alias dc=docker-compose diff --git a/bin/start.sh b/bin/start.sh new file mode 100644 index 0000000..8222365 --- /dev/null +++ b/bin/start.sh @@ -0,0 +1,31 @@ +#!/bin/bash -x + +COMPOSE_VERSION="1.23.2" +COMPOSE_URL="https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" + +install_opendax() { + sudo -u deploy bash < e + puts "ORDER_FAIL #{e.class}: #{e.message}" + exit 1 +end diff --git a/compose/.gitkeep b/compose/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config.ru b/config.ru new file mode 100644 index 0000000..0fb5fd8 --- /dev/null +++ b/config.ru @@ -0,0 +1,5 @@ +#\ -s Puma --host 0.0.0.0 -p 1337 -E production + +require_relative 'lib/opendax/webhook' + +run Webhook diff --git a/config/app.local.yml.example b/config/app.local.yml.example new file mode 100644 index 0000000..fdc59ae --- /dev/null +++ b/config/app.local.yml.example @@ -0,0 +1,48 @@ +--- +# Copy to config/app.local.yml and fill in values for local Docker development. +# cp config/app.local.yml.example config/app.local.yml +# +# After editing: rake render:config +# +app: + domain: app.local + subdomain: www + shahoo_subdomain: shahoo + shahoo_subdomain: shahoo + shahoo_subdomain: shahoo + shahoo_subdomain: shahoo + shahoo_subdomain: shahoo +render_protect: false +csrfEnabled: false +serverip: + enabled: false + ip: 127.0.0.1 +ssl: + enabled: false +updateVersions: false +captchaLogin: false +captcha: + type: none +images: + peatio: custom/dena:1 + barong: custom/dalan:1 + frontend: custom/gereh:1 + gereh: custom/gereh:1 + shahoo: custom/shahoo:1 + shahoo_bff: custom/shahoo-bff:1 + tower: ya3er/admin_tower:2.2.66 + rango: quay.io/openware/rango:2.6.1 +vault: + root_token: changeme + peatio_rails_token: changeme + peatio_crypto_token: changeme + peatio_upstream_token: changeme + peatio_matching_token: changeme + barong_token: changeme +database: + password: changeme +BetaCandaTestNetwork: true +parity: + enabled: false +bitcoind: + enabled: false diff --git a/config/app.production.yml.example b/config/app.production.yml.example new file mode 100644 index 0000000..d361d5b --- /dev/null +++ b/config/app.production.yml.example @@ -0,0 +1,57 @@ +--- +# Copy to config/app.production.yml on the production server (gitignored). +# Set OPENDAX_ENV=production before rake render:config / rake service:all. +# +# cp config/app.production.yml.example config/app.production.yml +# +app: + domain: tibitex.com + subdomain: www +serverip: + enabled: true + ip: YOUR_SERVER_PUBLIC_IP +ssl: + enabled: true + email: admin@fibitex.com +csrfEnabled: true +captchaLogin: true +captcha: + type: recaptcha + siteKey: YOUR_RECAPTCHA_SITE_KEY + secretKey: YOUR_RECAPTCHA_SECRET_KEY +database: + password: STRONG_DB_PASSWORD +vault: + root_token: changeme + peatio_rails_token: changeme + peatio_crypto_token: changeme + peatio_upstream_token: changeme + peatio_matching_token: changeme + barong_token: changeme +jibit: + key: YOUR_JIBIT_KEY + secret: YOUR_JIBIT_SECRET +kavenegar: + key: YOUR_KAVENEGAR_KEY + sender: YOUR_SENDER +vandar: + mobile: changeme + password: changeme + key: changeme +smtp: + host: mail.fibitex.com + port: 587 + user: "no-reply@fibitex.com" + password: "YOUR_SMTP_PASSWORD" + sender_email: "no-reply@fibitex.com" + sender_name: Fibitex + sender_logo: https://beta.fibitex.com/logo-email.png + auth: plain + domain: fibitex.com + starttls_auto: true + openssl_verify_mode: none +BetaCandaTestNetwork: false +parity: + enabled: false +bitcoind: + enabled: false diff --git a/config/app.staging.cutover.yml.example b/config/app.staging.cutover.yml.example new file mode 100644 index 0000000..3a3ed71 --- /dev/null +++ b/config/app.staging.cutover.yml.example @@ -0,0 +1,15 @@ +--- +# Production cutover overlay — Shahoo replaces Gereh on www.* (use after T5.2 QA sign-off). +# Copy to config/app.staging.yml (or app.production.yml) and set OPENDAX_ENV accordingly. +# +# images.frontend: custom/shahoo:1 ← main user-facing SPA +# Gereh service can be removed from compose after validation. +# +app: + domain: tibitex.com + subdomain: www + shahoo_subdomain: shahoo +images: + frontend: custom/shahoo:1 + shahoo: custom/shahoo:1 + shahoo_bff: custom/shahoo-bff:1 diff --git a/config/app.staging.yml.example b/config/app.staging.yml.example new file mode 100644 index 0000000..ec0fad4 --- /dev/null +++ b/config/app.staging.yml.example @@ -0,0 +1,83 @@ +--- +# Staging overlay — Fibitex beta environment (gitignored: app.staging.yml). +# +# Host naming (matches Cloudflare DNS on fibitex.com zone): +# domain: fibitex.com + subdomain: beta → beta.fibitex.com (Gereh) +# shahoo_subdomain: shahoo → shahoo.fibitex.com (Shahoo + BFF) +# +# Do NOT use domain: beta.fibitex.com + subdomain: www (creates www.beta.fibitex.com). +# +# cp config/app.staging.yml.example config/app.staging.yml +# export OPENDAX_ENV=staging +# bundle exec rake render:config +# docker compose up -d --force-recreate proxy frontend shahoo shahoo-bff +# +app: + domain: fibitex.com + subdomain: beta + shahoo_subdomain: shahoo + # optional explicit host (default: shahoo.fibitex.com): + # shahoo_host: shahoo.fibitex.com + +serverip: + enabled: true + ip: YOUR_SERVER_PUBLIC_IP + +ssl: + enabled: true + email: admin@fibitex.com + +csrfEnabled: true +captchaLogin: true + +images: + peatio: custom/dena:1 + barong: custom/dalan:1 + frontend: custom/gereh:1 + gereh: custom/gereh:1 + shahoo: custom/shahoo:1 + shahoo_bff: custom/shahoo-bff:1 + +database: + password: "STRONG_DB_PASSWORD" + +vault: + root_token: "PASTE_FROM_EXISTING_CONFIG" + peatio_rails_token: "PASTE_FROM_EXISTING_CONFIG" + peatio_crypto_token: "PASTE_FROM_EXISTING_CONFIG" + peatio_upstream_token: "PASTE_FROM_EXISTING_CONFIG" + peatio_matching_token: "PASTE_FROM_EXISTING_CONFIG" + barong_token: "PASTE_FROM_EXISTING_CONFIG" + +jibit: + key: "YOUR_JIBIT_KEY" + secret: "YOUR_JIBIT_SECRET" + +kavenegar: + key: "YOUR_KAVENEGAR_KEY" + sender: "YOUR_SENDER" + +vandar: + mobile: "YOUR_VANDAR_MOBILE" + password: "YOUR_VANDAR_PASSWORD" + key: "YOUR_VANDAR_KEY" + +captcha: + siteKey: "YOUR_RECAPTCHA_SITE_KEY" + secretKey: "YOUR_RECAPTCHA_SECRET_KEY" + +smtp: + host: mail.fibitex.com + port: 587 + user: "no-reply@fibitex.com" + password: "YOUR_SMTP_PASSWORD" + sender_email: "no-reply@fibitex.com" + sender_name: Fibitex + # Host logo on your domain (not postimg.cc) — improves Gmail inbox rate + sender_logo: https://beta.fibitex.com/logo-email.png + auth: plain + domain: fibitex.com + starttls_auto: true + openssl_verify_mode: none + +BetaCandaTestNetwork: false diff --git a/config/app.yml b/config/app.yml new file mode 100644 index 0000000..a1d76d1 --- /dev/null +++ b/config/app.yml @@ -0,0 +1,147 @@ +--- +# Shared baseline configuration (safe to commit — no real secrets). +# Local overrides: config/app.local.yml (gitignored) +# Production secrets: config/app.production.yml (gitignored, OPENDAX_ENV=production) +app: + name: Fibitex + domain: tibitex.com + subdomain: www + shahoo_subdomain: shahoo + show_landing: true +render_protect: false +csrfEnabled: true +serverip: + enabled: true + ip: changeme +admin: + user: admin@fibitex.com + pass: changeme +jibit: + url: https://napi.jibit.ir/ide/v1/ + key: changeme + secret: changeme +kavenegar: + key: changeme + sender: changeme +vandar: + mobile: changeme + password: changeme + key: changeme + name: developers +ssl: + enabled: true + email: admin@fibitex.com +updateVersions: false +images: + peatio: custom/dena:1 + barong: custom/dalan:1 + frontend: custom/gereh:1 + gereh: custom/gereh:1 + shahoo: custom/shahoo:1 + shahoo_bff: custom/shahoo-bff:1 + tower: ya3er/admin_tower:2.2.66 + rango: quay.io/openware/rango:2.6.1 +finex: + enabled: false + image: quay.io/openware/finex:2.6.39 + license_key: changeme +vendor: + frontend: git@github.com:openware/baseapp.git +kyc: + provider: local + authorization_token: changeme + sandbox_mode: true + api_endpoint: https://api.kycaid.com/ +vault: + root_token: changeme + peatio_rails_token: changeme + peatio_crypto_token: changeme + peatio_upstream_token: changeme + peatio_matching_token: changeme + barong_token: changeme + finex_engine_token: changeme +database: + host: db + adapter: mysql + port: 3306 + user: root + password: changeme +storage: + provider: local +twilio: + enabled: false + phone_number: "+15005550000" + account_sid: changeme + auth_token: changeme +gaTrackerKey: '' +captchaLogin: true +captcha: + type: recaptcha + siteKey: changeme + secretKey: changeme +smtp: + host: mail.fibitex.com + port: 587 + user: changeme + password: changeme + sender_email: changeme + sender_name: Fibitex + sender_logo: https://beta.fibitex.com/logo-email.png + auth: plain + domain: fibitex.com + starttls_auto: true + openssl_verify_mode: none +wallets: + eth: + - kind: deposit + address: changeme + max_balance: 0.0 + secret: changeme + - kind: hot + address: changeme + max_balance: 100.0 + secret: changeme + - kind: warm + address: changeme + max_balance: 1000.0 + secret: changeme + btc: + - kind: deposit + address: changeme + max_balance: 0.0 + - kind: hot + address: changeme + max_balance: 100.0 + - kind: warm + address: changeme + max_balance: 1000.0 +BetaCandaTestNetwork: false +parity: + enabled: false + network: testnet + address: parity + rpcport: 8545 + port: 30303 +bitcoind: + enabled: false + rpcuser: admin + rpcpassword: changeme + address: bitcoind + network: testnet + rpcport: 18332 + port: 18333 +litecoind: + rpcuser: admin + rpcpassword: changeme + address: litecoind + network: testnet + rpcport: 19332 + port: 19335 +terraform: + credentials: "~/safe/opendax.json" + project: example-opendax + region: europe-west4 + zone: europe-west4-a + instance_name: opendax-cloud + machine_type: n1-standard-4 + image: debian-cloud/debian-9 diff --git a/config/applogic/.gitkeep b/config/applogic/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/arke/.gitkeep b/config/arke/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/barong/authz_rules.yml b/config/barong/authz_rules.yml new file mode 100644 index 0000000..549af2f --- /dev/null +++ b/config/barong/authz_rules.yml @@ -0,0 +1,18 @@ +# +# pass for whitelisted (public) routes +# block for blacklisted routes +# +rules: + pass: + - api/v2/dalan/public + - api/v2/dalan/identity + - api/v2/dena/public + - api/v2/dena/coinmarketcap + - api/v2/dena/coingecko + - api/v2/ranger/public + - api/v2/applogic/public + - api/v2/arke/public + - api/v2/finex/public + block: + - api/v2/dalan/management + - api/v2/dena/management diff --git a/config/barong/barong.yml b/config/barong/barong.yml new file mode 100644 index 0000000..7c11e47 --- /dev/null +++ b/config/barong/barong.yml @@ -0,0 +1,52 @@ +activation_requirements: + email: 'verified' +state_triggers: + banned: + - ban + - fraud + deleted: + - delete + locked: + - suspicious + - lock +document_types: + - Passport + - Identity card + - Driver license + - Utility Bill + - Residental + - Institutional + - Poa + - Selfie +document_categories: + - front_side + - selfie + - back_side +user_storage_titles: +# - personal ## example +# - company ## example +captcha_protected_endpoints: [] +# - user_create +# - session_create +# - password_reset +# - email_confirmation + +profile_verification_roles: + - superadmin + # - admin + # - kyc_worker + +kyc_levels: + 1: + 2: profile + 3: access_phone + 4: card + 5: iban + 2: + 6: poa + 7: telephone + 8: selfie + 9: owner_phone + 3: + 10: vip + diff --git a/config/barong/seeds.yml b/config/barong/seeds.yml new file mode 100644 index 0000000..e354f3f --- /dev/null +++ b/config/barong/seeds.yml @@ -0,0 +1,382 @@ +# List of Barong administrators. +# +# Other parameters that you can set here can be found in Account, +# Profile and Phone models (e.g. app/models/account.rb...); all the +# model properties are listed at the very bottom of this models files. +# +# Note: email is the only required field here. +users: + - email: admin@test.com + password: "123qwe!@#QWE" + role: superadmin + state: active + level: 3 + - email: user@test.com + password: "123qwe!@#QWE" + role: member + state: active + level: 0 + - email: bot@test.com + password: "123qwe!@#QWE" + role: member + state: active + level: 3 + +levels: + - key: email + id: 1 + value: verified + description: "User enter a valid code after registration" + - key: profile + id: 2 + value: verified + description: "User personal documents have been verified" + - key: access_phone + id: 3 + value: verified + description: "User entered a valid code from sms" + - key: card + id: 4 + value: verified + description: "User card number have been verified" + - key: iban + id: 5 + value: verified + description: "User iban have been verified" + - key: poa + id: 6 + value: verified + description: "User card bank have been verified" + - key: telephone + id: 7 + value: verified + description: "User entered a valid code from ring call" + - key: selfie + id: 8 + value: verified + description: "User selfie documents have been verified" + - key: owner_phone + id: 9 + value: verified + description: "User owner mobile have been verified" + - key: vip + id: 10 + value: verified + description: "User Vip have been verified" + +restrictions: {} +# - { category: whitelist, scope: country, value: UA, state: disabled } +# - { category: maintenance, scope: all, value: all, state: disabled } +# - { category: blacklist, scope: ip, value: 164.116.47.255, state: disabled, code: 433 } +# - { category: blacklist, scope: ip_subnet, value: 164.116.47.0/24, state: disabled, code: 434 } +# - { category: blacklist, scope: country, value: USA, state: disabled, code: 435 } +# - { category: blacklist, scope: continent, value: SA, state: disabled, code: 436 } + +permissions: +# SUPER ADMIN has an access to the whole system without any limits + # so we can just grant him access to /api/v2/* + - { role: superadmin, verb: all, path: api/v2, action: accept } + # Rango(ranger) access + - { role: superadmin, verb: get, path: api/v2/ranger, action: accept } + # we are watching after you 0_0 + - { role: superadmin, verb: post, path: api/v2/, action: audit } + - { role: superadmin, verb: put, path: api/v2/, action: audit } + - { role: superadmin, verb: delete, path: api/v2/, action: audit } + +# ADMIN + # admin has nearly full access to barong and peatio api, except managing permissions + - { role: admin, verb: all, path: api/v2, action: accept } + # ranger access + - { role: admin, verb: get, path: api/v2/ranger, action: accept } + # Finex upstream access + - { role: admin, verb: get, path: api/v2/open_finance, action: accept } + # admin doesnt have access to manage platform roles and permissions + - { role: admin, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + # admin doesnt have access to manage roles + - { role: admin, verb: all, path: api/v2/dalan/admin/users/role, action: drop } + # admin doesnt have access to admin activities + - { role: admin, verb: all, path: api/v2/dalan/admin/activities/admin, action: drop } + # we are watching after you 0_0 + - { role: admin, verb: post, path: api/v2/, action: audit } + - { role: admin, verb: put, path: api/v2/, action: audit } + - { role: admin, verb: delete, path: api/v2/, action: audit } + +# ACCOUNTANT + # accountant has a read access to Barong admin + - { role: accountant, verb: get, path: api/v2/dalan/admin, action: accept } + # accountant has a read access to Peatio financial information and creating of adjustments + - { role: accountant, verb: get, path: api/v2/dena/admin/members, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/beneficiaries, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/currencies, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/blockchains, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/wallets, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/trading_fees, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/withdraw_limits, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/orders, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/markets, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/engine, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/trades, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/deposits, action: accept } + - { role: accountant, verb: post, path: api/v2/dena/admin/deposits/new, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/withdraws, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/adjustments, action: accept } + - { role: accountant, verb: post, path: api/v2/dena/admin/adjustments/new, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/assets, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/liabilities, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/revenues, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/expenses, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/internal_transfers, action: accept } + # accountant doesnt have access to see pending documents + - { role: accountant, verb: get, path: api/v2/dalan/admin/users/documents/pending, action: drop } + # accountant doesnt have access to manage platform roles and permissions + - { role: accountant, verb: all, path: api/v2/dalan/admin/users/role, action: drop } + - { role: accountant, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + # accountant doesnt have access to admin activities + - { role: accountant, verb: all, path: api/v2/dalan/admin/activities/admin, action: drop } + # we are watching after you 0_0 + - { role: accountant, verb: post, path: api/v2/, action: audit } + - { role: accountant, verb: put, path: api/v2/, action: audit } + - { role: accountant, verb: delete, path: api/v2/, action: audit } + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: accountant, verb: all, path: api/v2/dena/account, action: accept } + - { role: accountant, verb: all, path: api/v2/dena/market, action: accept } + - { role: accountant, verb: all, path: api/v2/finex/market, action: accept } + - { role: accountant, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: accountant, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: accountant, verb: all, path: api/v2/dena/swagger, action: accept } + # Drop Peatio order endpoint requests + # ranger access + - { role: accountant, verb: get, path: api/v2/ranger, action: accept } + # applogic access + - { role: accountant, verb: all, path: api/v2/applogic, action: accept } + # get abilities + - { role: accountant, verb: all, path: api/v2/dena/admin/abilities, action: accept } + - { role: accountant, verb: all, path: api/v2/dalan/admin/abilities, action: accept } + +# COMPLIANCE + - { role: compliance, verb: get, path: api/v2/dalan/admin, action: accept } + # has an access to CRUD of user-related resources + - { role: compliance, verb: get, path: api/v2/dena/admin/members, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/beneficiaries, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/currencies, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/trades, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/orders, action: accept } + - { role: compliance, verb: all, path: api/v2/dalan/admin/users, action: accept } + # has ability to see deposit, withdraw, operations (partial) + - { role: compliance, verb: get, path: api/v2/dena/admin/deposits, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/withdraws, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/assets, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/liabilities, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/expenses, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/markets, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/engine, action: accept } + # has no ability to see the configurations + - { role: compliance, verb: all, path: api/v2/dena/admin/adjustments, action: drop } + - { role: compliance, verb: all, path: api/v2/dena/admin/revenues, action: drop } + - { role: compliance, verb: all, path: api/v2/dena/admin/blockchains, action: drop } + - { role: compliance, verb: all, path: api/v2/dena/admin/wallets, action: drop } + - { role: compliance, verb: all, path: api/v2/dena/admin/trading_fees, action: drop } + - { role: compliance, verb: all, path: api/v2/dena/admin/withdraw_limits, action: drop } + - { role: compliance, verb: all, path: api/v2/dalan/admin/restrictions, action: drop } + # compliance doesnt have access to change users roles + - { role: compliance, verb: all, path: api/v2/dalan/admin/users/role, action: drop } + # compliance doesnt have access to admin activities + - { role: compliance, verb: all, path: api/v2/dalan/admin/activities/admin, action: drop } + # compliance doesnt have access to manage platform roles and permissions + - { role: compliance, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + # we are watching after you 0_0 + - { role: compliance, verb: post, path: api/v2/, action: audit } + - { role: compliance, verb: put, path: api/v2/, action: audit } + - { role: compliance, verb: delete, path: api/v2/, action: audit } + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: compliance, verb: all, path: api/v2/dena/account, action: accept } + - { role: compliance, verb: all, path: api/v2/dena/market, action: accept } + - { role: compliance, verb: all, path: api/v2/finex/market, action: accept } + - { role: compliance, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: compliance, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: compliance, verb: all, path: api/v2/dena/swagger, action: accept } + # Drop Peatio order endpoint requests + # ranger access + - { role: compliance, verb: get, path: api/v2/ranger, action: accept } + # applogic access + - { role: compliance, verb: all, path: api/v2/applogic, action: accept } + # get abilities + - { role: compliance, verb: all, path: api/v2/dena/admin/abilities, action: accept } + - { role: compliance, verb: all, path: api/v2/dalan/admin/abilities, action: accept } + +# TECHNICAL + # has an access to CRUD of peatio admin functionality on market, blockchain, wallets, currencies + - { role: technical, verb: get, path: api/v2/dalan/admin, action: accept } + - { role: technical, verb: get, path: api/v2/dena/admin, action: accept } + # technical has a configuration access to Peatio admin + - { role: technical, verb: all, path: api/v2/dena/admin/blockchains, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/currencies, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/markets, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/wallets, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/trading_fees, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/withdraw_limits, action: accept } + - { role: technical, verb: get, path: api/v2/dena/admin/internal_transfers, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/engine, action: accept } + # technical has access to delete orders + - { role: technical, verb: delete, path: api/v2/finex/admin/bulk/orders_by_id, action: accept } + - { role: technical, verb: post, path: api/v2/finex/admin/orders/cancel, action: accept } + # technical has an ability to create and update restrictions + - { role: technical, verb: all, path: api/v2/dalan/admin/restrictions, action: accept } + # has no ability to see and update Deposit, Withdraw, Adjustments + - { role: technical, verb: all, path: api/v2/dena/admin/deposits, action: drop } + - { role: technical, verb: all, path: api/v2/dena/admin/withdraws, action: drop } + - { role: technical, verb: all, path: api/v2/dena/admin/adjustments, action: drop } + # Finex upstream access + - { role: technical, verb: get, path: api/v2/open_finance, action: accept } + # technical doesnt have access to see pending documents + - { role: technical, verb: get, path: api/v2/dalan/admin/users/documents/pending, action: drop } + # technical doesnt have access to admin activities + - { role: technical, verb: all, path: api/v2/dalan/admin/activities/admin, action: drop } + # technical doesnt have access to manage platform roles and permissions + - { role: technical, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + # we are watching after you 0_0 + - { role: technical, verb: post, path: api/v2/, action: audit } + - { role: technical, verb: put, path: api/v2/, action: audit } + - { role: technical, verb: delete, path: api/v2/, action: audit } + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: technical, verb: all, path: api/v2/dena/account, action: accept } + - { role: technical, verb: all, path: api/v2/dena/market, action: accept } + - { role: technical, verb: all, path: api/v2/finex/market, action: accept } + - { role: technical, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: technical, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: technical, verb: all, path: api/v2/dena/swagger, action: accept } + # Drop Peatio order endpoint requests + # ranger access + - { role: technical, verb: get, path: api/v2/ranger, action: accept } + # applogic access + - { role: technical, verb: all, path: api/v2/applogic, action: accept } + # get abilities + - { role: technical, verb: all, path: api/v2/dena/admin/abilities, action: accept } + - { role: technical, verb: all, path: api/v2/dalan/admin/abilities, action: accept } + +# SUPPORT + # has read only access to several statistic and user-related endpoints + - { role: support, verb: get, path: api/v2/dalan/admin, action: accept } + - { role: support, verb: get, path: api/v2/dena/admin, action: accept } + # has no ability to see the configurations + - { role: support, verb: all, path: api/v2/dena/admin/adjustments, action: drop } + - { role: support, verb: all, path: api/v2/dena/admin/revenues, action: drop } + - { role: support, verb: all, path: api/v2/dena/admin/blockchains, action: drop } + - { role: support, verb: all, path: api/v2/dena/admin/wallets, action: drop } + - { role: support, verb: all, path: api/v2/dena/admin/trading_fees, action: drop } + - { role: support, verb: all, path: api/v2/dena/admin/withdraw_limits, action: drop } + - { role: support, verb: all, path: api/v2/dalan/admin/restrictions, action: drop } + - { role: support, verb: get, path: api/v2/dena/admin/internal_transfers, action: accept } + - { role: support, verb: get, path: api/v2/dena/admin/engine, action: accept } + # has ability to disable 2FA + - { role: support, verb: post, path: api/v2/dalan/admin/users/update, action: accept } + # support doesnt have access to admin activities + - { role: support, verb: all, path: api/v2/dalan/admin/activities/admin, action: drop } + # support doesnt have access to manage platform roles and permissions + - { role: support, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + - { role: support, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + # we are watching after you 0_0 + - { role: support, verb: post, path: api/v2/, action: audit } + - { role: support, verb: put, path: api/v2/, action: audit } + - { role: support, verb: delete, path: api/v2/, action: audit } + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: support, verb: all, path: api/v2/dena/account, action: accept } + - { role: support, verb: all, path: api/v2/dena/market, action: accept } + - { role: support, verb: all, path: api/v2/finex/market, action: accept } + - { role: support, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: support, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: support, verb: all, path: api/v2/dena/swagger, action: accept } + # Drop Peatio order endpoint requests + # ranger access + - { role: support, verb: get, path: api/v2/ranger, action: accept } + # applogic access + - { role: support, verb: all, path: api/v2/applogic, action: accept } + # get abilities + - { role: support, verb: all, path: api/v2/dena/admin/abilities, action: accept } + - { role: support, verb: all, path: api/v2/dalan/admin/abilities, action: accept } + +# TRADER + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: trader, verb: all, path: api/v2/dena/account, action: accept } + - { role: trader, verb: all, path: api/v2/dena/market, action: accept } + - { role: trader, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: trader, verb: all, path: api/v2/resource, action: accept } + - { role: trader, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: trader, verb: all, path: api/v2/dena/swagger, action: accept } + # ranger access + - { role: trader, verb: get, path: api/v2/ranger, action: accept } + # Finex upstream access + - { role: trader, verb: get, path: api/v2/open_finance, action: accept } + # applogic access + - { role: trader, verb: all, path: api/v2/applogic, action: accept } + +# MEMBER + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: member, verb: all, path: api/v2/dena/account, action: accept } + - { role: member, verb: all, path: api/v2/dena/market, action: accept } + - { role: member, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: member, verb: all, path: api/v2/resource, action: accept } + - { role: member, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: member, verb: all, path: api/v2/dena/swagger, action: accept } + # ranger access + - { role: member, verb: get, path: api/v2/ranger, action: accept } + # Finex upstream access + - { role: member, verb: get, path: api/v2/open_finance, action: accept } + # applogic access + - { role: member, verb: all, path: api/v2/applogic, action: accept } + +# BROKER + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: broker, verb: all, path: api/v2/dena/account, action: accept } + - { role: broker, verb: all, path: api/v2/dena/market, action: accept } + - { role: broker, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: broker, verb: all, path: api/v2/resource, action: accept } + - { role: broker, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: broker, verb: all, path: api/v2/dena/swagger, action: accept } + # ranger access + - { role: broker, verb: get, path: api/v2/ranger, action: accept } + # Finex upstream access + - { role: broker, verb: get, path: api/v2/open_finance, action: accept } + # applogic access + - { role: broker, verb: all, path: api/v2/applogic, action: accept } + +# MAKER + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: maker, verb: all, path: api/v2/dena/account, action: accept } + - { role: maker, verb: all, path: api/v2/dena/market, action: accept } + - { role: maker, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: maker, verb: all, path: api/v2/resource, action: accept } + - { role: maker, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: maker, verb: all, path: api/v2/dena/swagger, action: accept } + # ranger access + - { role: maker, verb: get, path: api/v2/ranger, action: accept } + # Finex upstream access + - { role: maker, verb: get, path: api/v2/open_finance, action: accept } + # applogic access + - { role: maker, verb: all, path: api/v2/applogic, action: accept } + +# Service Account Maker + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: sa_maker, verb: all, path: api/v2/dena/account, action: accept } + - { role: sa_maker, verb: all, path: api/v2/dena/market, action: accept } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: sa_maker, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: sa_maker, verb: all, path: api/v2/dena/swagger, action: accept } + # Service Account can not interact with Password, 2FA, KYC, API keys, Beneficiary, Deposit and Withdraw + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/otp, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/phones, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/profiles, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/documents, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/addresses, action: drop } + - { role: sa_maker, verb: all, path: api/v2/applogic/private/tenants, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/api_keys, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/users/password, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dena/account/deposit_address, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dena/account/withdraws, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dena/account/beneficiaries, action: drop } + # Finex upstream access + - { role: sa_maker, verb: get, path: api/v2/open_finance, action: accept } + # ranger access + - { role: sa_maker, verb: get, path: api/v2/ranger, action: accept } + # applogic access + - { role: sa_maker, verb: all, path: api/v2/applogic, action: accept } diff --git a/config/frontend/.gitkeep b/config/frontend/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/gateway/.gitkeep b/config/gateway/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/influxdb/arke.sql b/config/influxdb/arke.sql new file mode 100644 index 0000000..d90d6d2 --- /dev/null +++ b/config/influxdb/arke.sql @@ -0,0 +1,79 @@ +CREATE DATABASE arke_development; + +CREATE CONTINUOUS QUERY "trade_to_cq_1m" ON arke_development +RESAMPLE EVERY 5s FOR 10m +BEGIN + SELECT FIRST(price) AS open, max(price) AS high, min(price) AS low, last(price) AS close, sum(amount) AS volume INTO candles_1m FROM trades GROUP BY time(1m), market fill(null) +END; + +CREATE CONTINUOUS QUERY "trade_amount_to_cq_1m" ON arke_development +RESAMPLE EVERY 5s FOR 10m +BEGIN + SELECT sum(amount) AS volume INTO candles_1m FROM trades GROUP BY time(1m), market fill(0) +END; + +CREATE CONTINUOUS QUERY "cq_5m" ON arke_development +RESAMPLE EVERY 5s FOR 10m +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_5m" FROM "candles_1m" GROUP BY time(5m), market +END; + +CREATE CONTINUOUS QUERY "cq_15m" ON arke_development +RESAMPLE EVERY 5s FOR 30m +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_15m" FROM "candles_5m" GROUP BY time(15m), market +END; + +CREATE CONTINUOUS QUERY "cq_30m" ON arke_development +RESAMPLE EVERY 5s FOR 1h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_30m" FROM "candles_15m" GROUP BY time(30m), market +END; + +CREATE CONTINUOUS QUERY "cq_1h" ON arke_development +RESAMPLE EVERY 5s FOR 2h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_1h" FROM "candles_30m" GROUP BY time(1h), market +END; + +CREATE CONTINUOUS QUERY "cq_2h" ON arke_development +RESAMPLE EVERY 5s FOR 4h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_2h" FROM "candles_1h" GROUP BY time(2h), market +END; + +CREATE CONTINUOUS QUERY "cq_4h" ON arke_development +RESAMPLE EVERY 5s FOR 8h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_4h" FROM "candles_2h" GROUP BY time(4h), market +END; + +CREATE CONTINUOUS QUERY "cq_6h" ON arke_development +RESAMPLE EVERY 5s FOR 12h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_6h" FROM "candles_2h" GROUP BY time(6h), market +END; + +CREATE CONTINUOUS QUERY "cq_12h" ON arke_development +RESAMPLE EVERY 5s FOR 24h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_12h" FROM "candles_6h" GROUP BY time(12h), market +END; + +CREATE CONTINUOUS QUERY "cq_1d" ON arke_development +RESAMPLE EVERY 5s FOR 2d +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_1d" FROM "candles_6h" GROUP BY time(1d), market +END; + +CREATE CONTINUOUS QUERY "cq_3d" ON arke_development +RESAMPLE EVERY 5s FOR 6d +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_3d" FROM "candles_1d" GROUP BY time(3d), market +END; + +CREATE CONTINUOUS QUERY "cq_1w" ON arke_development +RESAMPLE EVERY 5s FOR 2w +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_1w" FROM "candles_1d" GROUP BY time(7d), market +END; diff --git a/config/influxdb/build_candles.sql b/config/influxdb/build_candles.sql new file mode 100644 index 0000000..fd25b6f --- /dev/null +++ b/config/influxdb/build_candles.sql @@ -0,0 +1,11 @@ +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_5m" FROM "candles_1m" GROUP BY time(5m), market; +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_15m" FROM "candles_5m" GROUP BY time(15m), market; +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_30m" FROM "candles_15m" GROUP BY time(30m), market; +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_1h" FROM "candles_30m" GROUP BY time(1h), market; +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_2h" FROM "candles_1h" GROUP BY time(2h), market; +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_4h" FROM "candles_2h" GROUP BY time(4h), market; +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_6h" FROM "candles_2h" GROUP BY time(6h), market; +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_12h" FROM "candles_6h" GROUP BY time(6h), market; +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_1d" FROM "candles_4h" GROUP BY time(1d), market; +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_3d" FROM "candles_1d" GROUP BY time(3d), market; +SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_1w" FROM "candles_1d" GROUP BY time(1w), market; diff --git a/config/influxdb/peatio.sql b/config/influxdb/peatio.sql new file mode 100644 index 0000000..9367de0 --- /dev/null +++ b/config/influxdb/peatio.sql @@ -0,0 +1,66 @@ +CREATE DATABASE peatio_production; +CREATE CONTINUOUS QUERY "trade_to_cq_1m" ON peatio_production +RESAMPLE EVERY 1s FOR 3m +BEGIN + SELECT FIRST(price) AS open, max(price) AS high, min(price) AS low, last(price) AS close, sum(amount) AS volume INTO candles_1m FROM trades GROUP BY time(1m), market +END; +CREATE CONTINUOUS QUERY "candles_1m_to_cq_1m" ON peatio_production +RESAMPLE EVERY 1m FOR 2m +BEGIN + SELECT last(close) AS open, last(close) AS high, last(close) AS low, last(close) AS close, last(volume) * 0 as volume INTO candles_1m FROM candles_1m GROUP BY time(1m), market fill(previous) +END; +CREATE CONTINUOUS QUERY "cq_5m" ON peatio_production +RESAMPLE EVERY 5s FOR 10m +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_5m" FROM "candles_1m" GROUP BY time(5m), market +END; +CREATE CONTINUOUS QUERY "cq_15m" ON peatio_production +RESAMPLE EVERY 5s FOR 30m +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_15m" FROM "candles_5m" GROUP BY time(15m), market +END; +CREATE CONTINUOUS QUERY "cq_30m" ON peatio_production +RESAMPLE EVERY 5s FOR 1h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_30m" FROM "candles_15m" GROUP BY time(30m), market +END; +CREATE CONTINUOUS QUERY "cq_1h" ON peatio_production +RESAMPLE EVERY 5s FOR 2h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_1h" FROM "candles_30m" GROUP BY time(1h), market +END; +CREATE CONTINUOUS QUERY "cq_2h" ON peatio_production +RESAMPLE EVERY 5s FOR 4h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_2h" FROM "candles_1h" GROUP BY time(2h), market +END; +CREATE CONTINUOUS QUERY "cq_4h" ON peatio_production +RESAMPLE EVERY 5s FOR 8h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_4h" FROM "candles_2h" GROUP BY time(4h), market +END; +CREATE CONTINUOUS QUERY "cq_6h" ON peatio_production +RESAMPLE EVERY 5s FOR 12h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_6h" FROM "candles_2h" GROUP BY time(6h), market +END; +CREATE CONTINUOUS QUERY "cq_12h" ON peatio_production +RESAMPLE EVERY 5s FOR 24h +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_12h" FROM "candles_6h" GROUP BY time(12h), market +END; +CREATE CONTINUOUS QUERY "cq_1d" ON peatio_production +RESAMPLE EVERY 5s FOR 2d +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_1d" FROM "candles_6h" GROUP BY time(1d), market +END; +CREATE CONTINUOUS QUERY "cq_3d" ON peatio_production +RESAMPLE EVERY 5s FOR 6d +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_3d" FROM "candles_1d" GROUP BY time(3d), market +END; +CREATE CONTINUOUS QUERY "cq_1w" ON peatio_production +RESAMPLE EVERY 5s FOR 2w +BEGIN + SELECT FIRST(open) as open, MAX(high) as high, MIN(low) as low, LAST(close) as close, SUM(volume) as volume INTO "candles_1w" FROM "candles_1d" GROUP BY time(7d), market +END; diff --git a/config/mailer/templates/deposit_accepted.en.html.erb b/config/mailer/templates/deposit_accepted.en.html.erb new file mode 100644 index 0000000..4e90f48 --- /dev/null +++ b/config/mailer/templates/deposit_accepted.en.html.erb @@ -0,0 +1,55 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/email_confirmation.en.html.erb b/config/mailer/templates/email_confirmation.en.html.erb new file mode 100644 index 0000000..5e738f6 --- /dev/null +++ b/config/mailer/templates/email_confirmation.en.html.erb @@ -0,0 +1,73 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/email_confirmation.ru.html.erb b/config/mailer/templates/email_confirmation.ru.html.erb new file mode 100644 index 0000000..ea8a425 --- /dev/null +++ b/config/mailer/templates/email_confirmation.ru.html.erb @@ -0,0 +1,73 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/email_confirmation_code.en.html.erb b/config/mailer/templates/email_confirmation_code.en.html.erb new file mode 100644 index 0000000..9534060 --- /dev/null +++ b/config/mailer/templates/email_confirmation_code.en.html.erb @@ -0,0 +1,97 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/email_otp_disable_confirmation_code.en.html.erb b/config/mailer/templates/email_otp_disable_confirmation_code.en.html.erb new file mode 100644 index 0000000..62506df --- /dev/null +++ b/config/mailer/templates/email_otp_disable_confirmation_code.en.html.erb @@ -0,0 +1,73 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/email_otp_enable_confirmation_code.en.html.erb b/config/mailer/templates/email_otp_enable_confirmation_code.en.html.erb new file mode 100644 index 0000000..957fef7 --- /dev/null +++ b/config/mailer/templates/email_otp_enable_confirmation_code.en.html.erb @@ -0,0 +1,73 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/label.en.html.erb b/config/mailer/templates/label.en.html.erb new file mode 100644 index 0000000..833659b --- /dev/null +++ b/config/mailer/templates/label.en.html.erb @@ -0,0 +1,76 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/new_beneficiary.en.html.erb b/config/mailer/templates/new_beneficiary.en.html.erb new file mode 100644 index 0000000..c2cc1d4 --- /dev/null +++ b/config/mailer/templates/new_beneficiary.en.html.erb @@ -0,0 +1,55 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/otp_confirmation_code.en.html.erb b/config/mailer/templates/otp_confirmation_code.en.html.erb new file mode 100644 index 0000000..30bebd3 --- /dev/null +++ b/config/mailer/templates/otp_confirmation_code.en.html.erb @@ -0,0 +1,73 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/password_confirmation_code.en.html.erb b/config/mailer/templates/password_confirmation_code.en.html.erb new file mode 100644 index 0000000..1dca894 --- /dev/null +++ b/config/mailer/templates/password_confirmation_code.en.html.erb @@ -0,0 +1,73 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/password_reset.en.html.erb b/config/mailer/templates/password_reset.en.html.erb new file mode 100644 index 0000000..f433cf4 --- /dev/null +++ b/config/mailer/templates/password_reset.en.html.erb @@ -0,0 +1,97 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/password_reset.ru.html.erb b/config/mailer/templates/password_reset.ru.html.erb new file mode 100644 index 0000000..13eca0f --- /dev/null +++ b/config/mailer/templates/password_reset.ru.html.erb @@ -0,0 +1,73 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/session_create.en.html.erb b/config/mailer/templates/session_create.en.html.erb new file mode 100644 index 0000000..01c52c7 --- /dev/null +++ b/config/mailer/templates/session_create.en.html.erb @@ -0,0 +1,61 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/session_failed.en.html.erb b/config/mailer/templates/session_failed.en.html.erb new file mode 100644 index 0000000..c850873 --- /dev/null +++ b/config/mailer/templates/session_failed.en.html.erb @@ -0,0 +1,61 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/withdraw_confirmation_code.en.html.erb b/config/mailer/templates/withdraw_confirmation_code.en.html.erb new file mode 100644 index 0000000..59c7b0a --- /dev/null +++ b/config/mailer/templates/withdraw_confirmation_code.en.html.erb @@ -0,0 +1,73 @@ + + + + + + + + + + + diff --git a/config/mailer/templates/withdraw_succeed.en.html.erb b/config/mailer/templates/withdraw_succeed.en.html.erb new file mode 100644 index 0000000..13f92ae --- /dev/null +++ b/config/mailer/templates/withdraw_succeed.en.html.erb @@ -0,0 +1,55 @@ + + + + + + + + + + + diff --git a/config/monitoring/alertmanager/.gitkeep b/config/monitoring/alertmanager/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/monitoring/loki/.gitkeep b/config/monitoring/loki/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/monitoring/prometheus/.gitkeep b/config/monitoring/prometheus/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/monitoring/promtail/.gitkeep b/config/monitoring/promtail/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/mysql/innodb.cnf b/config/mysql/innodb.cnf new file mode 100644 index 0000000..83717b1 --- /dev/null +++ b/config/mysql/innodb.cnf @@ -0,0 +1,8 @@ +[mysqld] +innodb_buffer_pool_size = 2G +innodb_buffer_pool_instances = 2 +innodb_log_buffer_size = 128M +innodb_log_file_size = 512M +innodb_flush_log_at_trx_commit = 0 +# mysql2 0.5.x (Rails 5.2) — keep native password until Ruby/mysql2 upgrade +default_authentication_plugin=mysql_native_password diff --git a/config/peatio/plugins.yml b/config/peatio/plugins.yml new file mode 100644 index 0000000..274bf12 --- /dev/null +++ b/config/peatio/plugins.yml @@ -0,0 +1,22 @@ +# Be sure to run "bin/install_plugins" when you modify this file. +# +# This file is used for listing Peatio plugins. +# The plugins must be listed as an array. Each element of array described the plugin using the next variables: +# +# * name +# Mandatory. Specify plugin name. The name must be compatible with filesystem rules. +# +# * git +# Mandatory. Specify Git repository URL. +# +# * commit +# Mandatory. Specify commit hash which Peatio will checkout via "bin/install_plugins". +# +# * require +# Optional. Specify relative path to file from vendor/plugins which should be required by Peatio. +# You may set this value to "false" if you don't want Peatio to require the plugin. + +# Example configuration: +#- name: peatio-plugin-example +# git: https://github.com/rubykube/peatio-plugin-example.git +# commit: 11edd2e7c0bef229516f42fde79615a68a008d45 diff --git a/config/peatio/seed/.gitkeep b/config/peatio/seed/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/peatio/seed/currencies.yml b/config/peatio/seed/currencies.yml new file mode 100644 index 0000000..e7f888e --- /dev/null +++ b/config/peatio/seed/currencies.yml @@ -0,0 +1,411 @@ +- id: irt + name: Iranian Toman + type: fiat + precision: 2 + base_factor: 1 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 10 + min_collection_amount: 10 + withdraw_limit_24h: 1000 + withdraw_limit_72h: 2000 + deposit_fee: 0 + withdraw_fee: 0 + position: 100 + options: {} + + + +- id: cad + name: Canadian Dollar + type: fiat + precision: 2 + base_factor: 1 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 10 + min_collection_amount: 10 + withdraw_limit_24h: 1000 + withdraw_limit_72h: 2000 + deposit_fee: 0 + withdraw_fee: 0 + position: 1 + options: {} + +- id: usdt + name: Tether + blockchain_key: eth-rinkeby + type: coin + precision: 2 + base_factor: 1 + # IMPORTANT: Don't forget to update this variable according + # to your ERC20-based currency requirements (usually can be found on the official website). + visible: true + deposit_enabled: false + withdrawal_enabled: false + # Deposits with less amount are skipped during blockchain synchronization. + # We advise to set value 10 times bigger than the network fee to prevent losses. + # NOTE: Network fee is paid in ETH but min_deposit_amount is in TRST. + min_deposit_amount: 2 + min_collection_amount: 20 + withdraw_limit_24h: 1000 + withdraw_limit_72h: 3000 + deposit_fee: 0 + withdraw_fee: 4 + position: 2 + options: + # ERC20 tx fees configurations. + # Maximum amount of gas you're willing to spend on a particular transaction. + gas_limit: 90_000 + # Internal price that is paid for running a contract on the Ethereum network. + gas_price: 1_000_000_000 + # + # ERC20 configuration. + erc20_contract_address: '0xdac17f958d2ee523a2206206994597c13d831ec7' # Always wrap this value in quotes! + +- id: btc + name: Bitcoin + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 0.00005 + min_collection_amount: 0.0001 + withdraw_limit_24h: 0.1 + withdraw_limit_72h: 0.2 + deposit_fee: 0 + withdraw_fee: 0.0003 + position: 3 + options: {} + +- id: eth + name: Ethereum + blockchain_key: eth-rinkeby + type: coin + precision: 8 + base_factor: 1_000_000_000_000_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 0.00021 + min_collection_amount: 0.00021 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 0 + position: 4 + options: + gas_limit: 21_000 + gas_price: 1_000_000_000 + +- id: etc + name: Ethereum Classic + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 1_000_000_000_000_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 0.00021 + min_collection_amount: 0.00021 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 0 + position: 5 + options: {} + +- id: shib + name: 1000 Shiba Inu + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 6 + options: {} + +- id: bch + name: Bitcoin Cash + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 7 + options: {} + +- id: ltc + name: Litecoin + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 8 + options: {} + +- id: ada + name: Cardano + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 9 + options: {} + +- id: bnb + name: BNB + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 10 + options: {} + +- id: xlm + name: Stellar Lumens + blockchain_key: xlm-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 11 + options: {} + +- id: xrp + name: Ripple + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 12 + options: {} + +- id: trx + name: Tron + blockchain_key: trx-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 13 + options: {} + +- id: doge + name: Dogecoin + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 14 + options: {} + +- id: uni + name: Uniswap + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 15 + options: {} + +- id: link + name: Chainlink + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 16 + options: {} + +- id: dot + name: Polkadot + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 17 + options: {} + +- id: aave + name: AAVE + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 18 + options: {} + +- id: matic + name: Polygon + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 19 + options: {} + +- id: mkr + name: Maker + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 20 + options: {} + +- id: sol + name: Solana + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 21 + options: {} + diff --git a/config/peatio/seed/markets.yml b/config/peatio/seed/markets.yml new file mode 100644 index 0000000..c5b186a --- /dev/null +++ b/config/peatio/seed/markets.yml @@ -0,0 +1,752 @@ +# IRT Market------------------------------------------ +- id: usdtirt + engine_name: peatio-default-engine + base_unit: usdt + quote_unit: irt + amount_precision: 2 + price_precision: 2 + min_price: 9000 + max_price: 9000000 + min_amount: 1 + position: 40 + state: enabled + data: {} +- id: btcirt + engine_name: peatio-default-engine + base_unit: btc + quote_unit: irt + amount_precision: 6 + price_precision: 2 + min_price: 90000000 + max_price: 18000000000 + min_amount: 0.0001 + position: 41 + state: enabled + data: {} +- id: ethirt + engine_name: peatio-default-engine + base_unit: eth + quote_unit: irt + amount_precision: 5 + price_precision: 2 + min_price: 9000000 + max_price: 1800000000 + min_amount: 0.0001 + position: 42 + state: enabled + data: {} +- id: etcirt + engine_name: peatio-default-engine + base_unit: etc + quote_unit: irt + amount_precision: 2 + price_precision: 4 + min_price: 90000 + max_price: 45000000 + min_amount: 0.01 + position: 43 + state: enabled + data: {} +- id: shibirt + engine_name: peatio-default-engine + base_unit: shib + quote_unit: irt + amount_precision: 0 + price_precision: 6 + min_price: 1 + max_price: 900000 + min_amount: 1 + position: 44 + state: enabled + data: {} +- id: bchirt + engine_name: peatio-default-engine + base_unit: bch + quote_unit: irt + amount_precision: 5 + price_precision: 2 + min_price: 9000 + max_price: 450000000 + min_amount: 0.001 + position: 45 + state: enabled + data: {} +- id: ltcirt + engine_name: peatio-default-engine + base_unit: ltc + quote_unit: irt + amount_precision: 6 + price_precision: 2 + min_price: 9000 + max_price: 450000000 + min_amount: 0.001 + position: 46 + state: enabled + data: {} +- id: adairt + engine_name: peatio-default-engine + base_unit: ada + quote_unit: irt + amount_precision: 3 + price_precision: 4 + min_price: 9 + max_price: 9000000 + min_amount: 0.1 + position: 47 + state: enabled + data: {} +- id: bnbirt + engine_name: peatio-default-engine + base_unit: bnb + quote_unit: irt + amount_precision: 4 + price_precision: 3 + min_price: 90000 + max_price: 450000000 + min_amount: 0.01 + position: 48 + state: enabled + data: {} +- id: xlmirt + engine_name: peatio-default-engine + base_unit: xlm + quote_unit: irt + amount_precision: 5 + price_precision: 4 + min_price: 9 + max_price: 9000000 + min_amount: 0.1 + position: 49 + state: enabled + data: {} +- id: xrpirt + engine_name: peatio-default-engine + base_unit: xrp + quote_unit: irt + amount_precision: 5 + price_precision: 4 + min_price: 9 + max_price: 9000000 + min_amount: 0.1 + position: 50 + state: enabled + data: {} +- id: trxirt + engine_name: peatio-default-engine + base_unit: trx + quote_unit: irt + amount_precision: 5 + price_precision: 4 + min_price: 9 + max_price: 9000000 + min_amount: 0.1 + position: 51 + state: enabled + data: {} +- id: dogeirt + engine_name: peatio-default-engine + base_unit: doge + quote_unit: irt + amount_precision: 5 + price_precision: 4 + min_price: 9 + max_price: 9000000 + min_amount: 1 + position: 52 + state: enabled + data: {} +- id: uniirt + engine_name: peatio-default-engine + base_unit: uni + quote_unit: irt + amount_precision: 4 + price_precision: 4 + min_price: 9 + max_price: 9000000 + min_amount: 0.001 + position: 53 + state: enabled + data: {} +- id: linkirt + engine_name: peatio-default-engine + base_unit: link + quote_unit: irt + amount_precision: 4 + price_precision: 4 + min_price: 9 + max_price: 9000000 + min_amount: 0.001 + position: 54 + state: enabled + data: {} +- id: dotirt + engine_name: peatio-default-engine + base_unit: dot + quote_unit: irt + amount_precision: 3 + price_precision: 4 + min_price: 90 + max_price: 9000000 + min_amount: 0.1 + position: 55 + state: enabled + data: {} +- id: aaveirt + engine_name: peatio-default-engine + base_unit: aave + quote_unit: irt + amount_precision: 4 + price_precision: 6 + min_price: 9000 + max_price: 450000000 + min_amount: 0.0001 + position: 56 + state: enabled + data: {} +- id: maticirt + engine_name: peatio-default-engine + base_unit: matic + quote_unit: irt + amount_precision: 3 + price_precision: 4 + min_price: 90 + max_price: 9000000 + min_amount: 1 + position: 57 + state: enabled + data: {} +- id: mkrirt + engine_name: peatio-default-engine + base_unit: mkr + quote_unit: irt + amount_precision: 4 + price_precision: 4 + min_price: 9000 + max_price: 450000000 + min_amount: 0.0001 + position: 58 + state: enabled + data: {} +- id: solirt + engine_name: peatio-default-engine + base_unit: sol + quote_unit: irt + amount_precision: 4 + price_precision: 6 + min_price: 90 + max_price: 9000000 + min_amount: 0.001 + position: 59 + state: enabled + data: {} + +# CAD Market------------------------------------------ +- id: usdtcad + engine_name: peatio-default-engine + base_unit: usdt + quote_unit: cad + amount_precision: 2 + price_precision: 2 + min_price: 0.1 + max_price: 100 + min_amount: 1 + position: 1 + state: enabled + data: {} + +- id: btccad + engine_name: peatio-default-engine + base_unit: btc + quote_unit: cad + amount_precision: 6 + price_precision: 2 + min_price: 1000 + max_price: 200000 + min_amount: 0.0001 + position: 2 + state: enabled + data: {} + +- id: ethcad + engine_name: peatio-default-engine + base_unit: eth + quote_unit: cad + amount_precision: 5 + price_precision: 2 + min_price: 100 + max_price: 20000 + min_amount: 0.0001 + position: 3 + state: enabled + data: {} + +- id: etccad + engine_name: peatio-default-engine + base_unit: etc + quote_unit: cad + amount_precision: 2 + price_precision: 4 + min_price: 1 + max_price: 500 + min_amount: 0.01 + position: 4 + state: enabled + data: {} + +- id: shibcad + engine_name: peatio-default-engine + base_unit: shib + quote_unit: cad + amount_precision: 0 + price_precision: 6 + min_price: 0.00001 + max_price: 10 + min_amount: 1 + position: 5 + state: enabled + data: {} + +- id: bchcad + engine_name: peatio-default-engine + base_unit: bch + quote_unit: cad + amount_precision: 5 + price_precision: 2 + min_price: 0.1 + max_price: 5000 + min_amount: 0.001 + position: 6 + state: enabled + data: {} + +- id: ltccad + engine_name: peatio-default-engine + base_unit: ltc + quote_unit: cad + amount_precision: 6 + price_precision: 2 + min_price: 0.1 + max_price: 5000 + min_amount: 0.001 + position: 7 + state: enabled + data: {} + +- id: adacad + engine_name: peatio-default-engine + base_unit: ada + quote_unit: cad + amount_precision: 3 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 8 + state: enabled + data: {} + +- id: bnbcad + engine_name: peatio-default-engine + base_unit: bnb + quote_unit: cad + amount_precision: 4 + price_precision: 3 + min_price: 1 + max_price: 5000 + min_amount: 0.01 + position: 9 + state: enabled + data: {} + +- id: xlmcad + engine_name: peatio-default-engine + base_unit: xlm + quote_unit: cad + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 10 + state: enabled + data: {} + +- id: xrpcad + engine_name: peatio-default-engine + base_unit: xrp + quote_unit: cad + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 11 + state: enabled + data: {} + +- id: trxcad + engine_name: peatio-default-engine + base_unit: trx + quote_unit: cad + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 12 + state: enabled + data: {} + +- id: dogecad + engine_name: peatio-default-engine + base_unit: doge + quote_unit: cad + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 1 + position: 13 + state: enabled + data: {} + +- id: unicad + engine_name: peatio-default-engine + base_unit: uni + quote_unit: cad + amount_precision: 4 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.001 + position: 14 + state: enabled + data: {} + +- id: linkcad + engine_name: peatio-default-engine + base_unit: link + quote_unit: cad + amount_precision: 4 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.001 + position: 15 + state: enabled + data: {} + +- id: dotcad + engine_name: peatio-default-engine + base_unit: dot + quote_unit: cad + amount_precision: 3 + price_precision: 4 + min_price: 0.001 + max_price: 100 + min_amount: 0.1 + position: 16 + state: enabled + data: {} + +- id: aavecad + engine_name: peatio-default-engine + base_unit: aave + quote_unit: cad + amount_precision: 4 + price_precision: 6 + min_price: 0.1 + max_price: 5000 + min_amount: 0.0001 + position: 17 + state: enabled + data: {} + +- id: maticcad + engine_name: peatio-default-engine + base_unit: matic + quote_unit: cad + amount_precision: 3 + price_precision: 4 + min_price: 0.001 + max_price: 100 + min_amount: 1 + position: 18 + state: enabled + data: {} + +- id: mkrcad + engine_name: peatio-default-engine + base_unit: mkr + quote_unit: cad + amount_precision: 4 + price_precision: 4 + min_price: 0.1 + max_price: 5000 + min_amount: 0.0001 + position: 19 + state: enabled + data: {} + +- id: solcad + engine_name: peatio-default-engine + base_unit: sol + quote_unit: cad + amount_precision: 4 + price_precision: 6 + min_price: 0.001 + max_price: 100 + min_amount: 0.001 + position: 20 + state: enabled + data: {} + +# USDT Market------------------------------------------ +- id: btcusdt + engine_name: peatio-default-engine + base_unit: btc + quote_unit: usdt + amount_precision: 6 + price_precision: 4 + min_price: 1000 + max_price: 200000 + min_amount: 0.0001 + position: 21 + state: enabled + data: {} + +- id: ethusdt + engine_name: peatio-default-engine + base_unit: eth + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 100 + max_price: 20000 + min_amount: 0.0001 + position: 22 + state: enabled + data: {} + +- id: etcusdt + engine_name: peatio-default-engine + base_unit: etc + quote_unit: usdt + amount_precision: 4 + price_precision: 4 + min_price: 1 + max_price: 500 + min_amount: 0.001 + position: 23 + state: enabled + data: {} + +- id: shibusdt + engine_name: peatio-default-engine + base_unit: shib + quote_unit: usdt + amount_precision: 0 + price_precision: 6 + min_price: 0.000001 + max_price: 10 + min_amount: 1 + position: 24 + state: enabled + data: {} + +- id: bchusdt + engine_name: peatio-default-engine + base_unit: bch + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 0.1 + max_price: 5000 + min_amount: 0.001 + position: 25 + state: enabled + data: {} + +- id: ltcusdt + engine_name: peatio-default-engine + base_unit: ltc + quote_unit: usdt + amount_precision: 6 + price_precision: 4 + min_price: 0.1 + max_price: 5000 + min_amount: 0.0001 + position: 26 + state: enabled + data: {} + +- id: adausdt + engine_name: peatio-default-engine + base_unit: ada + quote_unit: usdt + amount_precision: 3 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 27 + state: enabled + data: {} + +- id: bnbusdt + engine_name: peatio-default-engine + base_unit: bnb + quote_unit: usdt + amount_precision: 4 + price_precision: 3 + min_price: 1 + max_price: 5000 + min_amount: 0.01 + position: 28 + state: enabled + data: {} + +- id: xlmusdt + engine_name: peatio-default-engine + base_unit: xlm + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 29 + state: enabled + data: {} + +- id: xrpusdt + engine_name: peatio-default-engine + base_unit: xrp + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 30 + state: enabled + data: {} + +- id: trxusdt + engine_name: peatio-default-engine + base_unit: trx + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 31 + state: enabled + data: {} + +- id: dogeusdt + engine_name: peatio-default-engine + base_unit: doge + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 1 + position: 32 + state: enabled + data: {} + +- id: uniusdt + engine_name: peatio-default-engine + base_unit: uni + quote_unit: usdt + amount_precision: 4 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.001 + position: 33 + state: enabled + data: {} + +- id: linkusdt + engine_name: peatio-default-engine + base_unit: link + quote_unit: usdt + amount_precision: 4 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.001 + position: 34 + state: enabled + data: {} + +- id: dotusdt + engine_name: peatio-default-engine + base_unit: dot + quote_unit: usdt + amount_precision: 3 + price_precision: 4 + min_price: 0.001 + max_price: 100 + min_amount: 0.1 + position: 35 + state: enabled + data: {} + +- id: aaveusdt + engine_name: peatio-default-engine + base_unit: aave + quote_unit: usdt + amount_precision: 4 + price_precision: 6 + min_price: 0.1 + max_price: 5000 + min_amount: 0.0001 + position: 36 + state: enabled + data: {} + +- id: maticusdt + engine_name: peatio-default-engine + base_unit: matic + quote_unit: usdt + amount_precision: 3 + price_precision: 4 + min_price: 0.001 + max_price: 100 + min_amount: 1 + position: 37 + state: enabled + data: {} + +- id: mkrusdt + engine_name: peatio-default-engine + base_unit: mkr + quote_unit: usdt + amount_precision: 4 + price_precision: 4 + min_price: 0.1 + max_price: 5000 + min_amount: 0.001 + position: 38 + state: enabled + data: {} + +- id: solusdt + engine_name: peatio-default-engine + base_unit: sol + quote_unit: usdt + amount_precision: 4 + price_precision: 6 + min_price: 0.0001 + max_price: 100 + min_amount: 0.001 + position: 39 + state: enabled + data: {} + + diff --git a/config/secrets/.gitkeep b/config/secrets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/test_users.yml b/config/test_users.yml new file mode 100644 index 0000000..b28ec7b --- /dev/null +++ b/config/test_users.yml @@ -0,0 +1,43 @@ +# Test users for local / test environments (see bin/seed_test_users.rb) +# Password for all: 123qwe!@#QWE + +remove_emails: + - admin@fibitex.com + - admin@barong.io + - john@barong.io + +users: + - email: user@test.com + uid: TST0001USER + password: "123qwe!@#QWE" + role: member + state: active + level: 0 + kyc: zero + peatio_group: vip-0 + fiat_balance: 20000 + coin_multiplier: 2 + + - email: bot@test.com + uid: TST0002BOT + password: "123qwe!@#QWE" + role: member + state: active + level: 3 + kyc: full + peatio_group: bot + fiat_balance: 20000000 + coin_multiplier: 1000000 + coin_fixed: + usdt: 20000000 + + - email: admin@test.com + uid: TST0003ADMIN + password: "123qwe!@#QWE" + role: superadmin + state: active + level: 3 + kyc: full + peatio_group: vip-0 + fiat_balance: 2000 + coin_multiplier: 10 diff --git a/config/utils.yml b/config/utils.yml new file mode 100644 index 0000000..e0445ca --- /dev/null +++ b/config/utils.yml @@ -0,0 +1,178 @@ +images: + applogic: rubykube/applogic:latest + arke: custom/arke:3 #quay.io/openware/arke:2.6.0-bccb72c + superset: amancevice/superset:0.28.1 +superset: + email: yaser@fibitex.com + username: yaser + password: changeme +arke: + log_level: WARN # Level of Arke log info + + accounts: + #---------------------------{source}----------------------------------- + - id: bitfinex_source # Unique account id of the source + driver: bitfinex # One of supported sources drivers + delay: 1 # Delay of balance information update + key: "" # API key from source (not required for copy strategy) + secret: "" # Secret from API key from source (not required for copy strategy) + + #---------------------------{source}----------------------------------- + - id: binance_source # Unique account id of the source + driver: binance # One of supported sources drivers + delay: 1 # Delay of balance information update + key: "" # API key from source (not required for copy strategy) + secret: "" # Secret from API key from source (not required for copy strategy) + + #---------------------------{target}----------------------------------- + - id: opendax_target # Unique account id of the target + driver: opendax # Only supported target driver + key: "b1068c9c54fa2035" # API key from the target, required + secret: "6048b9c7668ea7ea0107a62265674540" # Secret from API key from the target, required + host: "https://www.tibitex.com" # Your target URL + ws: "wss://www.tibitex.com" # Your target WebSocet URL + debug: false + verify_ssl: false + finex: false + + strategies: + #---------------------------{strategy}----------------------------------- + - id: copy-BTCUSD # Name of a strategy + type: copy # Type of the strategy + debug: true # True to see extra Arke logs + enabled: true # True to run this strategy after Arke (re)startgit + period: 90 # Period of order book refresh + params: + spread_bids: 0.0015 # Percentage difference from the best price on buy side + spread_asks: 0.0015 # Percentage difference from the best price on sell side + limit_asks_base: 0.08 # The amount of base currency that will be placed for sale in the order book, if have enough balance + limit_bids_base: 0.08 # The amount of base currency that will be placed for buy in the order book, if have enough balance in quote currency equivalent + max_amount_per_order: 0.014 # Limit amount of base currency per order (the small amount are, the bigger number of orders at the same price will be created) + levels_size: 1 # Minimum price difference between price points + levels_count: 10 # Maximum amount of price points that may be created + side: both # Side, ask, bid or both to apply the strategy on + target: + account_id: opendax_target # Unique account id, from the account section, that will be used as a target (your exchange) + market_id: btctestusdt # Market pair code in lowercase, from your target exchange + sources: + - account_id: binance_source # Unique account id, from the account section, that will be used as a source + market_id: BTCUSDT # Market pair code in uppercase, from you source exchange + + #---------------------------{Microtrades-Market strategy}----------------------------------- + - id: microtrades-BTCUSD # Name of a strategy + type: microtrades-market # Type of the strategy + debug: true # True to see extra Arke logs + enabled: true # True to run this strategy after Arke (re)startgit + period: 10 # Period between micro trades + period_random_delay: 13 # Random delay applied to a period + params: + linked_strategy_id: copy-BTCUSD # Strategy that microtrade links to, to calculate order price + min_amount: 0.000001 # Minimum amount of order + max_amount: 0.00009 # Maximum amount of order + target: + account_id: opendax_target # Unique account id, from the account section, that will be used as a target (your exchange) + market_id: btctestusdt # Market pair code in lowercase, from your target exchange + + # log_level: INFO + # accounts: + # - id: 1 + # driver: bitfaker + # debug: false + # host: "http://www.app.local" + # ws: "ws://www.app.local" + # key: "" + # secret: "" + # delay: 1 + + # - id: 2 + # driver: bitfaker + # host: "api.binance.com" + # key: + # secret: + # delay: 1 + + # strategies: + # - id: 1 + # type: copy + # debug: true + # enabled: true + # period: 10 + # params: + # spread_bids: 0.003 + # spread_asks: 0.003 + # limit_asks_base: 0.05 + # limit_bids_base: 0.05 + # levels_size: 0.25 + # levels_count: 10 + # side: both + # enable_orderback: false + # target: + # account_id: 1 + # market: + # id: BTCUSD + # base: btc + # quote: usd + # base_precision: 2 + # quote_precision: 2 + # min_ask_amount: 1.5 + # min_bid_amount: 1.5 + # sources: + # - account_id: 2 + # market: + # id: BTCUSD + # base: BTC + # quote: USD + # base_precision: 8 + # quote_precision: 8 + # min_order_back_amount: 1.5 + + # - id: 2 + # type: microtrades + # debug: true + # period: 5 + # period_random_delay: 10 + # params: + # linked_strategy_id: 1 + # min_amount: 0.05 + # max_amount: 10 + # min_price: 100 + # max_price: 1000 + # target: + # account_id: 1 + # market: + # id: BTCUSD + # base: btc + # quote: usd + # base_precision: 2 + # quote_precision: 2 + # min_ask_amount: 1.5 + # min_bid_amount: 1.5 + # strategy: + # type: copy + # volume_ratio: 0.1 + # target: + # driver: rubykube + # market: 'FTHUSD' + # host: "http://www.app.local" + # key: "" + # secret: "" + # rate_limit: 1 + # sources: + # - driver: bitfaker + # market: 'tETHUSD' + # host: "api.bitfinex.com" + # key: "" + # secret: "" + # rate_limit: 0.2 + # - driver: bitfinex + # market: 'tETHUSD' + # host: "api.bitfinex.com" + # key: "" + # secret: "" + # rate_limit: 0.2 + # - driver: binance + # market: 'ETHUSDT' + # host: "api.binance.com" + # key: "" + # secret: "" + # rate_limit: 0.2 diff --git a/data/mysql/barong_production.sql b/data/mysql/barong_production.sql new file mode 100644 index 0000000..cf54c67 --- /dev/null +++ b/data/mysql/barong_production.sql @@ -0,0 +1,328 @@ +-- MySQL dump 10.13 Distrib 5.7.24, for Linux (x86_64) +-- +-- Host: db Database: barong_production +-- ------------------------------------------------------ +-- Server version 5.7.24 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `activities` +-- + +DROP TABLE IF EXISTS `activities`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `activities` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) NOT NULL, + `user_ip` varchar(255) NOT NULL, + `user_agent` varchar(255) NOT NULL, + `topic` varchar(255) NOT NULL, + `action` varchar(255) NOT NULL, + `result` varchar(255) NOT NULL, + `data` text, + `created_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `index_activities_on_user_id` (`user_id`) +) ENGINE=InnoDB AUTO_INCREMENT=440 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `activities` +-- + +LOCK TABLES `activities` WRITE; +/*!40000 ALTER TABLE `activities` DISABLE KEYS */; +INSERT INTO `activities` VALUES (1,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:04:28'),(2,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 15:04:44'),(3,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:04'),(4,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:07'),(5,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:07'),(6,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:08'),(7,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:08'),(8,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:14'),(9,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:15'),(10,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:15'),(11,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:17'),(12,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:17'),(13,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:17'),(14,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:17'),(15,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:05:21'),(16,6,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 15:06:15'),(17,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:06:50'),(18,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 15:08:23'),(19,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:08:36'),(20,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 15:09:30'),(21,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 15:10:10'),(22,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:10:14'),(23,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:12:16'),(24,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:15:20'),(25,1,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:17:53'),(26,1,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:17:57'),(27,1,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:17:58'),(28,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:18:33'),(29,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:18:56'),(30,1,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:41:55'),(31,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 15:43:56'),(32,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:44:18'),(33,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login','succeed',NULL,'2019-01-22 15:53:01'),(34,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 15:54:45'),(35,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','request QR code for 2FA','succeed',NULL,'2019-01-22 15:54:46'),(36,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','request QR code for 2FA','succeed',NULL,'2019-01-22 15:55:21'),(37,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','succeed',NULL,'2019-01-22 15:56:35'),(38,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','request QR code for 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 15:56:39'),(39,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 15:56:49'),(40,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','request QR code for 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 15:56:55'),(41,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 15:57:06'),(42,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 15:57:11'),(43,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 15:57:12'),(44,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 15:57:13'),(45,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 15:57:13'),(46,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 15:57:13'),(47,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 15:58:13'),(48,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 15:59:20'),(49,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-22 15:59:34'),(50,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 15:59:36'),(51,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-22 16:01:04'),(52,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:01:08'),(53,1,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 16:01:19'),(54,1,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:01:23'),(55,1,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-22 16:01:30'),(56,6,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 16:02:19'),(57,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:02:27'),(58,2,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 16:02:37'),(59,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:02:49'),(60,2,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','otp','request QR code for 2FA','succeed',NULL,'2019-01-22 16:02:59'),(61,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:03:09'),(62,2,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','otp','enable 2FA','succeed',NULL,'2019-01-22 16:03:38'),(63,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:03:55'),(64,2,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:03:57'),(65,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:01'),(66,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:01'),(67,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:04:01'),(68,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:02'),(69,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:02'),(70,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:02'),(71,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:02'),(72,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:02'),(73,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:03'),(74,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:03'),(75,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:04'),(76,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:05'),(77,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:05'),(78,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:05'),(79,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:05'),(80,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:05'),(81,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:05'),(82,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:06'),(83,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:06'),(84,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:06'),(85,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:06'),(86,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:06'),(87,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:06'),(88,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:06'),(89,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:06'),(90,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:06'),(91,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:06'),(92,2,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 16:04:07'),(93,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:07'),(94,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:07'),(95,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:07'),(96,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:07'),(97,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:07'),(98,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:07'),(99,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:07'),(100,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:08'),(101,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:08'),(102,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:08'),(103,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:08'),(104,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:08'),(105,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:08'),(106,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:08'),(107,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:09'),(108,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:09'),(109,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:09'),(110,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:09'),(111,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:09'),(112,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:09'),(113,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:09'),(114,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:10'),(115,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:10'),(116,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:11'),(117,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:12'),(118,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:12'),(119,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:12'),(120,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:12'),(121,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:13'),(122,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:13'),(123,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:13'),(124,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:13'),(125,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:14'),(126,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:14'),(127,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:14'),(128,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:14'),(129,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:14'),(130,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:14'),(131,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:14'),(132,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-22 16:04:16'),(133,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:22'),(134,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:22'),(135,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:23'),(136,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:23'),(137,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:23'),(138,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:23'),(139,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:24'),(140,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:24'),(141,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:24'),(142,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:24'),(143,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:24'),(144,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:25'),(145,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:25'),(146,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:25'),(147,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:25'),(148,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:26'),(149,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:26'),(150,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:27'),(151,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:27'),(152,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:27'),(153,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:27'),(154,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:28'),(155,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:29'),(156,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:29'),(157,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:29'),(158,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:29'),(159,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-22 16:04:30'),(160,2,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:34'),(161,2,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-22 16:04:42'),(162,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:57'),(163,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:57'),(164,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:58'),(165,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:58'),(166,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:58'),(167,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:59'),(168,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:59'),(169,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:04:59'),(170,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:05:03'),(171,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:05:05'),(172,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:05:05'),(173,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:05:05'),(174,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:05:05'),(175,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:05:06'),(176,2,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:05:08'),(177,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-22 16:05:12'),(178,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:05:18'),(179,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','otp','enable 2FA','failed','{\"reason\":\"2FA has been already enabled for this account\"}','2019-01-22 16:05:20'),(180,2,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-22 16:05:39'),(181,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-22 16:05:42'),(182,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:05:51'),(183,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-22 16:06:02'),(184,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:06:08'),(185,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-22 16:06:35'),(186,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-22 16:06:43'),(187,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-22 16:07:04'),(188,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:09:05'),(189,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-22 16:09:14'),(190,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:09:34'),(191,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:10:10'),(192,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:11:41'),(193,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:11:59'),(194,2,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:12:22'),(195,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 16:13:29'),(196,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:13:36'),(197,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:13:41'),(198,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:14:48'),(199,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-22 16:15:13'),(200,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login','succeed',NULL,'2019-01-22 16:15:41'),(201,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login','succeed',NULL,'2019-01-22 16:15:45'),(202,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:17:15'),(203,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:17:26'),(204,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-22 16:17:42'),(205,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-22 16:18:10'),(206,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 16:18:10'),(207,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:18:22'),(208,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 16:18:55'),(209,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:19:08'),(210,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:20:31'),(211,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-22 16:20:40'),(212,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:32:56'),(213,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:32:58'),(214,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:34:16'),(215,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 16:36:28'),(216,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 17:08:15'),(217,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-22 17:08:19'),(218,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 17:11:30'),(219,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 17:36:20'),(220,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login','succeed',NULL,'2019-01-22 17:36:35'),(221,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 17:36:58'),(222,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 17:37:00'),(223,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 17:43:59'),(224,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-22 18:00:46'),(225,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 18:03:45'),(226,1,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 18:08:53'),(227,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 18:13:51'),(228,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-22 18:14:07'),(229,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 18:19:24'),(230,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 18:20:38'),(231,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 18:25:51'),(232,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 18:26:08'),(233,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 18:36:11'),(234,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 18:36:37'),(235,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-22 18:37:02'),(236,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-22 18:37:21'),(237,8,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-22 18:37:36'),(238,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-22 18:37:50'),(239,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 18:39:39'),(240,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-22 18:39:59'),(241,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 18:45:21'),(242,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 18:46:56'),(243,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 18:54:45'),(244,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 19:18:55'),(245,1,'93.73.173.111','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 19:19:19'),(246,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 19:27:42'),(247,1,'93.73.173.111','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 19:28:48'),(248,1,'93.73.173.111','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 19:29:04'),(249,1,'93.73.173.111','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 19:31:35'),(250,8,'93.73.173.111','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 19:37:51'),(251,8,'93.73.173.111','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 19:43:15'),(252,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 19:50:03'),(253,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 19:57:08'),(254,1,'46.219.221.200','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 20:09:04'),(255,1,'46.219.221.200','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 20:09:36'),(256,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 20:10:16'),(257,1,'46.219.221.200','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 20:11:27'),(258,1,'46.219.221.200','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 20:11:37'),(259,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 20:16:27'),(260,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 20:18:26'),(261,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 20:20:25'),(262,1,'46.219.221.200','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 20:26:40'),(263,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 20:31:12'),(264,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 20:31:52'),(265,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 20:37:12'),(266,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 20:40:01'),(267,1,'93.73.173.111','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 20:54:36'),(268,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 20:54:42'),(269,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 21:10:16'),(270,7,'31.43.56.7','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 21:30:42'),(271,1,'46.219.221.200','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-22 22:34:50'),(272,1,'46.219.221.200','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-22 22:35:17'),(273,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 06:45:53'),(274,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 06:48:50'),(275,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 06:49:16'),(276,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 06:53:03'),(277,8,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 06:55:01'),(278,8,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 06:56:18'),(279,5,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 07:02:02'),(280,5,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 07:17:51'),(281,8,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 07:18:26'),(282,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 07:19:58'),(283,8,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 07:30:50'),(284,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 07:31:07'),(285,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 07:47:28'),(286,5,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 07:48:53'),(287,5,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 07:56:09'),(288,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 08:02:23'),(289,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 08:09:08'),(290,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-23 08:09:14'),(291,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 08:10:31'),(292,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-23 08:10:48'),(293,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 08:12:00'),(294,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-23 08:13:19'),(295,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 08:19:10'),(296,10,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:21:42'),(297,10,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:21:43'),(298,10,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:21:43'),(299,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 08:32:11'),(300,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 08:37:08'),(301,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 08:39:43'),(302,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 08:41:19'),(303,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 08:41:28'),(304,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 08:41:34'),(305,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:41:41'),(306,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:41:42'),(307,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:41:42'),(308,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:41:42'),(309,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:41:43'),(310,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:41:43'),(311,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:41:44'),(312,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:41:44'),(313,3,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 08:41:44'),(314,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 08:42:02'),(315,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 08:42:42'),(316,1,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 08:44:02'),(317,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','otp','request QR code for 2FA','succeed',NULL,'2019-01-23 08:45:42'),(318,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','otp','enable 2FA','succeed',NULL,'2019-01-23 08:46:00'),(319,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 08:48:46'),(320,5,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 08:48:57'),(321,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 08:51:02'),(322,5,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 08:52:13'),(323,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 08:52:19'),(324,1,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','logout','succeed',NULL,'2019-01-23 08:55:56'),(325,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 08:56:08'),(326,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 08:56:10'),(327,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 08:56:38'),(328,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 08:56:39'),(329,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:10:24'),(330,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:21:12'),(331,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:21:12'),(332,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:21:12'),(333,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:21:12'),(334,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:21:13'),(335,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:21:13'),(336,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:21:18'),(337,8,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:23:03'),(338,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 09:25:03'),(339,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 09:25:46'),(340,8,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 09:34:17'),(341,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:34:24'),(342,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 09:35:37'),(343,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 09:36:29'),(344,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:37:41'),(345,17,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 09:43:42'),(346,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 09:53:11'),(347,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','login','succeed',NULL,'2019-01-23 10:01:24'),(348,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0','session','login','succeed',NULL,'2019-01-23 10:04:12'),(349,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 10:04:50'),(350,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 10:06:58'),(351,1,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 10:07:06'),(352,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 10:11:10'),(353,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 10:11:50'),(354,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login','succeed',NULL,'2019-01-23 10:11:55'),(355,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 10:11:55'),(356,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 10:11:56'),(357,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 10:14:16'),(358,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 10:14:46'),(359,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 10:20:46'),(360,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','logout','succeed',NULL,'2019-01-23 10:23:00'),(361,1,'82.124.184.177','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 10:23:35'),(362,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 10:28:32'),(363,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 10:28:48'),(364,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Cypress/3.1.4 Chrome/59.0.3071.115 Electron/1.8.2 Safari/537.36','session','login::2fa','failed','{\"reason\":\"OTP code is invalid\"}','2019-01-23 10:29:40'),(365,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 10:34:38'),(366,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 10:35:16'),(367,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 10:42:15'),(368,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 10:42:30'),(369,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 10:42:32'),(370,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36','session','login','succeed',NULL,'2019-01-23 10:49:57'),(371,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 10:55:18'),(372,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 10:57:14'),(373,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 11:05:27'),(374,4,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login','succeed',NULL,'2019-01-23 11:07:14'),(375,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 11:08:03'),(376,18,'188.130.178.81','Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 11:10:55'),(377,18,'188.130.178.81','Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0','session','login','failed','{\"reason\":\"Your account is not active\"}','2019-01-23 11:11:44'),(378,4,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 11:12:36'),(379,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','logout','succeed',NULL,'2019-01-23 11:16:48'),(380,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 11:17:28'),(381,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','otp','request QR code for 2FA','succeed',NULL,'2019-01-23 11:17:48'),(382,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','otp','enable 2FA','succeed',NULL,'2019-01-23 11:18:13'),(383,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 11:18:17'),(384,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 11:18:25'),(385,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-23 11:18:40'),(386,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 11:18:56'),(387,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','succeed',NULL,'2019-01-23 11:19:05'),(388,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 11:19:25'),(389,8,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 11:20:18'),(390,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 11:20:58'),(391,8,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 11:24:18'),(392,8,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 11:25:38'),(393,8,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 11:30:54'),(394,8,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 11:31:04'),(395,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 11:38:53'),(396,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 11:44:01'),(397,1,'195.214.197.210','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 11:44:22'),(398,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 11:48:06'),(399,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 11:48:17'),(400,2,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 11:48:56'),(401,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36','session','login::2fa','failed','{\"reason\":\"The account has enabled 2FA but OTP code is missing\"}','2019-01-23 11:50:26'),(402,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 11:50:49'),(403,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 11:52:04'),(404,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 11:52:15'),(405,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36','session','login','succeed',NULL,'2019-01-23 11:52:23'),(406,14,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 11:53:11'),(407,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 11:58:22'),(408,14,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 11:59:40'),(409,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 12:08:49'),(410,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','login','succeed',NULL,'2019-01-23 12:21:16'),(411,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 12:27:08'),(412,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 12:38:44'),(413,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 12:39:19'),(414,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36','session','login','succeed',NULL,'2019-01-23 12:41:36'),(415,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','logout','succeed',NULL,'2019-01-23 12:46:51'),(416,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 12:49:13'),(417,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36','session','login','succeed',NULL,'2019-01-23 12:49:15'),(418,1,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 12:54:35'),(419,1,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 13:14:30'),(420,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','login','succeed',NULL,'2019-01-23 13:36:09'),(421,1,'195.214.197.210','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 13:37:43'),(422,1,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 13:41:15'),(423,1,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','logout','succeed',NULL,'2019-01-23 13:48:53'),(424,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 13:49:24'),(425,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','logout','succeed',NULL,'2019-01-23 13:50:54'),(426,7,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 13:51:09'),(427,8,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36','session','login','succeed',NULL,'2019-01-23 13:52:13'),(428,7,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 13:52:24'),(429,4,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login','succeed',NULL,'2019-01-23 13:54:21'),(430,4,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 14:00:10'),(431,7,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','logout','succeed',NULL,'2019-01-23 14:05:26'),(432,8,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36','session','logout','succeed',NULL,'2019-01-23 14:05:30'),(433,1,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 14:13:19'),(434,4,'195.214.197.210','Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36','session','login','succeed',NULL,'2019-01-23 14:15:54'),(435,1,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','logout','succeed',NULL,'2019-01-23 14:19:58'),(436,1,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 14:26:28'),(437,1,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','logout','succeed',NULL,'2019-01-23 14:26:34'),(438,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','login','succeed',NULL,'2019-01-23 14:27:11'),(439,8,'195.214.197.210','Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0','session','logout','succeed',NULL,'2019-01-23 14:36:46'); +/*!40000 ALTER TABLE `activities` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `apikeys` +-- + +DROP TABLE IF EXISTS `apikeys`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `apikeys` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL, + `kid` varchar(255) NOT NULL, + `algorithm` varchar(255) NOT NULL, + `scope` varchar(255) DEFAULT NULL, + `state` varchar(255) NOT NULL DEFAULT 'active', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_apikeys_on_user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `apikeys` +-- + +LOCK TABLES `apikeys` WRITE; +/*!40000 ALTER TABLE `apikeys` DISABLE KEYS */; +/*!40000 ALTER TABLE `apikeys` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `ar_internal_metadata` +-- + +DROP TABLE IF EXISTS `ar_internal_metadata`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `ar_internal_metadata` ( + `key` varchar(255) NOT NULL, + `value` varchar(255) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `ar_internal_metadata` +-- + +LOCK TABLES `ar_internal_metadata` WRITE; +/*!40000 ALTER TABLE `ar_internal_metadata` DISABLE KEYS */; +INSERT INTO `ar_internal_metadata` VALUES ('environment','production','2019-01-22 14:57:40','2019-01-31 17:57:54'); +/*!40000 ALTER TABLE `ar_internal_metadata` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `documents` +-- + +DROP TABLE IF EXISTS `documents`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `documents` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL, + `upload` varchar(255) DEFAULT NULL, + `doc_type` varchar(255) DEFAULT NULL, + `doc_number` varchar(255) DEFAULT NULL, + `doc_expire` date DEFAULT NULL, + `metadata` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_documents_on_user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `documents` +-- + +LOCK TABLES `documents` WRITE; +/*!40000 ALTER TABLE `documents` DISABLE KEYS */; +/*!40000 ALTER TABLE `documents` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `labels` +-- + +DROP TABLE IF EXISTS `labels`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `labels` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) unsigned NOT NULL, + `key` varchar(255) NOT NULL, + `value` varchar(255) NOT NULL, + `scope` varchar(255) NOT NULL DEFAULT 'public', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_labels_on_user_id_and_key_and_scope` (`user_id`,`key`,`scope`), + KEY `index_labels_on_user_id` (`user_id`) +) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `labels` +-- + +LOCK TABLES `labels` WRITE; +/*!40000 ALTER TABLE `labels` DISABLE KEYS */; +INSERT INTO `labels` VALUES (1,1,'email','verified','private','2019-01-22 14:57:44','2019-01-22 14:57:44'),(2,1,'phone','verified','private','2019-01-22 14:57:44','2019-01-22 14:57:44'),(3,1,'document','verified','private','2019-01-22 14:57:45','2019-01-22 14:57:45'),(4,2,'email','verified','private','2019-01-22 14:57:45','2019-01-22 14:57:45'),(5,2,'phone','verified','private','2019-01-22 14:57:45','2019-01-22 14:57:45'),(6,2,'document','verified','private','2019-01-22 14:57:46','2019-01-22 14:57:46'),(7,4,'email','verified','private','2019-01-22 14:57:46','2019-01-22 14:57:46'),(8,5,'email','verified','private','2019-01-22 14:57:46','2019-01-22 14:57:46'),(9,5,'phone','verified','private','2019-01-22 14:57:47','2019-01-22 14:57:47'),(10,6,'email','verified','private','2019-01-22 14:57:47','2019-01-22 14:57:47'),(11,6,'phone','verified','private','2019-01-22 14:57:47','2019-01-22 14:57:47'),(12,6,'document','verified','private','2019-01-22 14:57:47','2019-01-22 14:57:47'),(14,7,'phone','verified','private','2019-01-22 14:57:47','2019-01-22 14:57:47'),(15,7,'document','verified','private','2019-01-22 14:57:47','2019-01-22 14:57:47'),(16,8,'email','verified','private','2019-01-22 14:57:48','2019-01-22 14:57:48'),(17,8,'phone','verified','private','2019-01-22 14:57:48','2019-01-22 14:57:48'),(18,8,'document','verified','private','2019-01-22 14:57:48','2019-01-22 14:57:48'),(20,3,'email','verified','private','2019-01-23 08:41:13','2019-01-23 08:41:13'),(21,5,'document','verified','private','2019-01-23 08:46:49','2019-01-23 08:46:49'),(22,17,'phone','verified','public','2019-01-23 09:44:36','2019-01-23 09:44:36'),(23,17,'email','verified','private','2019-01-23 09:45:10','2019-01-23 09:45:10'),(24,17,'document','verified','private','2019-01-23 09:45:34','2019-01-23 09:45:34'),(26,9,'email','verified','private','2019-01-23 10:08:56','2019-01-23 10:08:56'),(27,9,'phone','verified','private','2019-01-23 10:09:17','2019-01-23 10:09:17'),(28,9,'document','verified','private','2019-01-23 10:09:47','2019-01-23 10:09:47'),(29,4,'phone','verified','private','2019-01-23 12:13:16','2019-01-23 12:13:16'); +/*!40000 ALTER TABLE `labels` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `levels` +-- + +DROP TABLE IF EXISTS `levels`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `levels` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `key` varchar(255) NOT NULL, + `value` varchar(255) DEFAULT NULL, + `description` varchar(255) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `levels` +-- + +LOCK TABLES `levels` WRITE; +/*!40000 ALTER TABLE `levels` DISABLE KEYS */; +INSERT INTO `levels` VALUES (1,'email','verified','User clicked on the confirmation link','2019-01-22 14:57:41','2019-01-22 14:57:41'),(2,'phone','verified','User entered a valid code from sms','2019-01-22 14:57:41','2019-01-22 14:57:41'),(3,'document','verified','User personal documents have been verified','2019-01-22 14:57:41','2019-01-22 14:57:41'); +/*!40000 ALTER TABLE `levels` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `phones` +-- + +DROP TABLE IF EXISTS `phones`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `phones` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `user_id` int(10) unsigned NOT NULL, + `country` varchar(255) NOT NULL, + `number` varchar(255) NOT NULL, + `code` varchar(5) DEFAULT NULL, + `validated_at` datetime DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_phones_on_number` (`number`), + KEY `index_phones_on_user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `phones` +-- + +LOCK TABLES `phones` WRITE; +/*!40000 ALTER TABLE `phones` DISABLE KEYS */; +/*!40000 ALTER TABLE `phones` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `profiles` +-- + +DROP TABLE IF EXISTS `profiles`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `profiles` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `user_id` bigint(20) DEFAULT NULL, + `first_name` varchar(255) DEFAULT NULL, + `last_name` varchar(255) DEFAULT NULL, + `dob` date DEFAULT NULL, + `address` varchar(255) DEFAULT NULL, + `postcode` varchar(255) DEFAULT NULL, + `city` varchar(255) DEFAULT NULL, + `country` varchar(255) DEFAULT NULL, + `metadata` text, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_profiles_on_user_id` (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `profiles` +-- + +LOCK TABLES `profiles` WRITE; +/*!40000 ALTER TABLE `profiles` DISABLE KEYS */; +/*!40000 ALTER TABLE `profiles` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `schema_migrations` +-- + +DROP TABLE IF EXISTS `schema_migrations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `schema_migrations` ( + `version` varchar(255) NOT NULL, + PRIMARY KEY (`version`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `schema_migrations` +-- + +LOCK TABLES `schema_migrations` WRITE; +/*!40000 ALTER TABLE `schema_migrations` DISABLE KEYS */; +INSERT INTO `schema_migrations` VALUES ('20181101143041'),('20181115100105'),('20190108115333'); +/*!40000 ALTER TABLE `schema_migrations` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `users` +-- + +DROP TABLE IF EXISTS `users`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `users` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `uid` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `password_digest` varchar(255) NOT NULL, + `role` varchar(255) NOT NULL DEFAULT 'member', + `level` int(11) NOT NULL DEFAULT '0', + `otp` tinyint(1) DEFAULT '0', + `state` varchar(255) NOT NULL DEFAULT 'pending', + `referral_id` bigint(20) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_users_on_email` (`email`), + UNIQUE KEY `index_users_on_uid` (`uid`) +) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `users` +-- + +LOCK TABLES `users` WRITE; +/*!40000 ALTER TABLE `users` DISABLE KEYS */; +INSERT INTO `users` VALUES (1,'ID7CAF88CD33','iron@man.io','$2a$10$Sonzos5G.VrXRW2vAzwPWu.7o47BiOMxd/FXohb7Y7mBj7FMwwOX2','admin',3,0,'active',NULL,'2019-01-22 14:57:41','2019-01-23 11:52:09'),(2,'ID535CA9B575','TestMeHelios+PhillipaRuais@gmail.com','$2a$10$Q7Hd0dYrEs5xJaV5TYOMNOa1KZ0tk3NzgfleLe3I863jcQuiQ6M1.','admin',3,1,'active',NULL,'2019-01-22 14:57:45','2019-01-23 08:46:00'),(3,'IDBA8F4E58B9','TestMeHelios+AntoinePelletier@gmail.com','$2a$10$eZnOwFoyiElkIXII6VPhDuPiJGhRVeLdgC9CC18A4QxdsZm0MQJ02','member',1,0,'pending',NULL,'2019-01-22 14:57:46','2019-01-23 08:40:39'),(4,'ID1799AE7C6F','TestMeHelios+CecileVaillancourt@gmail.com','$2a$10$I6rWbfd3M6YCIG77A.zlJOpluUIV10.mmQwMHJGJLeswkst2bc5t2','member',2,0,'active',NULL,'2019-01-22 14:57:46','2019-01-23 12:13:16'),(5,'ID8CB21CC3A3','TestMeHelios+CharmaineOuellet@gmail.com','$2a$10$3TW0TWTAtvTnLbOX/7/A/u3ZhdPZYNJet0hFPpx1LsHLG7TQ4.tL6','member',3,0,'active',NULL,'2019-01-22 14:57:46','2019-01-23 08:46:49'),(6,'IDF18F8B5E89','TestMeHelios+RamonLMcCourt@gmail.com','$2a$10$6faQ09HTyk1k55QUsx0zu.otKmmMtWUmTB.4qKU4uCY5D6b9bX3MK','member',3,0,'banned',NULL,'2019-01-22 14:57:47','2019-01-22 14:57:47'),(7,'ID79BF61C8A0','TestMeHelios+AmyJBriggs@gmail.com','$2a$10$AFtfR9pGt0ITbxLOfflkI.nhijURh363wKK6ug8mwzQ2LApiFgy8K','member',3,0,'active',NULL,'2019-01-22 14:57:47','2019-01-22 14:57:47'),(8,'ID6FC9E9F399','TestMeHelios+DavidTMoore@gmail.com','$2a$10$wMzT6zS65EK/mwhV604B/Oe7b1oOtyzBsz2mRUwp5nGNxGGwfiQ4m','member',3,0,'active',NULL,'2019-01-22 14:57:48','2019-01-22 14:57:48'),(9,'IDC9DA23294E','alinetskyi@heliostech.fr','$2a$10$2eZ9m9pPCIdIcjgDOHs.qu2C4QNmxcuA9NUr71cFeyZ.jf1wTtACq','member',3,0,'pending',NULL,'2019-01-23 08:18:09','2019-01-23 10:09:47'),(10,'IDE897F251A9','alinetskyi+test@heliostech.fr','$2a$10$RHuofUq3B290qpG7.g.pVeBpvg8ZsjtpexMgiZyV3NK2pXfYNpp/K','member',0,0,'pending',NULL,'2019-01-23 08:21:16','2019-01-23 08:21:16'),(11,'IDBCA5517FBA','alinetskyi+kek@heliostech.fr','$2a$10$AVCHCl8nltvQEo2OFC9lC.w2dKjTQnKFfLKGx6.mcU5yuGvgd1wVK','member',0,0,'pending',NULL,'2019-01-23 08:26:06','2019-01-23 08:26:06'),(12,'ID04A3A9C8AA','artem.linetskiy@gmail.com','$2a$10$O3hExABJrhxaPbCcayo3H.kOuzqQBlxvvDEkEc7TsPUZ.iI47YR.e','member',0,0,'pending',NULL,'2019-01-23 08:26:43','2019-01-23 08:26:43'),(13,'IDEB048F34E1','koliadych@gmail.com','$2a$10$OyK9fUMw7WbAians4eKkzeDLzDRCljA.iCc2OzhLBQEnq3F7k5XzO','member',0,0,'pending',NULL,'2019-01-23 08:28:55','2019-01-23 08:28:55'),(14,'ID7E9639E27F','admin@devkube.com','$2a$10$2TOdJDVvjM5h5QEsrPy0ye5XxFZfy9n/pwY8ofBJhegScn25LFkiu','admin',3,0,'active',NULL,'2019-01-23 09:35:48','2019-01-23 09:37:34'),(15,'ID6846714A89','rdyadenko@heliostech.fr','$2a$10$lm6kS6.4./goW4DQvcNtZusVE93VedRkVlqasKkf4Dfs4joTYYCE6','member',0,0,'pending',NULL,'2019-01-23 09:37:36','2019-01-23 09:37:36'),(16,'ID2F8E2AF176','user@devkube.com','$2a$10$AHSwZlp/3v8u2akKgXw4N.bjYkF4W59s1SLaSHk7mVOHdK5GrUrwm','member',1,0,'active',NULL,'2019-01-23 09:39:08','2019-01-23 09:39:39'),(17,'IDE08425FBA5','okoliadych+kik@heliostech.fr','$2a$10$7kDT2C0FFCZ4W5qgyh2UietG05e4Eh68JcN/B0SIyt5nComGw2NDa','member',1,0,'pending',NULL,'2019-01-23 09:40:09','2019-01-23 09:45:10'),(18,'IDB160F1B776','cgenchevsky@heliostech.fr','$2a$10$O4v2xaRDDlQuqKtcz15gRucSck5cgXuAHDTmpyfdKComusp1yFed.','member',0,0,'pending',NULL,'2019-01-23 11:05:25','2019-01-23 11:05:25'); +/*!40000 ALTER TABLE `users` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2019-01-31 17:58:52 diff --git a/data/mysql/peatio_production.sql b/data/mysql/peatio_production.sql new file mode 100644 index 0000000..615c24d --- /dev/null +++ b/data/mysql/peatio_production.sql @@ -0,0 +1,674 @@ +-- MySQL dump 10.13 Distrib 5.7.24, for Linux (x86_64) +-- +-- Host: db Database: peatio_production +-- ------------------------------------------------------ +-- Server version 5.7.24 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `accounts` +-- + +DROP TABLE IF EXISTS `accounts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `accounts` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `member_id` int(11) NOT NULL, + `currency_id` varchar(10) NOT NULL, + `balance` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `locked` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_accounts_on_currency_id_and_member_id` (`currency_id`,`member_id`), + KEY `index_accounts_on_member_id` (`member_id`) USING BTREE +) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `accounts` +-- + +LOCK TABLES `accounts` WRITE; +/*!40000 ALTER TABLE `accounts` DISABLE KEYS */; +INSERT INTO `accounts` VALUES (1,1,'eth',0.4161118508655127,0.0000000000000000,'2019-01-22 15:23:10','2019-01-22 15:23:10'),(3,1,'trst',0.0000000000000000,0.0000000000000000,'2019-01-22 15:23:10','2019-01-22 15:23:10'),(4,1,'usd',0.0000000000000000,0.0000000000000000,'2019-01-22 15:23:10','2019-01-22 15:23:10'),(5,2,'eth',0.0000000000000000,0.0000000000000000,'2019-01-22 15:44:19','2019-01-22 15:44:19'),(6,2,'kyn',0.0000000000000000,0.0000000000000000,'2019-01-22 15:44:19','2019-01-22 15:44:19'),(7,2,'trst',0.0000000000000000,0.0000000000000000,'2019-01-22 15:44:19','2019-01-22 15:44:19'),(8,2,'usd',10000.0000000000000000,0.0000000000000000,'2019-01-22 15:44:19','2019-01-22 15:44:19'),(9,3,'eth',2.4187850000000000,1.7000000000000000,'2019-01-22 18:03:46','2019-01-22 18:03:46'),(10,3,'kyn',25200.0000000000000000,800.0000000000000000,'2019-01-22 18:03:46','2019-01-22 18:03:46'),(11,3,'trst',0.0000000000000000,0.0000000000000000,'2019-01-22 18:03:46','2019-01-22 18:03:46'),(12,3,'usd',48.7982750000000000,0.0000000000000000,'2019-01-22 18:03:46','2019-01-22 18:03:46'),(13,4,'eth',0.8723200000000000,0.0000000000000000,'2019-01-22 18:37:36','2019-01-22 18:37:36'),(14,4,'kyn',400.0000000000000000,2600.0000000000000000,'2019-01-22 18:37:37','2019-01-22 18:37:37'),(15,4,'trst',0.0000000000000000,0.0000000000000000,'2019-01-22 18:37:37','2019-01-22 18:37:37'),(16,4,'usd',9949.9459850000000000,0.0000000000000000,'2019-01-22 18:37:37','2019-01-22 18:37:37'),(17,5,'eth',0.0000000000000000,0.0000000000000000,'2019-01-23 07:02:02','2019-01-23 07:02:02'),(18,5,'kyn',0.0000000000000000,0.0000000000000000,'2019-01-23 07:02:02','2019-01-23 07:02:02'),(19,5,'trst',0.0000000000000000,0.0000000000000000,'2019-01-23 07:02:02','2019-01-23 07:02:02'),(20,5,'usd',2000.0000000000000000,0.0000000000000000,'2019-01-23 07:02:02','2019-01-23 07:02:02'),(21,6,'eth',0.0000000000000000,0.0000000000000000,'2019-01-23 08:54:39','2019-01-23 08:54:39'),(22,6,'kyn',0.0000000000000000,0.0000000000000000,'2019-01-23 08:54:39','2019-01-23 08:54:39'),(23,6,'trst',0.0000000000000000,0.0000000000000000,'2019-01-23 08:54:39','2019-01-23 08:54:39'),(24,6,'usd',0.0000000000000000,0.0000000000000000,'2019-01-23 08:54:39','2019-01-23 08:54:39'),(25,9,'eth',0.0000000000000000,0.0000000000000000,'2019-01-23 11:07:14','2019-01-23 11:07:14'),(26,9,'kyn',0.0000000000000000,0.0000000000000000,'2019-01-23 11:07:14','2019-01-23 11:07:14'),(27,9,'trst',0.0000000000000000,0.0000000000000000,'2019-01-23 11:07:14','2019-01-23 11:07:14'),(28,9,'usd',0.0000000000000000,0.0000000000000000,'2019-01-23 11:07:14','2019-01-23 11:07:14'),(29,10,'eth',0.0000000000000000,0.0000000000000000,'2019-01-23 11:53:11','2019-01-23 11:53:11'),(30,10,'kyn',0.0000000000000000,0.0000000000000000,'2019-01-23 11:53:11','2019-01-23 11:53:11'),(31,10,'trst',0.0000000000000000,0.0000000000000000,'2019-01-23 11:53:11','2019-01-23 11:53:11'),(32,10,'usd',0.0000000000000000,0.0000000000000000,'2019-01-23 11:53:11','2019-01-23 11:53:11'); +/*!40000 ALTER TABLE `accounts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `assets` +-- + +DROP TABLE IF EXISTS `assets`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `assets` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` int(11) NOT NULL, + `currency_id` varchar(255) NOT NULL, + `reference_id` int(11) DEFAULT NULL, + `reference_type` varchar(255) DEFAULT NULL, + `debit` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `credit` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_assets_on_currency_id` (`currency_id`), + KEY `index_assets_on_reference_type_and_reference_id` (`reference_type`,`reference_id`) +) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `assets` +-- + +LOCK TABLES `assets` WRITE; +/*!40000 ALTER TABLE `assets` DISABLE KEYS */; +INSERT INTO `assets` VALUES (1,102,'eth',1,'Deposit',0.0000000000000000,2.0000000000000000,'2019-01-22 20:25:29','2019-01-22 20:25:29'),(2,102,'kyn',2,'Deposit',0.0000000000000000,1000.0000000000000000,'2019-01-22 21:09:09','2019-01-22 21:09:09'),(3,102,'kyn',3,'Deposit',0.0000000000000000,3000.0000000000000000,'2019-01-23 06:59:00','2019-01-23 06:59:00'),(4,102,'eth',4,'Deposit',0.0000000000000000,1.0000000000000000,'2019-01-23 06:59:32','2019-01-23 06:59:32'),(5,101,'usd',5,'Deposit',0.0000000000000000,10000.0000000000000000,'2019-01-23 07:18:45','2019-01-23 07:18:45'),(6,101,'usd',6,'Deposit',0.0000000000000000,2000.0000000000000000,'2019-01-23 07:18:54','2019-01-23 07:18:54'),(7,101,'usd',7,'Deposit',0.0000000000000000,10000.0000000000000000,'2019-01-23 07:19:00','2019-01-23 07:19:00'),(8,102,'eth',8,'Deposit',0.0000000000000000,0.4161118508655127,'2019-01-23 08:47:25','2019-01-23 08:47:25'),(9,102,'eth',9,'Deposit',0.0000000000000000,1.0000000000000000,'2019-01-23 09:13:34','2019-01-23 09:13:34'),(10,102,'eth',10,'Deposit',0.0000000000000000,1.0000000000000000,'2019-01-23 11:22:47','2019-01-23 11:22:47'),(11,102,'kyn',11,'Deposit',0.0000000000000000,25000.0000000000000000,'2019-01-23 11:24:33','2019-01-23 11:24:33'); +/*!40000 ALTER TABLE `assets` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `blockchains` +-- + +DROP TABLE IF EXISTS `blockchains`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `blockchains` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `key` varchar(255) NOT NULL, + `name` varchar(255) DEFAULT NULL, + `client` varchar(255) NOT NULL, + `server` varchar(255) DEFAULT NULL, + `height` int(11) NOT NULL, + `explorer_address` varchar(255) DEFAULT NULL, + `explorer_transaction` varchar(255) DEFAULT NULL, + `min_confirmations` int(11) NOT NULL DEFAULT '6', + `status` varchar(255) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_blockchains_on_key` (`key`), + KEY `index_blockchains_on_status` (`status`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `blockchains` +-- + +LOCK TABLES `blockchains` WRITE; +/*!40000 ALTER TABLE `blockchains` DISABLE KEYS */; +INSERT INTO `blockchains` VALUES (1,'eth-rinkeby','Ethereum Rinkeby','ethereum','http://parity:8545',3741720,'https://rinkeby.etherscan.io/address/#{address}','https://rinkeby.etherscan.io/tx/#{txid}',6,'active','2019-01-22 15:18:02','2019-01-23 14:47:31'),(2,'eth-mainet','Ethereum Mainet','ethereum','http://parity:8545',5000000,'https://etherscan.io/address/#{address}','https://etherscan.io/tx/#{txid}',6,'disabled','2019-01-22 15:18:02','2019-01-22 15:18:02'); +/*!40000 ALTER TABLE `blockchains` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `currencies` +-- + +DROP TABLE IF EXISTS `currencies`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `currencies` ( + `id` varchar(10) NOT NULL, + `name` varchar(255) DEFAULT NULL, + `blockchain_key` varchar(32) DEFAULT NULL, + `symbol` varchar(1) NOT NULL, + `type` varchar(30) NOT NULL DEFAULT 'coin', + `deposit_fee` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `min_deposit_amount` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `min_collection_amount` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `withdraw_fee` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `min_withdraw_amount` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `withdraw_limit_24h` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `withdraw_limit_72h` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `position` int(11) NOT NULL DEFAULT '0', + `options` varchar(1000) NOT NULL DEFAULT '{}', + `enabled` tinyint(1) NOT NULL DEFAULT '1', + `base_factor` bigint(20) NOT NULL DEFAULT '1', + `precision` tinyint(4) NOT NULL DEFAULT '8', + `icon_url` varchar(255) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_currencies_on_enabled` (`enabled`), + KEY `index_currencies_on_position` (`position`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `currencies` +-- + +LOCK TABLES `currencies` WRITE; +/*!40000 ALTER TABLE `currencies` DISABLE KEYS */; +INSERT INTO `currencies` VALUES ('eth','Ethereum','eth-rinkeby','Ξ','coin',0.0000000000000000,0.0002100000000000,0.0002100000000000,0.0000000000000000,0.0000000000000000,0.2000000000000000,0.5000000000000001,0,'{\"gas_limit\":21000,\"gas_price\":1000000000}',1,1000000000000000000,8,NULL,'2019-01-22 15:18:02','2019-01-22 15:18:02'),('kyn','Kayen','eth-rinkeby','K','coin',0.0000000000000000,0.0002100000000000,0.0002100000000000,0.0000000000000000,0.0000000000000000,300.0000000000000000,600.0000000000000000,0,'{\"erc20_contract_address\":\"0x4ec07a41b94e035336cca74877319d06964ab76d\",\"gas_limit\":90000,\"gas_price\":1000000000}',1,1000000000000000000,8,'','2019-01-22 15:18:03','2019-01-22 21:08:18'),('trst','WeTrust','eth-rinkeby','Ξ','coin',0.0000000000000000,0.0002100000000000,0.0002100000000000,0.0000000000000000,0.0000000000000000,300.0000000000000000,600.0000000000000000,0,'{\"gas_limit\":90000,\"gas_price\":1000000000,\"erc20_contract_address\":\"0x87099add3bcc0821b5b151307c147215f839a110\"}',1,1000000,8,NULL,'2019-01-22 15:18:03','2019-01-22 15:18:03'),('usd','US Dollar','','$','fiat',0.0000000000000000,0.0000000000000000,0.0000000000000000,0.0000000000000000,0.0000000000000000,100.0000000000000000,200.0000000000000000,0,'{\"erc20_contract_address\":\"\",\"gas_limit\":\"\",\"gas_price\":\"\"}',1,1,2,'','2019-01-22 15:18:02','2019-01-23 09:22:49'); +/*!40000 ALTER TABLE `currencies` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `deposits` +-- + +DROP TABLE IF EXISTS `deposits`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `deposits` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `member_id` int(11) NOT NULL, + `currency_id` varchar(10) NOT NULL, + `amount` decimal(32,16) NOT NULL, + `fee` decimal(32,16) NOT NULL, + `address` varchar(95) DEFAULT NULL, + `txid` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, + `txout` int(11) DEFAULT NULL, + `aasm_state` varchar(30) NOT NULL, + `block_number` int(11) DEFAULT NULL, + `type` varchar(30) NOT NULL, + `tid` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `completed_at` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_deposits_on_currency_id_and_txid_and_txout` (`currency_id`,`txid`,`txout`), + KEY `index_deposits_on_currency_id` (`currency_id`), + KEY `index_deposits_on_type` (`type`), + KEY `index_deposits_on_member_id_and_txid` (`member_id`,`txid`), + KEY `index_deposits_on_aasm_state_and_member_id_and_currency_id` (`aasm_state`,`member_id`,`currency_id`), + KEY `index_deposits_on_tid` (`tid`) +) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `deposits` +-- + +LOCK TABLES `deposits` WRITE; +/*!40000 ALTER TABLE `deposits` DISABLE KEYS */; +INSERT INTO `deposits` VALUES (1,3,'eth',2.0000000000000000,0.0000000000000000,'0x9ddacb6dbfb8cb4d0d39cbd5a69cb76d92303edf','0x2f79af1e70faa3ac8c62cb0f51ebaab4f3f7b92a6670f44b9fbecd93c0041ea0',NULL,'collected',3737312,'Deposits::Coin','TID3BB1D5A12A','2019-01-22 20:24:01','2019-01-22 20:25:31','2019-01-22 20:25:29'),(2,3,'kyn',1000.0000000000000000,0.0000000000000000,'0x61922a271c24fab6b1fd8b822e259d883fad39c3','0x91297ed252ea4ed9bd6da97cbbec3def85932b8a8de228f4807ba04ac2ce235a',0,'collected',3737306,'Deposits::Coin','TID49CB347EA3','2019-01-22 21:09:09','2019-01-22 21:54:00','2019-01-22 21:09:09'),(3,4,'kyn',3000.0000000000000000,0.0000000000000000,'0xec151f867b69704e0612c2bdd9c853fb57094a91','0xf66950ed46b8dd369d382fecc852f6a79d200a11a04ef7895e431dd89cec0da8',7,'collected',3739846,'Deposits::Coin','TID49EE3CB297','2019-01-23 06:57:31','2019-01-23 06:59:14','2019-01-23 06:59:00'),(4,3,'eth',1.0000000000000000,0.0000000000000000,'0x9ddacb6dbfb8cb4d0d39cbd5a69cb76d92303edf','0x6bb7a89209be9d4ec5d72672f077b9c2ef5421a97740461ad2e94553861eeed3',NULL,'collected',3739848,'Deposits::Coin','TIDB3E14FE087','2019-01-23 06:58:03','2019-01-23 06:59:39','2019-01-23 06:59:32'),(5,4,'usd',10000.0000000000000000,0.0000000000000000,NULL,NULL,NULL,'accepted',NULL,'Deposits::Fiat','TIDF88FAEA77E','2019-01-23 07:05:09','2019-01-23 07:18:45','2019-01-23 07:18:45'),(6,5,'usd',2000.0000000000000000,0.0000000000000000,NULL,NULL,NULL,'accepted',NULL,'Deposits::Fiat','TID1F8E5872A2','2019-01-23 07:08:07','2019-01-23 07:18:54','2019-01-23 07:18:54'),(7,2,'usd',10000.0000000000000000,0.0000000000000000,NULL,NULL,NULL,'accepted',NULL,'Deposits::Fiat','TID26C362E896','2019-01-23 07:08:47','2019-01-23 07:19:00','2019-01-23 07:19:00'),(8,1,'eth',0.4161118508655127,0.0000000000000000,'0xe40666e5297b20ed002c94a65f59f36ec2942608','0xa00682b165a4fcc3844121f56c0b03995d8b8ab11c07b71a35bd92654a51cbc1',NULL,'accepted',3740282,'Deposits::Coin','TIDF7F6FBEF4D','2019-01-23 08:46:32','2019-01-23 08:47:25','2019-01-23 08:47:25'),(9,3,'eth',1.0000000000000000,0.0000000000000000,'0x9ddacb6dbfb8cb4d0d39cbd5a69cb76d92303edf','0xe7b18a75e5eb1a6fd3416251e44383b2918d23968762f3dec90ba238a6d2a153',NULL,'collected',3740384,'Deposits::Coin','TID9B224980D2','2019-01-23 09:12:00','2019-01-23 09:13:35','2019-01-23 09:13:34'),(10,3,'eth',1.0000000000000000,0.0000000000000000,'0x9ddacb6dbfb8cb4d0d39cbd5a69cb76d92303edf','0x5eae760a5b33a6c640e1e8092bf408a2e059b9b4ad4c726bf90ea341ae8b732d',NULL,'collected',3740901,'Deposits::Coin','TIDB877B4BDDA','2019-01-23 11:21:17','2019-01-23 11:22:48','2019-01-23 11:22:47'),(11,3,'kyn',25000.0000000000000000,0.0000000000000000,'0x61922a271c24fab6b1fd8b822e259d883fad39c3','0xa27e1f372ece5d4ddb5ef9f89319104abc7a5a61ff639ba6f942d52aebf4a448',0,'collected',3740908,'Deposits::Coin','TIDCDDB6247D0','2019-01-23 11:23:03','2019-01-23 11:24:36','2019-01-23 11:24:33'); +/*!40000 ALTER TABLE `deposits` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `expenses` +-- + +DROP TABLE IF EXISTS `expenses`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `expenses` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` int(11) NOT NULL, + `currency_id` varchar(255) NOT NULL, + `reference_id` int(11) DEFAULT NULL, + `reference_type` varchar(255) DEFAULT NULL, + `debit` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `credit` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_expenses_on_currency_id` (`currency_id`), + KEY `index_expenses_on_reference_type_and_reference_id` (`reference_type`,`reference_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `expenses` +-- + +LOCK TABLES `expenses` WRITE; +/*!40000 ALTER TABLE `expenses` DISABLE KEYS */; +/*!40000 ALTER TABLE `expenses` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `liabilities` +-- + +DROP TABLE IF EXISTS `liabilities`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `liabilities` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` int(11) NOT NULL, + `currency_id` varchar(255) NOT NULL, + `member_id` int(11) DEFAULT NULL, + `reference_id` int(11) DEFAULT NULL, + `reference_type` varchar(255) DEFAULT NULL, + `debit` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `credit` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_liabilities_on_currency_id` (`currency_id`), + KEY `index_liabilities_on_member_id` (`member_id`), + KEY `index_liabilities_on_reference_type_and_reference_id` (`reference_type`,`reference_id`) +) ENGINE=InnoDB AUTO_INCREMENT=482 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `liabilities` +-- + +LOCK TABLES `liabilities` WRITE; +/*!40000 ALTER TABLE `liabilities` DISABLE KEYS */; +INSERT INTO `liabilities` VALUES (1,202,'eth',3,1,'Deposit',0.0000000000000000,2.0000000000000000,'2019-01-22 20:25:29','2019-01-22 20:25:29'),(2,202,'kyn',3,2,'Deposit',0.0000000000000000,1000.0000000000000000,'2019-01-22 21:09:09','2019-01-22 21:09:09'),(3,202,'kyn',4,3,'Deposit',0.0000000000000000,3000.0000000000000000,'2019-01-23 06:59:00','2019-01-23 06:59:00'),(4,202,'eth',3,4,'Deposit',0.0000000000000000,1.0000000000000000,'2019-01-23 06:59:32','2019-01-23 06:59:32'),(5,201,'usd',4,5,'Deposit',0.0000000000000000,10000.0000000000000000,'2019-01-23 07:18:45','2019-01-23 07:18:45'),(6,201,'usd',5,6,'Deposit',0.0000000000000000,2000.0000000000000000,'2019-01-23 07:18:54','2019-01-23 07:18:54'),(7,201,'usd',2,7,'Deposit',0.0000000000000000,10000.0000000000000000,'2019-01-23 07:19:00','2019-01-23 07:19:00'),(8,201,'usd',4,1,'Order',23.6000000000000000,0.0000000000000000,'2019-01-23 07:22:04','2019-01-23 07:22:04'),(9,211,'usd',4,1,'Order',0.0000000000000000,23.6000000000000000,'2019-01-23 07:22:04','2019-01-23 07:22:04'),(10,201,'usd',4,2,'Order',34.5000000000000000,0.0000000000000000,'2019-01-23 07:22:27','2019-01-23 07:22:27'),(11,211,'usd',4,2,'Order',0.0000000000000000,34.5000000000000000,'2019-01-23 07:22:27','2019-01-23 07:22:27'),(12,201,'usd',4,3,'Order',22.4000000000000000,0.0000000000000000,'2019-01-23 07:22:39','2019-01-23 07:22:39'),(13,211,'usd',4,3,'Order',0.0000000000000000,22.4000000000000000,'2019-01-23 07:22:39','2019-01-23 07:22:39'),(14,201,'usd',4,4,'Order',43.2000000000000000,0.0000000000000000,'2019-01-23 07:22:47','2019-01-23 07:22:47'),(15,211,'usd',4,4,'Order',0.0000000000000000,43.2000000000000000,'2019-01-23 07:22:47','2019-01-23 07:22:47'),(16,201,'usd',4,5,'Order',99.0000000000000000,0.0000000000000000,'2019-01-23 07:23:03','2019-01-23 07:23:03'),(17,211,'usd',4,5,'Order',0.0000000000000000,99.0000000000000000,'2019-01-23 07:23:03','2019-01-23 07:23:03'),(18,202,'kyn',4,6,'Order',300.0000000000000000,0.0000000000000000,'2019-01-23 07:27:11','2019-01-23 07:27:11'),(19,212,'kyn',4,6,'Order',0.0000000000000000,300.0000000000000000,'2019-01-23 07:27:11','2019-01-23 07:27:11'),(20,202,'kyn',4,7,'Order',500.0000000000000000,0.0000000000000000,'2019-01-23 07:27:53','2019-01-23 07:27:53'),(21,212,'kyn',4,7,'Order',0.0000000000000000,500.0000000000000000,'2019-01-23 07:27:53','2019-01-23 07:27:53'),(22,202,'kyn',4,8,'Order',800.0000000000000000,0.0000000000000000,'2019-01-23 07:28:19','2019-01-23 07:28:19'),(23,212,'kyn',4,8,'Order',0.0000000000000000,800.0000000000000000,'2019-01-23 07:28:19','2019-01-23 07:28:19'),(24,202,'kyn',4,9,'Order',1000.0000000000000000,0.0000000000000000,'2019-01-23 07:28:28','2019-01-23 07:28:28'),(25,212,'kyn',4,9,'Order',0.0000000000000000,1000.0000000000000000,'2019-01-23 07:28:28','2019-01-23 07:28:28'),(26,202,'eth',3,10,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 07:32:23','2019-01-23 07:32:23'),(27,212,'eth',3,10,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 07:32:23','2019-01-23 07:32:23'),(28,202,'eth',3,11,'Order',0.3000000000000000,0.0000000000000000,'2019-01-23 07:32:39','2019-01-23 07:32:39'),(29,212,'eth',3,11,'Order',0.0000000000000000,0.3000000000000000,'2019-01-23 07:32:39','2019-01-23 07:32:39'),(30,202,'eth',3,12,'Order',0.5000000000000000,0.0000000000000000,'2019-01-23 07:32:49','2019-01-23 07:32:49'),(31,212,'eth',3,12,'Order',0.0000000000000000,0.5000000000000000,'2019-01-23 07:32:49','2019-01-23 07:32:49'),(32,202,'eth',3,13,'Order',0.5000000000000000,0.0000000000000000,'2019-01-23 07:32:58','2019-01-23 07:32:58'),(33,212,'eth',3,13,'Order',0.0000000000000000,0.5000000000000000,'2019-01-23 07:32:58','2019-01-23 07:32:58'),(34,202,'eth',3,14,'Order',0.3000000000000000,0.0000000000000000,'2019-01-23 07:33:13','2019-01-23 07:33:13'),(35,212,'eth',3,14,'Order',0.0000000000000000,0.3000000000000000,'2019-01-23 07:33:13','2019-01-23 07:33:13'),(36,202,'eth',3,15,'Order',0.4500000000000000,0.0000000000000000,'2019-01-23 07:37:32','2019-01-23 07:37:32'),(37,212,'eth',3,15,'Order',0.0000000000000000,0.4500000000000000,'2019-01-23 07:37:32','2019-01-23 07:37:32'),(38,202,'eth',3,16,'Order',0.4000000000000000,0.0000000000000000,'2019-01-23 07:37:47','2019-01-23 07:37:47'),(39,212,'eth',3,16,'Order',0.0000000000000000,0.4000000000000000,'2019-01-23 07:37:47','2019-01-23 07:37:47'),(40,212,'eth',3,12,'Order',0.5000000000000000,0.0000000000000000,'2019-01-23 07:42:10','2019-01-23 07:42:10'),(41,202,'eth',3,12,'Order',0.0000000000000000,0.5000000000000000,'2019-01-23 07:42:10','2019-01-23 07:42:10'),(42,202,'eth',3,20,'Order',0.4500000000000000,0.0000000000000000,'2019-01-23 07:43:19','2019-01-23 07:43:19'),(43,212,'eth',3,20,'Order',0.0000000000000000,0.4500000000000000,'2019-01-23 07:43:19','2019-01-23 07:43:19'),(44,202,'eth',3,21,'Order',0.4000000000000000,0.0000000000000000,'2019-01-23 07:43:34','2019-01-23 07:43:34'),(45,212,'eth',3,21,'Order',0.0000000000000000,0.4000000000000000,'2019-01-23 07:43:34','2019-01-23 07:43:34'),(46,202,'kyn',3,22,'Order',300.0000000000000000,0.0000000000000000,'2019-01-23 07:44:10','2019-01-23 07:44:10'),(47,212,'kyn',3,22,'Order',0.0000000000000000,300.0000000000000000,'2019-01-23 07:44:10','2019-01-23 07:44:10'),(48,202,'kyn',3,23,'Order',500.0000000000000000,0.0000000000000000,'2019-01-23 07:45:28','2019-01-23 07:45:28'),(49,212,'kyn',3,23,'Order',0.0000000000000000,500.0000000000000000,'2019-01-23 07:45:28','2019-01-23 07:45:28'),(50,202,'eth',1,8,'Deposit',0.0000000000000000,0.4161118508655127,'2019-01-23 08:47:25','2019-01-23 08:47:25'),(51,212,'eth',3,13,'Order',0.5000000000000000,0.0000000000000000,'2019-01-23 08:58:34','2019-01-23 08:58:34'),(52,202,'eth',3,13,'Order',0.0000000000000000,0.5000000000000000,'2019-01-23 08:58:34','2019-01-23 08:58:34'),(53,201,'usd',4,24,'Order',11.8500000000000000,0.0000000000000000,'2019-01-23 08:59:19','2019-01-23 08:59:19'),(54,211,'usd',4,24,'Order',0.0000000000000000,11.8500000000000000,'2019-01-23 08:59:19','2019-01-23 08:59:19'),(55,202,'eth',3,25,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 09:00:04','2019-01-23 09:00:04'),(56,212,'eth',3,25,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 09:00:04','2019-01-23 09:00:04'),(57,212,'eth',3,1,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 09:00:05','2019-01-23 09:00:05'),(58,211,'usd',4,1,'Trade',11.8500000000000000,0.0000000000000000,'2019-01-23 09:00:05','2019-01-23 09:00:05'),(59,201,'usd',3,1,'Trade',0.0000000000000000,11.8322250000000000,'2019-01-23 09:00:05','2019-01-23 09:00:05'),(60,202,'eth',4,1,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 09:00:05','2019-01-23 09:00:05'),(61,201,'usd',4,26,'Order',13.0900000000000000,0.0000000000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(62,211,'usd',4,26,'Order',0.0000000000000000,13.0900000000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(63,212,'eth',3,2,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(64,211,'usd',4,2,'Trade',11.9000000000000000,0.0000000000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(65,201,'usd',3,2,'Trade',0.0000000000000000,11.8821500000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(66,202,'eth',4,2,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(67,211,'usd',4,2,'Trade',1.1900000000000000,0.0000000000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(68,201,'usd',4,2,'Trade',0.0000000000000000,1.1900000000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(69,201,'usd',4,27,'Order',29.2500000000000000,0.0000000000000000,'2019-01-23 09:03:54','2019-01-23 09:03:54'),(70,211,'usd',4,27,'Order',0.0000000000000000,29.2500000000000000,'2019-01-23 09:03:54','2019-01-23 09:03:54'),(71,201,'usd',4,28,'Order',32.4800000000000000,0.0000000000000000,'2019-01-23 09:04:31','2019-01-23 09:04:31'),(72,211,'usd',4,28,'Order',0.0000000000000000,32.4800000000000000,'2019-01-23 09:04:31','2019-01-23 09:04:31'),(73,201,'usd',4,29,'Order',31.9200000000000000,0.0000000000000000,'2019-01-23 09:05:02','2019-01-23 09:05:02'),(74,211,'usd',4,29,'Order',0.0000000000000000,31.9200000000000000,'2019-01-23 09:05:02','2019-01-23 09:05:02'),(75,201,'usd',4,30,'Order',28.2500000000000000,0.0000000000000000,'2019-01-23 09:05:16','2019-01-23 09:05:16'),(76,211,'usd',4,30,'Order',0.0000000000000000,28.2500000000000000,'2019-01-23 09:05:16','2019-01-23 09:05:16'),(77,201,'usd',4,31,'Order',23.3100000000000000,0.0000000000000000,'2019-01-23 09:12:50','2019-01-23 09:12:50'),(78,211,'usd',4,31,'Order',0.0000000000000000,23.3100000000000000,'2019-01-23 09:12:50','2019-01-23 09:12:50'),(79,202,'eth',3,9,'Deposit',0.0000000000000000,1.0000000000000000,'2019-01-23 09:13:34','2019-01-23 09:13:34'),(80,202,'eth',3,32,'Order',0.0500000000000000,0.0000000000000000,'2019-01-23 09:22:02','2019-01-23 09:22:02'),(81,212,'eth',3,32,'Order',0.0000000000000000,0.0500000000000000,'2019-01-23 09:22:02','2019-01-23 09:22:02'),(82,202,'eth',3,33,'Order',0.0800000000000000,0.0000000000000000,'2019-01-23 09:22:17','2019-01-23 09:22:17'),(83,212,'eth',3,33,'Order',0.0000000000000000,0.0800000000000000,'2019-01-23 09:22:17','2019-01-23 09:22:17'),(84,202,'eth',3,34,'Order',0.0900000000000000,0.0000000000000000,'2019-01-23 09:22:28','2019-01-23 09:22:28'),(85,212,'eth',3,34,'Order',0.0000000000000000,0.0900000000000000,'2019-01-23 09:22:28','2019-01-23 09:22:28'),(86,202,'eth',3,35,'Order',0.3000000000000000,0.0000000000000000,'2019-01-23 09:22:38','2019-01-23 09:22:38'),(87,212,'eth',3,35,'Order',0.0000000000000000,0.3000000000000000,'2019-01-23 09:22:38','2019-01-23 09:22:38'),(88,202,'eth',3,36,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 09:23:15','2019-01-23 09:23:15'),(89,212,'eth',3,36,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 09:23:15','2019-01-23 09:23:15'),(90,202,'eth',3,37,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 09:23:24','2019-01-23 09:23:24'),(91,212,'eth',3,37,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 09:23:24','2019-01-23 09:23:24'),(92,202,'eth',3,10,'Deposit',0.0000000000000000,1.0000000000000000,'2019-01-23 11:22:47','2019-01-23 11:22:47'),(93,202,'kyn',3,11,'Deposit',0.0000000000000000,25000.0000000000000000,'2019-01-23 11:24:33','2019-01-23 11:24:33'),(94,201,'usd',3,38,'Order',11.9000000000000000,0.0000000000000000,'2019-01-23 11:30:51','2019-01-23 11:30:51'),(95,211,'usd',3,38,'Order',0.0000000000000000,11.9000000000000000,'2019-01-23 11:30:51','2019-01-23 11:30:51'),(96,212,'eth',3,3,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:30:51','2019-01-23 11:30:51'),(97,211,'usd',3,3,'Trade',11.9000000000000000,0.0000000000000000,'2019-01-23 11:30:51','2019-01-23 11:30:51'),(98,201,'usd',3,3,'Trade',0.0000000000000000,11.8821500000000000,'2019-01-23 11:30:51','2019-01-23 11:30:51'),(99,202,'eth',3,3,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:30:51','2019-01-23 11:30:51'),(100,202,'eth',4,40,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:31:21','2019-01-23 11:31:21'),(101,212,'eth',4,40,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:31:21','2019-01-23 11:31:21'),(102,212,'eth',4,4,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:31:21','2019-01-23 11:31:21'),(103,211,'usd',4,4,'Trade',11.8000000000000000,0.0000000000000000,'2019-01-23 11:31:21','2019-01-23 11:31:21'),(104,201,'usd',4,4,'Trade',0.0000000000000000,11.7823000000000000,'2019-01-23 11:31:21','2019-01-23 11:31:21'),(105,202,'eth',4,4,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:31:21','2019-01-23 11:31:21'),(106,202,'eth',4,41,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:31:36','2019-01-23 11:31:36'),(107,212,'eth',4,41,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:31:36','2019-01-23 11:31:36'),(108,212,'eth',4,5,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:31:36','2019-01-23 11:31:36'),(109,211,'usd',4,5,'Trade',11.8000000000000000,0.0000000000000000,'2019-01-23 11:31:36','2019-01-23 11:31:36'),(110,201,'usd',4,5,'Trade',0.0000000000000000,11.7823000000000000,'2019-01-23 11:31:36','2019-01-23 11:31:36'),(111,202,'eth',4,5,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:31:36','2019-01-23 11:31:36'),(112,201,'usd',4,44,'Order',22.0000000000000000,0.0000000000000000,'2019-01-23 11:32:20','2019-01-23 11:32:20'),(113,211,'usd',4,44,'Order',0.0000000000000000,22.0000000000000000,'2019-01-23 11:32:20','2019-01-23 11:32:20'),(114,201,'usd',4,45,'Order',23.0000000000000000,0.0000000000000000,'2019-01-23 11:32:31','2019-01-23 11:32:31'),(115,211,'usd',4,45,'Order',0.0000000000000000,23.0000000000000000,'2019-01-23 11:32:31','2019-01-23 11:32:31'),(116,201,'usd',4,46,'Order',26.8400000000000000,0.0000000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(117,211,'usd',4,46,'Order',0.0000000000000000,26.8400000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(118,212,'eth',3,6,'Trade',0.2000000000000000,0.0000000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(119,211,'usd',4,6,'Trade',24.4000000000000000,0.0000000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(120,201,'usd',3,6,'Trade',0.0000000000000000,24.3634000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(121,202,'eth',4,6,'Trade',0.0000000000000000,0.1997000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(122,211,'usd',4,6,'Trade',2.4400000000000000,0.0000000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(123,201,'usd',4,6,'Trade',0.0000000000000000,2.4400000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(124,202,'eth',3,47,'Order',0.4000000000000000,0.0000000000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(125,212,'eth',3,47,'Order',0.0000000000000000,0.4000000000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(126,212,'eth',3,7,'Trade',0.2500000000000000,0.0000000000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(127,211,'usd',4,7,'Trade',29.2500000000000000,0.0000000000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(128,201,'usd',3,7,'Trade',0.0000000000000000,29.2061250000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(129,202,'eth',4,7,'Trade',0.0000000000000000,0.2496250000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(130,212,'eth',3,8,'Trade',0.1500000000000000,0.0000000000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(131,211,'usd',4,8,'Trade',17.4000000000000000,0.0000000000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(132,201,'usd',3,8,'Trade',0.0000000000000000,17.3739000000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(133,202,'eth',4,8,'Trade',0.0000000000000000,0.1497750000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(134,202,'eth',4,48,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:32:53','2019-01-23 11:32:53'),(135,212,'eth',4,48,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:32:53','2019-01-23 11:32:53'),(136,212,'eth',4,9,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:32:53','2019-01-23 11:32:53'),(137,211,'usd',4,9,'Trade',11.6000000000000000,0.0000000000000000,'2019-01-23 11:32:53','2019-01-23 11:32:53'),(138,201,'usd',4,9,'Trade',0.0000000000000000,11.5826000000000000,'2019-01-23 11:32:53','2019-01-23 11:32:53'),(139,202,'eth',4,9,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:32:53','2019-01-23 11:32:53'),(140,201,'usd',4,49,'Order',27.7200000000000000,0.0000000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(141,211,'usd',4,49,'Order',0.0000000000000000,27.7200000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(142,212,'eth',3,10,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(143,211,'usd',4,10,'Trade',12.2000000000000000,0.0000000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(144,201,'usd',3,10,'Trade',0.0000000000000000,12.1817000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(145,202,'eth',4,10,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(146,212,'eth',3,11,'Trade',0.0500000000000000,0.0000000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(147,211,'usd',4,11,'Trade',6.2500000000000000,0.0000000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(148,201,'usd',3,11,'Trade',0.0000000000000000,6.2406250000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(149,202,'eth',4,11,'Trade',0.0000000000000000,0.0499250000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(150,212,'eth',3,12,'Trade',0.0500000000000000,0.0000000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(151,211,'usd',4,12,'Trade',6.7500000000000000,0.0000000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(152,201,'usd',3,12,'Trade',0.0000000000000000,6.7398750000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(153,202,'eth',4,12,'Trade',0.0000000000000000,0.0499250000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(154,211,'usd',4,12,'Trade',2.5200000000000000,0.0000000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(155,201,'usd',4,12,'Trade',0.0000000000000000,2.5200000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(156,202,'eth',4,50,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(157,212,'eth',4,50,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(158,212,'eth',4,13,'Trade',0.0300000000000000,0.0000000000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(159,211,'usd',4,13,'Trade',3.4800000000000000,0.0000000000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(160,201,'usd',4,13,'Trade',0.0000000000000000,3.4747800000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(161,202,'eth',4,13,'Trade',0.0000000000000000,0.0299550000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(162,212,'eth',4,14,'Trade',0.0700000000000000,0.0000000000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(163,211,'usd',4,14,'Trade',8.0500000000000000,0.0000000000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(164,201,'usd',4,14,'Trade',0.0000000000000000,8.0379250000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(165,202,'eth',4,14,'Trade',0.0000000000000000,0.0698950000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(166,202,'eth',4,51,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:33:43','2019-01-23 11:33:43'),(167,212,'eth',4,51,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:33:43','2019-01-23 11:33:43'),(168,212,'eth',4,15,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:33:43','2019-01-23 11:33:43'),(169,211,'usd',4,15,'Trade',11.5000000000000000,0.0000000000000000,'2019-01-23 11:33:43','2019-01-23 11:33:43'),(170,201,'usd',4,15,'Trade',0.0000000000000000,11.4827500000000000,'2019-01-23 11:33:43','2019-01-23 11:33:43'),(171,202,'eth',4,15,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:33:43','2019-01-23 11:33:43'),(172,201,'usd',4,52,'Order',45.1440000000000000,0.0000000000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(173,211,'usd',4,52,'Order',0.0000000000000000,45.1440000000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(174,212,'eth',3,16,'Trade',0.0300000000000000,0.0000000000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(175,211,'usd',4,16,'Trade',4.0500000000000000,0.0000000000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(176,201,'usd',3,16,'Trade',0.0000000000000000,4.0439250000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(177,202,'eth',4,16,'Trade',0.0000000000000000,0.0299550000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(178,212,'eth',3,17,'Trade',0.2700000000000000,0.0000000000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(179,211,'usd',4,17,'Trade',36.9900000000000000,0.0000000000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(180,201,'usd',3,17,'Trade',0.0000000000000000,36.9345150000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(181,202,'eth',4,17,'Trade',0.0000000000000000,0.2695950000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(182,211,'usd',4,17,'Trade',4.1040000000000000,0.0000000000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(183,201,'usd',4,17,'Trade',0.0000000000000000,4.1040000000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(184,202,'eth',4,53,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:34:46','2019-01-23 11:34:46'),(185,212,'eth',4,53,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:34:46','2019-01-23 11:34:46'),(186,212,'eth',4,18,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:34:46','2019-01-23 11:34:46'),(187,211,'usd',4,18,'Trade',11.5000000000000000,0.0000000000000000,'2019-01-23 11:34:46','2019-01-23 11:34:46'),(188,201,'usd',4,18,'Trade',0.0000000000000000,11.4827500000000000,'2019-01-23 11:34:46','2019-01-23 11:34:46'),(189,202,'eth',4,18,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:34:46','2019-01-23 11:34:46'),(190,202,'eth',4,54,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(191,212,'eth',4,54,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(192,212,'eth',4,19,'Trade',0.0300000000000000,0.0000000000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(193,211,'usd',4,19,'Trade',3.4500000000000000,0.0000000000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(194,201,'usd',4,19,'Trade',0.0000000000000000,3.4448250000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(195,202,'eth',4,19,'Trade',0.0000000000000000,0.0299550000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(196,212,'eth',4,20,'Trade',0.0700000000000000,0.0000000000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(197,211,'usd',4,20,'Trade',8.0500000000000000,0.0000000000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(198,201,'usd',4,20,'Trade',0.0000000000000000,8.0379250000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(199,202,'eth',4,20,'Trade',0.0000000000000000,0.0698950000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(200,201,'usd',4,55,'Order',17.2500000000000000,0.0000000000000000,'2019-01-23 11:35:23','2019-01-23 11:35:23'),(201,211,'usd',4,55,'Order',0.0000000000000000,17.2500000000000000,'2019-01-23 11:35:23','2019-01-23 11:35:23'),(202,201,'usd',4,56,'Order',11.0000000000000000,0.0000000000000000,'2019-01-23 11:35:54','2019-01-23 11:35:54'),(203,211,'usd',4,56,'Order',0.0000000000000000,11.0000000000000000,'2019-01-23 11:35:54','2019-01-23 11:35:54'),(204,202,'eth',4,57,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(205,212,'eth',4,57,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(206,212,'eth',4,21,'Trade',0.1300000000000000,0.0000000000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(207,211,'usd',4,21,'Trade',14.9500000000000000,0.0000000000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(208,201,'usd',4,21,'Trade',0.0000000000000000,14.9275750000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(209,202,'eth',4,21,'Trade',0.0000000000000000,0.1298050000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(210,212,'eth',4,22,'Trade',0.0700000000000000,0.0000000000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(211,211,'usd',4,22,'Trade',8.0500000000000000,0.0000000000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(212,201,'usd',4,22,'Trade',0.0000000000000000,8.0379250000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(213,202,'eth',4,22,'Trade',0.0000000000000000,0.0698950000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(214,202,'eth',4,58,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:36:23','2019-01-23 11:36:23'),(215,212,'eth',4,58,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:36:23','2019-01-23 11:36:23'),(216,212,'eth',4,23,'Trade',0.0800000000000000,0.0000000000000000,'2019-01-23 11:36:23','2019-01-23 11:36:23'),(217,211,'usd',4,23,'Trade',9.2000000000000000,0.0000000000000000,'2019-01-23 11:36:23','2019-01-23 11:36:23'),(218,201,'usd',4,23,'Trade',0.0000000000000000,9.1862000000000000,'2019-01-23 11:36:23','2019-01-23 11:36:23'),(219,202,'eth',4,23,'Trade',0.0000000000000000,0.0798800000000000,'2019-01-23 11:36:23','2019-01-23 11:36:23'),(220,201,'usd',4,59,'Order',11.1000000000000000,0.0000000000000000,'2019-01-23 11:36:40','2019-01-23 11:36:40'),(221,211,'usd',4,59,'Order',0.0000000000000000,11.1000000000000000,'2019-01-23 11:36:40','2019-01-23 11:36:40'),(222,202,'eth',4,60,'Order',0.4000000000000000,0.0000000000000000,'2019-01-23 11:36:59','2019-01-23 11:36:59'),(223,212,'eth',4,60,'Order',0.0000000000000000,0.4000000000000000,'2019-01-23 11:36:59','2019-01-23 11:36:59'),(224,202,'eth',4,61,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:37:16','2019-01-23 11:37:16'),(225,212,'eth',4,61,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:37:16','2019-01-23 11:37:16'),(226,212,'eth',4,24,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:37:16','2019-01-23 11:37:16'),(227,211,'usd',4,24,'Trade',11.4000000000000000,0.0000000000000000,'2019-01-23 11:37:16','2019-01-23 11:37:16'),(228,201,'usd',4,24,'Trade',0.0000000000000000,11.3829000000000000,'2019-01-23 11:37:16','2019-01-23 11:37:16'),(229,202,'eth',4,24,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:37:16','2019-01-23 11:37:16'),(230,201,'usd',4,62,'Order',12.6500000000000000,0.0000000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(231,211,'usd',4,62,'Order',0.0000000000000000,12.6500000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(232,212,'eth',4,25,'Trade',0.0200000000000000,0.0000000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(233,211,'usd',4,25,'Trade',2.3000000000000000,0.0000000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(234,201,'usd',4,25,'Trade',0.0000000000000000,2.2965500000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(235,202,'eth',4,25,'Trade',0.0000000000000000,0.0199700000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(236,212,'eth',4,26,'Trade',0.0800000000000000,0.0000000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(237,211,'usd',4,26,'Trade',9.2000000000000000,0.0000000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(238,201,'usd',4,26,'Trade',0.0000000000000000,9.1862000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(239,202,'eth',4,26,'Trade',0.0000000000000000,0.0798800000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(240,211,'usd',4,26,'Trade',1.1500000000000000,0.0000000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(241,201,'usd',4,26,'Trade',0.0000000000000000,1.1500000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(242,201,'usd',4,63,'Order',25.3000000000000000,0.0000000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(243,211,'usd',4,63,'Order',0.0000000000000000,25.3000000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(244,212,'eth',4,27,'Trade',0.2000000000000000,0.0000000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(245,211,'usd',4,27,'Trade',23.0000000000000000,0.0000000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(246,201,'usd',4,27,'Trade',0.0000000000000000,22.9655000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(247,202,'eth',4,27,'Trade',0.0000000000000000,0.1997000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(248,211,'usd',4,27,'Trade',2.3000000000000000,0.0000000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(249,201,'usd',4,27,'Trade',0.0000000000000000,2.3000000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(250,202,'eth',4,64,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 11:38:29','2019-01-23 11:38:29'),(251,212,'eth',4,64,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 11:38:29','2019-01-23 11:38:29'),(252,202,'eth',4,65,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:38:49','2019-01-23 11:38:49'),(253,212,'eth',4,65,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:38:49','2019-01-23 11:38:49'),(254,212,'eth',4,28,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:38:49','2019-01-23 11:38:49'),(255,211,'usd',4,28,'Trade',11.4000000000000000,0.0000000000000000,'2019-01-23 11:38:49','2019-01-23 11:38:49'),(256,201,'usd',4,28,'Trade',0.0000000000000000,11.3829000000000000,'2019-01-23 11:38:49','2019-01-23 11:38:49'),(257,202,'eth',4,28,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:38:49','2019-01-23 11:38:49'),(258,201,'usd',3,66,'Order',1.2650000000000000,0.0000000000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(259,211,'usd',3,66,'Order',0.0000000000000000,1.2650000000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(260,212,'eth',4,29,'Trade',0.0100000000000000,0.0000000000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(261,211,'usd',3,29,'Trade',1.1500000000000000,0.0000000000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(262,201,'usd',4,29,'Trade',0.0000000000000000,1.1482750000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(263,202,'eth',3,29,'Trade',0.0000000000000000,0.0099850000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(264,211,'usd',3,29,'Trade',0.1150000000000000,0.0000000000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(265,201,'usd',3,29,'Trade',0.0000000000000000,0.1150000000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(266,202,'eth',4,67,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(267,212,'eth',4,67,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(268,212,'eth',4,30,'Trade',0.0800000000000000,0.0000000000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(269,211,'usd',4,30,'Trade',9.1200000000000000,0.0000000000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(270,201,'usd',4,30,'Trade',0.0000000000000000,9.1063200000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(271,202,'eth',4,30,'Trade',0.0000000000000000,0.0798800000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(272,212,'eth',4,31,'Trade',0.0200000000000000,0.0000000000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(273,211,'usd',4,31,'Trade',2.2600000000000000,0.0000000000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(274,201,'usd',4,31,'Trade',0.0000000000000000,2.2566100000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(275,202,'eth',4,31,'Trade',0.0000000000000000,0.0199700000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(276,201,'usd',4,68,'Order',12.6500000000000000,0.0000000000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(277,211,'usd',4,68,'Order',0.0000000000000000,12.6500000000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(278,212,'eth',4,32,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(279,211,'usd',4,32,'Trade',11.5000000000000000,0.0000000000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(280,201,'usd',4,32,'Trade',0.0000000000000000,11.4827500000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(281,202,'eth',4,32,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(282,211,'usd',4,32,'Trade',1.1500000000000000,0.0000000000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(283,201,'usd',4,32,'Trade',0.0000000000000000,1.1500000000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(284,202,'eth',4,69,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 11:40:17','2019-01-23 11:40:17'),(285,212,'eth',4,69,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 11:40:17','2019-01-23 11:40:17'),(286,212,'eth',4,33,'Trade',0.2000000000000000,0.0000000000000000,'2019-01-23 11:40:17','2019-01-23 11:40:17'),(287,211,'usd',4,33,'Trade',22.6000000000000000,0.0000000000000000,'2019-01-23 11:40:17','2019-01-23 11:40:17'),(288,201,'usd',4,33,'Trade',0.0000000000000000,22.5661000000000000,'2019-01-23 11:40:17','2019-01-23 11:40:17'),(289,202,'eth',4,33,'Trade',0.0000000000000000,0.1997000000000000,'2019-01-23 11:40:17','2019-01-23 11:40:17'),(290,202,'eth',4,70,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(291,212,'eth',4,70,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(292,212,'eth',4,34,'Trade',0.0300000000000000,0.0000000000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(293,211,'usd',4,34,'Trade',3.3900000000000000,0.0000000000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(294,201,'usd',4,34,'Trade',0.0000000000000000,3.3849150000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(295,202,'eth',4,34,'Trade',0.0000000000000000,0.0299550000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(296,212,'eth',4,35,'Trade',0.1700000000000000,0.0000000000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(297,211,'usd',4,35,'Trade',19.0400000000000000,0.0000000000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(298,201,'usd',4,35,'Trade',0.0000000000000000,19.0114400000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(299,202,'eth',4,35,'Trade',0.0000000000000000,0.1697450000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(300,202,'eth',4,71,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(301,212,'eth',4,71,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(302,212,'eth',4,36,'Trade',0.0300000000000000,0.0000000000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(303,211,'usd',4,36,'Trade',3.3600000000000000,0.0000000000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(304,201,'usd',4,36,'Trade',0.0000000000000000,3.3549600000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(305,202,'eth',4,36,'Trade',0.0000000000000000,0.0299550000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(306,212,'eth',4,37,'Trade',0.1700000000000000,0.0000000000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(307,211,'usd',4,37,'Trade',18.8700000000000000,0.0000000000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(308,201,'usd',4,37,'Trade',0.0000000000000000,18.8416950000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(309,202,'eth',4,37,'Trade',0.0000000000000000,0.1697450000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(310,201,'usd',4,72,'Order',15.0260000000000000,0.0000000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(311,211,'usd',4,72,'Order',0.0000000000000000,15.0260000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(312,212,'eth',4,38,'Trade',0.0100000000000000,0.0000000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(313,211,'usd',4,38,'Trade',1.1500000000000000,0.0000000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(314,201,'usd',4,38,'Trade',0.0000000000000000,1.1482750000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(315,202,'eth',4,38,'Trade',0.0000000000000000,0.0099850000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(316,212,'eth',3,39,'Trade',0.0300000000000000,0.0000000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(317,211,'usd',4,39,'Trade',4.1100000000000000,0.0000000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(318,201,'usd',3,39,'Trade',0.0000000000000000,4.1038350000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(319,202,'eth',4,39,'Trade',0.0000000000000000,0.0299550000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(320,212,'eth',3,40,'Trade',0.0600000000000000,0.0000000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(321,211,'usd',4,40,'Trade',8.4000000000000000,0.0000000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(322,201,'usd',3,40,'Trade',0.0000000000000000,8.3874000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(323,202,'eth',4,40,'Trade',0.0000000000000000,0.0599100000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(324,211,'usd',4,40,'Trade',1.3660000000000000,0.0000000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(325,201,'usd',4,40,'Trade',0.0000000000000000,1.3660000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(326,202,'eth',4,73,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(327,212,'eth',4,73,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(328,212,'eth',4,41,'Trade',0.0400000000000000,0.0000000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(329,211,'usd',4,41,'Trade',4.4400000000000000,0.0000000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(330,201,'usd',4,41,'Trade',0.0000000000000000,4.4333400000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(331,202,'eth',4,41,'Trade',0.0000000000000000,0.0399400000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(332,212,'eth',4,42,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(333,211,'usd',4,42,'Trade',11.1000000000000000,0.0000000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(334,201,'usd',4,42,'Trade',0.0000000000000000,11.0833500000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(335,202,'eth',4,42,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(336,212,'eth',4,43,'Trade',0.0600000000000000,0.0000000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(337,211,'usd',4,43,'Trade',6.6000000000000000,0.0000000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(338,201,'usd',4,43,'Trade',0.0000000000000000,6.5901000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(339,202,'eth',4,43,'Trade',0.0000000000000000,0.0599100000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(340,202,'eth',4,74,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(341,212,'eth',4,74,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(342,212,'eth',4,44,'Trade',0.1400000000000000,0.0000000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(343,211,'usd',4,44,'Trade',15.4000000000000000,0.0000000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(344,201,'usd',4,44,'Trade',0.0000000000000000,15.3769000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(345,202,'eth',4,44,'Trade',0.0000000000000000,0.1397900000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(346,212,'eth',4,45,'Trade',0.0600000000000000,0.0000000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(347,211,'usd',4,45,'Trade',6.6000000000000000,0.0000000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(348,201,'usd',4,45,'Trade',0.0000000000000000,6.5901000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(349,202,'eth',4,45,'Trade',0.0000000000000000,0.0599100000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(350,201,'usd',4,75,'Order',11.0000000000000000,0.0000000000000000,'2019-01-23 11:42:39','2019-01-23 11:42:39'),(351,211,'usd',4,75,'Order',0.0000000000000000,11.0000000000000000,'2019-01-23 11:42:39','2019-01-23 11:42:39'),(352,202,'eth',4,76,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 11:42:53','2019-01-23 11:42:53'),(353,212,'eth',4,76,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 11:42:53','2019-01-23 11:42:53'),(354,212,'eth',4,46,'Trade',0.0400000000000000,0.0000000000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(355,211,'usd',4,46,'Trade',4.4000000000000000,0.0000000000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(356,201,'usd',4,46,'Trade',0.0000000000000000,4.3934000000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(357,202,'eth',4,46,'Trade',0.0000000000000000,0.0399400000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(358,212,'eth',4,47,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(359,211,'usd',4,47,'Trade',11.0000000000000000,0.0000000000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(360,201,'usd',4,47,'Trade',0.0000000000000000,10.9835000000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(361,202,'eth',4,47,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(362,202,'eth',4,77,'Order',0.5000000000000000,0.0000000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(363,212,'eth',4,77,'Order',0.0000000000000000,0.5000000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(364,212,'eth',4,48,'Trade',0.4000000000000000,0.0000000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(365,211,'usd',4,48,'Trade',43.2000000000000000,0.0000000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(366,201,'usd',4,48,'Trade',0.0000000000000000,43.1352000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(367,202,'eth',4,48,'Trade',0.0000000000000000,0.3994000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(368,212,'eth',4,49,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(369,211,'usd',4,49,'Trade',9.9000000000000000,0.0000000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(370,201,'usd',4,49,'Trade',0.0000000000000000,9.8851500000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(371,202,'eth',4,49,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(372,212,'eth',4,76,'Order',0.0600000000000000,0.0000000000000000,'2019-01-23 11:43:49','2019-01-23 11:43:49'),(373,202,'eth',4,76,'Order',0.0000000000000000,0.0600000000000000,'2019-01-23 11:43:49','2019-01-23 11:43:49'),(374,212,'eth',4,64,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 11:43:50','2019-01-23 11:43:50'),(375,202,'eth',4,64,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 11:43:50','2019-01-23 11:43:50'),(376,211,'usd',4,5,'Order',89.1000000000000000,0.0000000000000000,'2019-01-23 11:43:50','2019-01-23 11:43:50'),(377,201,'usd',4,5,'Order',0.0000000000000000,89.1000000000000000,'2019-01-23 11:43:50','2019-01-23 11:43:50'),(378,202,'eth',4,78,'Order',0.5000000000000000,0.0000000000000000,'2019-01-23 11:44:05','2019-01-23 11:44:05'),(379,212,'eth',4,78,'Order',0.0000000000000000,0.5000000000000000,'2019-01-23 11:44:05','2019-01-23 11:44:05'),(380,201,'usd',4,79,'Order',33.3000000000000000,0.0000000000000000,'2019-01-23 11:44:17','2019-01-23 11:44:17'),(381,211,'usd',4,79,'Order',0.0000000000000000,33.3000000000000000,'2019-01-23 11:44:17','2019-01-23 11:44:17'),(382,201,'usd',4,80,'Order',22.2000000000000000,0.0000000000000000,'2019-01-23 11:45:44','2019-01-23 11:45:44'),(383,211,'usd',4,80,'Order',0.0000000000000000,22.2000000000000000,'2019-01-23 11:45:44','2019-01-23 11:45:44'),(384,201,'usd',3,86,'Order',13.2000000000000000,0.0000000000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(385,211,'usd',3,86,'Order',0.0000000000000000,13.2000000000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(386,212,'eth',4,50,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(387,211,'usd',3,50,'Trade',12.0000000000000000,0.0000000000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(388,201,'usd',4,50,'Trade',0.0000000000000000,11.9820000000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(389,202,'eth',3,50,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(390,211,'usd',3,50,'Trade',1.2000000000000000,0.0000000000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(391,201,'usd',3,50,'Trade',0.0000000000000000,1.2000000000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(392,201,'usd',3,87,'Order',13.2000000000000000,0.0000000000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(393,211,'usd',3,87,'Order',0.0000000000000000,13.2000000000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(394,212,'eth',4,51,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(395,211,'usd',3,51,'Trade',12.0000000000000000,0.0000000000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(396,201,'usd',4,51,'Trade',0.0000000000000000,11.9820000000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(397,202,'eth',3,51,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(398,211,'usd',3,51,'Trade',1.2000000000000000,0.0000000000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(399,201,'usd',3,51,'Trade',0.0000000000000000,1.2000000000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(400,201,'usd',3,88,'Order',13.2000000000000000,0.0000000000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(401,211,'usd',3,88,'Order',0.0000000000000000,13.2000000000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(402,212,'eth',4,52,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(403,211,'usd',3,52,'Trade',12.0000000000000000,0.0000000000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(404,201,'usd',4,52,'Trade',0.0000000000000000,11.9820000000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(405,202,'eth',3,52,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(406,211,'usd',3,52,'Trade',1.2000000000000000,0.0000000000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(407,201,'usd',3,52,'Trade',0.0000000000000000,1.2000000000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(408,202,'eth',4,93,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 13:49:44','2019-01-23 13:49:44'),(409,212,'eth',4,93,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 13:49:44','2019-01-23 13:49:44'),(410,212,'eth',4,53,'Trade',0.2000000000000000,0.0000000000000000,'2019-01-23 13:49:44','2019-01-23 13:49:44'),(411,211,'usd',4,53,'Trade',22.2000000000000000,0.0000000000000000,'2019-01-23 13:49:44','2019-01-23 13:49:44'),(412,201,'usd',4,53,'Trade',0.0000000000000000,22.1667000000000000,'2019-01-23 13:49:44','2019-01-23 13:49:44'),(413,202,'eth',4,53,'Trade',0.0000000000000000,0.1997000000000000,'2019-01-23 13:49:44','2019-01-23 13:49:44'),(414,211,'usd',4,80,'Order',22.2000000000000000,0.0000000000000000,'2019-01-23 13:49:53','2019-01-23 13:49:53'),(415,201,'usd',4,80,'Order',0.0000000000000000,22.2000000000000000,'2019-01-23 13:49:53','2019-01-23 13:49:53'),(416,211,'usd',4,79,'Order',11.1000000000000000,0.0000000000000000,'2019-01-23 13:49:54','2019-01-23 13:49:54'),(417,201,'usd',4,79,'Order',0.0000000000000000,11.1000000000000000,'2019-01-23 13:49:54','2019-01-23 13:49:54'),(418,212,'eth',4,78,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 13:49:54','2019-01-23 13:49:54'),(419,202,'eth',4,78,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 13:49:54','2019-01-23 13:49:54'),(420,201,'usd',4,94,'Order',100.0000000000000000,0.0000000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(421,211,'usd',4,94,'Order',0.0000000000000000,100.0000000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(422,212,'eth',3,54,'Trade',0.0300000000000000,0.0000000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(423,211,'usd',4,54,'Trade',4.2000000000000000,0.0000000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(424,201,'usd',3,54,'Trade',0.0000000000000000,4.1937000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(425,202,'eth',4,54,'Trade',0.0000000000000000,0.0299550000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(426,212,'eth',3,55,'Trade',0.0700000000000000,0.0000000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(427,211,'usd',4,55,'Trade',10.5000000000000000,0.0000000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(428,201,'usd',3,55,'Trade',0.0000000000000000,10.4842500000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(429,202,'eth',4,55,'Trade',0.0000000000000000,0.0698950000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(430,211,'usd',4,55,'Trade',85.3000000000000000,0.0000000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(431,201,'usd',4,55,'Trade',0.0000000000000000,85.3000000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(432,202,'eth',4,95,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 13:50:14','2019-01-23 13:50:14'),(433,212,'eth',4,95,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 13:50:14','2019-01-23 13:50:14'),(434,212,'eth',3,37,'Order',0.2000000000000000,0.0000000000000000,'2019-01-23 13:51:14','2019-01-23 13:51:14'),(435,202,'eth',3,37,'Order',0.0000000000000000,0.2000000000000000,'2019-01-23 13:51:14','2019-01-23 13:51:14'),(436,212,'eth',3,36,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 13:51:15','2019-01-23 13:51:15'),(437,202,'eth',3,36,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 13:51:15','2019-01-23 13:51:15'),(438,212,'eth',3,35,'Order',0.2300000000000000,0.0000000000000000,'2019-01-23 13:51:15','2019-01-23 13:51:15'),(439,202,'eth',3,35,'Order',0.0000000000000000,0.2300000000000000,'2019-01-23 13:51:15','2019-01-23 13:51:15'),(440,201,'usd',3,96,'Order',100.0000000000000000,0.0000000000000000,'2019-01-23 13:51:37','2019-01-23 13:51:37'),(441,211,'usd',3,96,'Order',0.0000000000000000,100.0000000000000000,'2019-01-23 13:51:37','2019-01-23 13:51:37'),(442,212,'eth',4,56,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 13:51:37','2019-01-23 13:51:37'),(443,211,'usd',3,56,'Trade',100.0000000000000000,0.0000000000000000,'2019-01-23 13:51:37','2019-01-23 13:51:37'),(444,201,'usd',4,56,'Trade',0.0000000000000000,99.8500000000000000,'2019-01-23 13:51:37','2019-01-23 13:51:37'),(445,202,'eth',3,56,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 13:51:37','2019-01-23 13:51:37'),(446,201,'usd',4,100,'Order',100.0000000000000000,0.0000000000000000,'2019-01-23 13:53:37','2019-01-23 13:53:37'),(447,211,'usd',4,100,'Order',0.0000000000000000,100.0000000000000000,'2019-01-23 13:53:37','2019-01-23 13:53:37'),(448,201,'usd',3,101,'Order',1.0000000000000000,0.0000000000000000,'2019-01-23 13:54:10','2019-01-23 13:54:10'),(449,211,'usd',3,101,'Order',0.0000000000000000,1.0000000000000000,'2019-01-23 13:54:10','2019-01-23 13:54:10'),(450,202,'eth',4,102,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 13:54:25','2019-01-23 13:54:25'),(451,212,'eth',4,102,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 13:54:25','2019-01-23 13:54:25'),(452,212,'eth',4,57,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 13:54:25','2019-01-23 13:54:25'),(453,211,'usd',4,57,'Trade',100.0000000000000000,0.0000000000000000,'2019-01-23 13:54:25','2019-01-23 13:54:25'),(454,201,'usd',4,57,'Trade',0.0000000000000000,99.8500000000000000,'2019-01-23 13:54:25','2019-01-23 13:54:25'),(455,202,'eth',4,57,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 13:54:25','2019-01-23 13:54:25'),(456,211,'usd',3,101,'Order',1.0000000000000000,0.0000000000000000,'2019-01-23 13:55:15','2019-01-23 13:55:15'),(457,201,'usd',3,101,'Order',0.0000000000000000,1.0000000000000000,'2019-01-23 13:55:15','2019-01-23 13:55:15'),(458,201,'usd',3,103,'Order',1.0000000000000000,0.0000000000000000,'2019-01-23 13:55:21','2019-01-23 13:55:21'),(459,211,'usd',3,103,'Order',0.0000000000000000,1.0000000000000000,'2019-01-23 13:55:21','2019-01-23 13:55:21'),(460,202,'eth',4,104,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 13:55:42','2019-01-23 13:55:42'),(461,212,'eth',4,104,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 13:55:42','2019-01-23 13:55:42'),(462,212,'eth',4,58,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 13:55:42','2019-01-23 13:55:42'),(463,211,'usd',3,58,'Trade',1.0000000000000000,0.0000000000000000,'2019-01-23 13:55:42','2019-01-23 13:55:42'),(464,201,'usd',4,58,'Trade',0.0000000000000000,0.9985000000000000,'2019-01-23 13:55:42','2019-01-23 13:55:42'),(465,202,'eth',3,58,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 13:55:42','2019-01-23 13:55:42'),(466,201,'usd',3,105,'Order',1.0000000000000000,0.0000000000000000,'2019-01-23 13:56:02','2019-01-23 13:56:02'),(467,211,'usd',3,105,'Order',0.0000000000000000,1.0000000000000000,'2019-01-23 13:56:02','2019-01-23 13:56:02'),(468,202,'eth',4,106,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 13:56:25','2019-01-23 13:56:25'),(469,212,'eth',4,106,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 13:56:25','2019-01-23 13:56:25'),(470,212,'eth',4,59,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 13:56:25','2019-01-23 13:56:25'),(471,211,'usd',3,59,'Trade',1.0000000000000000,0.0000000000000000,'2019-01-23 13:56:25','2019-01-23 13:56:25'),(472,201,'usd',4,59,'Trade',0.0000000000000000,0.9985000000000000,'2019-01-23 13:56:25','2019-01-23 13:56:25'),(473,202,'eth',3,59,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 13:56:25','2019-01-23 13:56:25'),(474,201,'usd',3,107,'Order',1.0000000000000000,0.0000000000000000,'2019-01-23 13:58:39','2019-01-23 13:58:39'),(475,211,'usd',3,107,'Order',0.0000000000000000,1.0000000000000000,'2019-01-23 13:58:39','2019-01-23 13:58:39'),(476,202,'eth',3,108,'Order',0.1000000000000000,0.0000000000000000,'2019-01-23 13:58:51','2019-01-23 13:58:51'),(477,212,'eth',3,108,'Order',0.0000000000000000,0.1000000000000000,'2019-01-23 13:58:51','2019-01-23 13:58:51'),(478,212,'eth',3,60,'Trade',0.1000000000000000,0.0000000000000000,'2019-01-23 13:58:51','2019-01-23 13:58:51'),(479,211,'usd',3,60,'Trade',1.0000000000000000,0.0000000000000000,'2019-01-23 13:58:51','2019-01-23 13:58:51'),(480,201,'usd',3,60,'Trade',0.0000000000000000,0.9985000000000000,'2019-01-23 13:58:51','2019-01-23 13:58:51'),(481,202,'eth',3,60,'Trade',0.0000000000000000,0.0998500000000000,'2019-01-23 13:58:51','2019-01-23 13:58:51'); +/*!40000 ALTER TABLE `liabilities` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `markets` +-- + +DROP TABLE IF EXISTS `markets`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `markets` ( + `id` varchar(20) NOT NULL, + `ask_unit` varchar(10) NOT NULL, + `bid_unit` varchar(10) NOT NULL, + `ask_fee` decimal(17,16) NOT NULL DEFAULT '0.0000000000000000', + `bid_fee` decimal(17,16) NOT NULL DEFAULT '0.0000000000000000', + `min_ask_price` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `max_bid_price` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `min_ask_amount` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `min_bid_amount` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `ask_precision` tinyint(4) NOT NULL DEFAULT '8', + `bid_precision` tinyint(4) NOT NULL DEFAULT '8', + `position` int(11) NOT NULL DEFAULT '0', + `enabled` tinyint(1) NOT NULL DEFAULT '1', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_markets_on_ask_unit_and_bid_unit` (`ask_unit`,`bid_unit`), + KEY `index_markets_on_ask_unit` (`ask_unit`), + KEY `index_markets_on_bid_unit` (`bid_unit`), + KEY `index_markets_on_position` (`position`), + KEY `index_markets_on_enabled` (`enabled`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `markets` +-- + +LOCK TABLES `markets` WRITE; +/*!40000 ALTER TABLE `markets` DISABLE KEYS */; +INSERT INTO `markets` VALUES ('ethusd','eth','usd',0.0015000000000000,0.0015000000000000,0.0000000000000000,0.0000000000000000,0.0000000000000000,0.0000000000000000,4,4,1,1,'2019-01-22 15:18:03','2019-01-22 15:18:03'),('kyneth','kyn','eth',0.0015000000000000,0.0015000000000000,0.0000000000000000,0.0000000000000000,0.0000000000000000,0.0000000000000000,4,4,3,1,'2019-01-22 15:18:03','2019-01-22 15:18:03'),('trsteth','trst','eth',0.0015000000000000,0.0015000000000000,0.0000000000000000,0.0000000000000000,0.0000000000000000,0.0000000000000000,4,4,2,1,'2019-01-22 15:18:03','2019-01-22 15:18:03'); +/*!40000 ALTER TABLE `markets` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `members` +-- + +DROP TABLE IF EXISTS `members`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `members` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `uid` varchar(12) NOT NULL, + `email` varchar(255) NOT NULL, + `level` int(11) NOT NULL, + `role` varchar(16) NOT NULL, + `state` varchar(16) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_members_on_email` (`email`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `members` +-- + +LOCK TABLES `members` WRITE; +/*!40000 ALTER TABLE `members` DISABLE KEYS */; +INSERT INTO `members` VALUES (2,'ID535CA9B575','testmehelios+philliparuais@gmail.com',3,'admin','active','2019-01-22 15:44:19','2019-01-22 15:44:19'),(3,'ID79BF61C8A0','testmehelios+amyjbriggs@gmail.com',3,'member','active','2019-01-22 18:03:46','2019-01-22 18:03:46'),(4,'ID6FC9E9F399','testmehelios+davidtmoore@gmail.com',3,'member','active','2019-01-22 18:37:36','2019-01-22 18:37:36'),(5,'ID8CB21CC3A3','testmehelios+charmaineouellet@gmail.com',3,'member','active','2019-01-23 07:02:02','2019-01-23 08:48:57'),(6,'ID7CAF88CD33','iron@man.io',3,'admin','active','2019-01-23 08:54:39','2019-01-23 08:54:39'),(9,'ID1799AE7C6F','testmehelios+cecilevaillancourt@gmail.com',2,'member','active','2019-01-23 11:07:14','2019-01-23 13:54:21'),(10,'ID7E9639E27F','admin@devkube.com',3,'admin','active','2019-01-23 11:53:11','2019-01-23 11:53:11'); +/*!40000 ALTER TABLE `members` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `operations_accounts` +-- + +DROP TABLE IF EXISTS `operations_accounts`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `operations_accounts` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` mediumint(9) NOT NULL, + `type` varchar(10) NOT NULL, + `kind` varchar(30) NOT NULL, + `currency_type` varchar(10) NOT NULL, + `description` varchar(100) DEFAULT NULL, + `scope` varchar(10) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_operations_accounts_on_code` (`code`), + UNIQUE KEY `index_operations_accounts_on_type_and_kind_and_currency_type` (`type`,`kind`,`currency_type`), + KEY `index_operations_accounts_on_type` (`type`), + KEY `index_operations_accounts_on_currency_type` (`currency_type`), + KEY `index_operations_accounts_on_scope` (`scope`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `operations_accounts` +-- + +LOCK TABLES `operations_accounts` WRITE; +/*!40000 ALTER TABLE `operations_accounts` DISABLE KEYS */; +/*!40000 ALTER TABLE `operations_accounts` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `orders` +-- + +DROP TABLE IF EXISTS `orders`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `orders` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `bid` varchar(10) NOT NULL, + `ask` varchar(10) NOT NULL, + `market_id` varchar(20) NOT NULL, + `price` decimal(32,16) DEFAULT NULL, + `volume` decimal(32,16) NOT NULL, + `origin_volume` decimal(32,16) NOT NULL, + `fee` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `state` int(11) NOT NULL, + `type` varchar(8) NOT NULL, + `member_id` int(11) NOT NULL, + `ord_type` varchar(30) NOT NULL, + `locked` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `origin_locked` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `funds_received` decimal(32,16) DEFAULT '0.0000000000000000', + `trades_count` int(11) NOT NULL DEFAULT '0', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_orders_on_member_id` (`member_id`) USING BTREE, + KEY `index_orders_on_state` (`state`) USING BTREE, + KEY `index_orders_on_type_and_state_and_member_id` (`type`,`state`,`member_id`), + KEY `index_orders_on_type_and_state_and_market_id` (`type`,`state`,`market_id`), + KEY `index_orders_on_type_and_market_id` (`type`,`market_id`), + KEY `index_orders_on_type_and_member_id` (`type`,`member_id`) +) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `orders` +-- + +LOCK TABLES `orders` WRITE; +/*!40000 ALTER TABLE `orders` DISABLE KEYS */; +INSERT INTO `orders` VALUES (1,'usd','eth','ethusd',118.0000000000000000,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,23.6000000000000000,0.2000000000000000,2,'2019-01-23 07:22:04','2019-01-23 07:22:04'),(2,'usd','eth','ethusd',115.0000000000000000,0.0000000000000000,0.3000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,34.5000000000000000,0.3000000000000000,4,'2019-01-23 07:22:27','2019-01-23 07:22:27'),(3,'usd','eth','ethusd',112.0000000000000000,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,22.4000000000000000,0.2000000000000000,2,'2019-01-23 07:22:39','2019-01-23 07:22:39'),(4,'usd','eth','ethusd',108.0000000000000000,0.0000000000000000,0.4000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,43.2000000000000000,0.4000000000000000,1,'2019-01-23 07:22:47','2019-01-23 07:22:47'),(5,'usd','eth','ethusd',99.0000000000000000,0.9000000000000000,1.0000000000000000,0.0015000000000000,0,'OrderBid',4,'limit',89.1000000000000000,99.0000000000000000,0.1000000000000000,1,'2019-01-23 07:23:03','2019-01-23 11:43:50'),(6,'eth','kyn','kyneth',0.0050000000000000,300.0000000000000000,300.0000000000000000,0.0015000000000000,100,'OrderAsk',4,'limit',300.0000000000000000,300.0000000000000000,0.0000000000000000,0,'2019-01-23 07:27:11','2019-01-23 07:27:11'),(7,'eth','kyn','kyneth',0.0070000000000000,500.0000000000000000,500.0000000000000000,0.0015000000000000,100,'OrderAsk',4,'limit',500.0000000000000000,500.0000000000000000,0.0000000000000000,0,'2019-01-23 07:27:53','2019-01-23 07:27:53'),(8,'eth','kyn','kyneth',0.0100000000000000,800.0000000000000000,800.0000000000000000,0.0015000000000000,100,'OrderAsk',4,'limit',800.0000000000000000,800.0000000000000000,0.0000000000000000,0,'2019-01-23 07:28:19','2019-01-23 07:28:19'),(9,'eth','kyn','kyneth',0.0150000000000000,1000.0000000000000000,1000.0000000000000000,0.0015000000000000,100,'OrderAsk',4,'limit',1000.0000000000000000,1000.0000000000000000,0.0000000000000000,0,'2019-01-23 07:28:28','2019-01-23 07:28:28'),(10,'usd','eth','ethusd',119.0000000000000000,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderAsk',3,'limit',0.0000000000000000,0.2000000000000000,23.8000000000000000,2,'2019-01-23 07:32:23','2019-01-23 07:32:23'),(11,'usd','eth','ethusd',122.0000000000000000,0.0000000000000000,0.3000000000000000,0.0015000000000000,200,'OrderAsk',3,'limit',0.0000000000000000,0.3000000000000000,36.6000000000000000,2,'2019-01-23 07:32:39','2019-01-23 07:32:39'),(12,'usd','eth','ethusd',127.0000000000000000,0.5000000000000000,0.5000000000000000,0.0015000000000000,0,'OrderAsk',3,'limit',0.5000000000000000,0.5000000000000000,0.0000000000000000,0,'2019-01-23 07:32:49','2019-01-23 07:42:10'),(13,'usd','eth','ethusd',130.0000000000000000,0.5000000000000000,0.5000000000000000,0.0015000000000000,0,'OrderAsk',3,'limit',0.5000000000000000,0.5000000000000000,0.0000000000000000,0,'2019-01-23 07:32:58','2019-01-23 08:58:34'),(14,'usd','eth','ethusd',137.0000000000000000,0.0000000000000000,0.3000000000000000,0.0015000000000000,200,'OrderAsk',3,'limit',0.0000000000000000,0.3000000000000000,41.1000000000000000,2,'2019-01-23 07:33:13','2019-01-23 07:33:13'),(15,'eth','kyn','kyneth',0.0045000000000000,100.0000000000000000,100.0000000000000000,0.0015000000000000,100,'OrderBid',3,'limit',0.4500000000000000,0.4500000000000000,0.0000000000000000,0,'2019-01-23 07:37:32','2019-01-23 07:37:32'),(16,'eth','kyn','kyneth',0.0040000000000000,100.0000000000000000,100.0000000000000000,0.0015000000000000,100,'OrderBid',3,'limit',0.4000000000000000,0.4000000000000000,0.0000000000000000,0,'2019-01-23 07:37:47','2019-01-23 07:37:47'),(20,'eth','kyn','kyneth',0.0030000000000000,150.0000000000000000,150.0000000000000000,0.0015000000000000,100,'OrderBid',3,'limit',0.4500000000000000,0.4500000000000000,0.0000000000000000,0,'2019-01-23 07:43:19','2019-01-23 07:43:19'),(21,'eth','kyn','kyneth',0.0020000000000000,200.0000000000000000,200.0000000000000000,0.0015000000000000,100,'OrderBid',3,'limit',0.4000000000000000,0.4000000000000000,0.0000000000000000,0,'2019-01-23 07:43:34','2019-01-23 07:43:34'),(22,'eth','kyn','kyneth',0.0200000000000000,300.0000000000000000,300.0000000000000000,0.0015000000000000,100,'OrderAsk',3,'limit',300.0000000000000000,300.0000000000000000,0.0000000000000000,0,'2019-01-23 07:44:10','2019-01-23 07:44:10'),(23,'eth','kyn','kyneth',0.0500000000000000,500.0000000000000000,500.0000000000000000,0.0015000000000000,100,'OrderAsk',3,'limit',500.0000000000000000,500.0000000000000000,0.0000000000000000,0,'2019-01-23 07:45:28','2019-01-23 07:45:28'),(24,'usd','eth','ethusd',118.5000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,11.8500000000000000,0.1000000000000000,1,'2019-01-23 08:59:19','2019-01-23 08:59:19'),(25,'usd','eth','ethusd',118.5000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',3,'limit',0.0000000000000000,0.1000000000000000,11.8500000000000000,1,'2019-01-23 09:00:04','2019-01-23 09:00:04'),(26,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',4,'market',1.1900000000000000,13.0900000000000000,0.1000000000000000,1,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(27,'usd','eth','ethusd',117.0000000000000000,0.0000000000000000,0.2500000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,29.2500000000000000,0.2500000000000000,1,'2019-01-23 09:03:54','2019-01-23 09:03:54'),(28,'usd','eth','ethusd',116.0000000000000000,0.0000000000000000,0.2800000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,32.4800000000000000,0.2800000000000000,3,'2019-01-23 09:04:31','2019-01-23 09:04:31'),(29,'usd','eth','ethusd',114.0000000000000000,0.0000000000000000,0.2800000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,31.9200000000000000,0.2800000000000000,3,'2019-01-23 09:05:02','2019-01-23 09:05:02'),(30,'usd','eth','ethusd',113.0000000000000000,0.0000000000000000,0.2500000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,28.2500000000000000,0.2500000000000000,3,'2019-01-23 09:05:16','2019-01-23 09:05:16'),(31,'usd','eth','ethusd',111.0000000000000000,0.0000000000000000,0.2100000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,23.3100000000000000,0.2100000000000000,2,'2019-01-23 09:12:50','2019-01-23 09:12:50'),(32,'usd','eth','ethusd',125.0000000000000000,0.0000000000000000,0.0500000000000000,0.0015000000000000,200,'OrderAsk',3,'limit',0.0000000000000000,0.0500000000000000,6.2500000000000000,1,'2019-01-23 09:22:02','2019-01-23 09:22:02'),(33,'usd','eth','ethusd',135.0000000000000000,0.0000000000000000,0.0800000000000000,0.0015000000000000,200,'OrderAsk',3,'limit',0.0000000000000000,0.0800000000000000,10.8000000000000000,2,'2019-01-23 09:22:17','2019-01-23 09:22:17'),(34,'usd','eth','ethusd',140.0000000000000000,0.0000000000000000,0.0900000000000000,0.0015000000000000,200,'OrderAsk',3,'limit',0.0000000000000000,0.0900000000000000,12.6000000000000000,2,'2019-01-23 09:22:28','2019-01-23 09:22:28'),(35,'usd','eth','ethusd',150.0000000000000000,0.2300000000000000,0.3000000000000000,0.0015000000000000,0,'OrderAsk',3,'limit',0.2300000000000000,0.3000000000000000,10.5000000000000000,1,'2019-01-23 09:22:38','2019-01-23 13:51:15'),(36,'usd','eth','ethusd',160.0000000000000000,0.1000000000000000,0.1000000000000000,0.0015000000000000,0,'OrderAsk',3,'limit',0.1000000000000000,0.1000000000000000,0.0000000000000000,0,'2019-01-23 09:23:15','2019-01-23 13:51:15'),(37,'usd','eth','ethusd',170.0000000000000000,0.2000000000000000,0.2000000000000000,0.0015000000000000,0,'OrderAsk',3,'limit',0.2000000000000000,0.2000000000000000,0.0000000000000000,0,'2019-01-23 09:23:24','2019-01-23 13:51:14'),(38,'usd','eth','ethusd',119.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',3,'limit',0.0000000000000000,11.9000000000000000,0.1000000000000000,1,'2019-01-23 11:30:51','2019-01-23 11:30:51'),(40,'usd','eth','ethusd',118.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.1000000000000000,11.8000000000000000,1,'2019-01-23 11:31:21','2019-01-23 11:31:21'),(41,'usd','eth','ethusd',117.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.1000000000000000,11.8000000000000000,1,'2019-01-23 11:31:36','2019-01-23 11:31:36'),(44,'usd','eth','ethusd',110.0000000000000000,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,22.0000000000000000,0.2000000000000000,2,'2019-01-23 11:32:20','2019-01-23 11:32:20'),(45,'usd','eth','ethusd',115.0000000000000000,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,23.0000000000000000,0.2000000000000000,2,'2019-01-23 11:32:31','2019-01-23 11:32:31'),(46,'usd','eth','ethusd',NULL,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderBid',4,'market',2.4400000000000000,26.8400000000000000,0.2000000000000000,1,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(47,'usd','eth','ethusd',NULL,0.0000000000000000,0.4000000000000000,0.0015000000000000,200,'OrderAsk',3,'market',0.0000000000000000,0.4000000000000000,46.6500000000000000,2,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(48,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.1000000000000000,11.6000000000000000,1,'2019-01-23 11:32:53','2019-01-23 11:32:53'),(49,'usd','eth','ethusd',NULL,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderBid',4,'market',2.5200000000000000,27.7200000000000000,0.2000000000000000,3,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(50,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.1000000000000000,11.5300000000000000,2,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(51,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.1000000000000000,11.5000000000000000,1,'2019-01-23 11:33:43','2019-01-23 11:33:43'),(52,'usd','eth','ethusd',NULL,0.0000000000000000,0.3000000000000000,0.0015000000000000,200,'OrderBid',4,'market',4.1040000000000000,45.1440000000000000,0.3000000000000000,2,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(53,'usd','eth','ethusd',110.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.1000000000000000,11.5000000000000000,1,'2019-01-23 11:34:46','2019-01-23 11:34:46'),(54,'usd','eth','ethusd',113.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.1000000000000000,11.5000000000000000,2,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(55,'usd','eth','ethusd',115.0000000000000000,0.0000000000000000,0.1500000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,17.2500000000000000,0.1500000000000000,2,'2019-01-23 11:35:23','2019-01-23 11:35:23'),(56,'usd','eth','ethusd',110.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,11.0000000000000000,0.1000000000000000,2,'2019-01-23 11:35:54','2019-01-23 11:35:54'),(57,'usd','eth','ethusd',110.0000000000000000,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.2000000000000000,23.0000000000000000,2,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(58,'usd','eth','ethusd',115.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.1000000000000000,11.5000000000000000,2,'2019-01-23 11:36:23','2019-01-23 11:36:23'),(59,'usd','eth','ethusd',111.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,11.1000000000000000,0.1000000000000000,1,'2019-01-23 11:36:40','2019-01-23 11:36:40'),(60,'usd','eth','ethusd',115.0000000000000000,0.0000000000000000,0.4000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.4000000000000000,46.0000000000000000,5,'2019-01-23 11:36:59','2019-01-23 11:36:59'),(61,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.1000000000000000,11.4000000000000000,1,'2019-01-23 11:37:16','2019-01-23 11:37:16'),(62,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',4,'market',1.1500000000000000,12.6500000000000000,0.1000000000000000,2,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(63,'usd','eth','ethusd',NULL,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderBid',4,'market',2.3000000000000000,25.3000000000000000,0.2000000000000000,1,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(64,'usd','eth','ethusd',1000.0000000000000000,0.2000000000000000,0.2000000000000000,0.0015000000000000,0,'OrderAsk',4,'limit',0.2000000000000000,0.2000000000000000,0.0000000000000000,0,'2019-01-23 11:38:29','2019-01-23 11:43:50'),(65,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.1000000000000000,11.4000000000000000,1,'2019-01-23 11:38:49','2019-01-23 11:38:49'),(66,'usd','eth','ethusd',NULL,0.0000000000000000,0.0100000000000000,0.0015000000000000,200,'OrderBid',3,'market',0.1150000000000000,1.2650000000000000,0.0100000000000000,1,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(67,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.1000000000000000,11.3800000000000000,2,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(68,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',4,'market',1.1500000000000000,12.6500000000000000,0.1000000000000000,1,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(69,'usd','eth','ethusd',NULL,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.2000000000000000,22.6000000000000000,1,'2019-01-23 11:40:17','2019-01-23 11:40:17'),(70,'usd','eth','ethusd',NULL,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.2000000000000000,22.4300000000000000,2,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(71,'usd','eth','ethusd',110.0000000000000000,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.2000000000000000,22.2300000000000000,2,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(72,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',4,'market',1.3660000000000000,15.0260000000000000,0.1000000000000000,3,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(73,'usd','eth','ethusd',NULL,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.2000000000000000,22.1400000000000000,3,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(74,'usd','eth','ethusd',NULL,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.2000000000000000,22.0000000000000000,2,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(75,'usd','eth','ethusd',110.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,11.0000000000000000,0.1000000000000000,1,'2019-01-23 11:42:39','2019-01-23 11:42:39'),(76,'usd','eth','ethusd',110.0000000000000000,0.0600000000000000,0.2000000000000000,0.0015000000000000,0,'OrderAsk',4,'limit',0.0600000000000000,0.2000000000000000,15.4000000000000000,2,'2019-01-23 11:42:53','2019-01-23 11:43:49'),(77,'usd','eth','ethusd',NULL,0.0000000000000000,0.5000000000000000,0.0015000000000000,200,'OrderAsk',4,'market',0.0000000000000000,0.5000000000000000,53.1000000000000000,2,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(78,'usd','eth','ethusd',120.0000000000000000,0.2000000000000000,0.5000000000000000,0.0015000000000000,0,'OrderAsk',4,'limit',0.2000000000000000,0.5000000000000000,36.0000000000000000,3,'2019-01-23 11:44:05','2019-01-23 13:49:54'),(79,'usd','eth','ethusd',111.0000000000000000,0.1000000000000000,0.3000000000000000,0.0015000000000000,0,'OrderBid',4,'limit',11.1000000000000000,33.3000000000000000,0.2000000000000000,1,'2019-01-23 11:44:17','2019-01-23 13:49:54'),(80,'usd','eth','ethusd',111.0000000000000000,0.2000000000000000,0.2000000000000000,0.0015000000000000,0,'OrderBid',4,'limit',22.2000000000000000,22.2000000000000000,0.0000000000000000,0,'2019-01-23 11:45:44','2019-01-23 13:49:53'),(86,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',3,'market',1.2000000000000000,13.2000000000000000,0.1000000000000000,1,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(87,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',3,'market',1.2000000000000000,13.2000000000000000,0.1000000000000000,1,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(88,'usd','eth','ethusd',NULL,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',3,'market',1.2000000000000000,13.2000000000000000,0.1000000000000000,1,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(93,'usd','eth','ethusd',111.0000000000000000,0.0000000000000000,0.2000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.2000000000000000,22.2000000000000000,1,'2019-01-23 13:49:44','2019-01-23 13:49:44'),(94,'usd','eth','ethusd',1000.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',85.3000000000000000,100.0000000000000000,0.1000000000000000,2,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(95,'usd','eth','ethusd',1000.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.1000000000000000,100.0000000000000000,1,'2019-01-23 13:50:14','2019-01-23 13:50:14'),(96,'usd','eth','ethusd',1000.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',3,'limit',0.0000000000000000,100.0000000000000000,0.1000000000000000,1,'2019-01-23 13:51:37','2019-01-23 13:51:37'),(100,'usd','eth','ethusd',1000.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',4,'limit',0.0000000000000000,100.0000000000000000,0.1000000000000000,1,'2019-01-23 13:53:37','2019-01-23 13:53:37'),(101,'usd','eth','ethusd',10.0000000000000000,0.1000000000000000,0.1000000000000000,0.0015000000000000,0,'OrderBid',3,'limit',1.0000000000000000,1.0000000000000000,0.0000000000000000,0,'2019-01-23 13:54:10','2019-01-23 13:55:15'),(102,'usd','eth','ethusd',10.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.1000000000000000,100.0000000000000000,1,'2019-01-23 13:54:25','2019-01-23 13:54:25'),(103,'usd','eth','ethusd',10.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',3,'limit',0.0000000000000000,1.0000000000000000,0.1000000000000000,1,'2019-01-23 13:55:21','2019-01-23 13:55:21'),(104,'usd','eth','ethusd',10.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.1000000000000000,1.0000000000000000,1,'2019-01-23 13:55:42','2019-01-23 13:55:42'),(105,'usd','eth','ethusd',10.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',3,'limit',0.0000000000000000,1.0000000000000000,0.1000000000000000,1,'2019-01-23 13:56:02','2019-01-23 13:56:02'),(106,'usd','eth','ethusd',10.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',4,'limit',0.0000000000000000,0.1000000000000000,1.0000000000000000,1,'2019-01-23 13:56:25','2019-01-23 13:56:25'),(107,'usd','eth','ethusd',10.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderBid',3,'limit',0.0000000000000000,1.0000000000000000,0.1000000000000000,1,'2019-01-23 13:58:39','2019-01-23 13:58:39'),(108,'usd','eth','ethusd',10.0000000000000000,0.0000000000000000,0.1000000000000000,0.0015000000000000,200,'OrderAsk',3,'limit',0.0000000000000000,0.1000000000000000,1.0000000000000000,1,'2019-01-23 13:58:51','2019-01-23 13:58:51'); +/*!40000 ALTER TABLE `orders` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `payment_addresses` +-- + +DROP TABLE IF EXISTS `payment_addresses`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `payment_addresses` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `currency_id` varchar(10) NOT NULL, + `account_id` int(11) NOT NULL, + `address` varchar(95) DEFAULT NULL, + `secret` varchar(128) DEFAULT NULL, + `details` varchar(1024) NOT NULL DEFAULT '{}', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_payment_addresses_on_currency_id_and_address` (`currency_id`,`address`) +) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `payment_addresses` +-- + +LOCK TABLES `payment_addresses` WRITE; +/*!40000 ALTER TABLE `payment_addresses` DISABLE KEYS */; +INSERT INTO `payment_addresses` VALUES (1,'eth',1,'0xe40666e5297b20ed002c94a65f59f36ec2942608','wx/Iagy#QYZ)c7vAgI7wl/teJ+iymHSjmn2xc&p!iBfWFl5WkGtFJ@K0mTFUI!KM','{}','2019-01-22 15:26:03','2019-01-22 15:41:36'),(3,'trst',3,'0xe865edbfa15327dcedb0b507be7305f71a894582','ET9ttZ#p/1Iz)Gm5ULrGLHRRzYAvCrrc%k&ywtNFq3GsUc&()pVyQ6AvkmuOQuxx','{}','2019-01-22 15:26:04','2019-01-22 19:26:47'),(4,'eth',5,'0xa27db7f644fd329abe8fc4bced462c05ef2c92cf','38BzkxNM+%gWl%HO5@Yf8J#v!J8sw/IAOm7%YnKB21#%!o$?uO41fTL4N!IYU@nQ','{}','2019-01-22 15:44:19','2019-01-22 17:51:16'),(5,'eth',9,'0x9ddacb6dbfb8cb4d0d39cbd5a69cb76d92303edf','/hH?SAP1VwDpWi490?&idP$jT1/CxpjC*%#CQBNu+8giKKM+1!yr$h%gs$GmnZxH','{}','2019-01-22 18:03:46','2019-01-22 18:03:56'),(6,'trst',11,'0xb318d836f2c512497b7a6846f6ae20688b9cf639','T!uX##eRy139Zul7RbFq+G1UJV9!XEHM3cni+lz2X+#dIOB7fc$4u6$AAU1hejr#','{}','2019-01-22 18:20:46','2019-01-22 20:20:30'),(7,'kyn',10,'0x61922a271c24fab6b1fd8b822e259d883fad39c3','O/0ik%)be2nCM1QmLIr#nCAr$pH5*+2jv/(zDaFO&aeHDy*5BfWryjJ9/7*Sb&WJ','{}','2019-01-22 18:27:26','2019-01-22 19:35:56'),(8,'eth',13,'0x1ceb42cc7a7d0d60e1605e04567a463fc991e123','V1BfpYy@PB5fVNpOH!B*e0++VVnkh26gGKx4?8ir?vI8Te%78Dts(rX!B%rSmUAx','{}','2019-01-22 19:22:53','2019-01-22 19:22:57'),(9,'kyn',14,'0xec151f867b69704e0612c2bdd9c853fb57094a91','qAD3p&S20dZ&r($WjJm(*mN4!8@jcFaz8Tv2(B$0yBjdqbTHh$1kMFjDr%Sw!R&1','{}','2019-01-22 19:22:53','2019-01-22 19:37:55'),(10,'trst',15,'0xc0632e2a7db677a228b78e9974f15c98a90553c9','&+S3GCC*eROVoHH+df?/mYHf/fp8?h5xD5yEP91Zk%aJN5C)50Vn%)Z@s2i+DknY','{}','2019-01-22 19:22:53','2019-01-22 19:37:59'),(11,'kyn',6,'0xc122c4505bdb387754e19e9f292f0a822178f2a2','HNG7ubl?UUpJ)dKbE74/z6ZIM4Ub80$r%SK7yNm3IbYYI0%dWJ%Z@wM7kz!Rqmk6','{}','2019-01-23 08:19:04','2019-01-23 08:19:07'),(12,'trst',7,'0x7d66a0fd468b5defeacf9ad5b9f700ee06e9eced','LIX%@7(Q*765HG@+w6C%hE$GZ)ZSmeO3Vqd?SM1MgLfE*Tu1d)iGj/ZIT+&JsEC!','{}','2019-01-23 08:19:05','2019-01-23 08:19:10'),(13,'eth',17,'0xadba52efafdaf8ec2359b2fea69e071581ff0275','zG8&DfM*ul3voO(Ft0ofv(sFc(jqGum9MesUu0445Ywrae1s#ir2JmnZ7618CCXX','{}','2019-01-23 08:48:58','2019-01-23 08:49:01'),(14,'kyn',18,'0x49f35337a3025dcf7a62d46770f72f99457c91a5','XZ*wGQnzAPen8zOq5k2T)iTCk!u%QS5yUUN5Ap2iIezRscc?1mTwkDdx#g!YBxJp','{}','2019-01-23 08:49:01','2019-01-23 08:49:09'),(15,'trst',19,'0x65364bebdeed0184f207d7a2f49c81f986b179dc','%M7wM5B*3J!26W@SwU6g0h93zPKAIqDflY7nDG/aRQWgEOIzwqs#hkdktk4#&(E/','{}','2019-01-23 08:49:03','2019-01-23 08:49:14'),(16,'eth',21,'0xdfe9ae9496b70410c4fe466766d082581445a3e4','+d$1bTT&4UCruFaHHVt0y9SKntSA0rBFIgm*AQ5)Q3*IYpCRa9V&V$$4B/jZ?o6+','{}','2019-01-23 08:56:39','2019-01-23 08:56:42'),(17,'kyn',22,'0xb299f3f77b4a7e5fbc045702574b98477b2a8a02','@n0aGFSLQdjefJeFyWfltc5hv/QutFZbMhFSCW?ZCI+c8GvEAgcLnqkVF8id#qYA','{}','2019-01-23 08:56:40','2019-01-23 08:56:44'),(18,'trst',23,'0x55254af3236cafe816c8df83e891e90e69e75241','6!ETsQT+u/a7Zw2k(dqeQNbex*9+%tGdyH9f+gBSNGNB6YEHQMc6QPmuUa6hWrUF','{}','2019-01-23 08:56:41','2019-01-23 08:56:46'),(19,'eth',29,'0xed6675ad4e84c1096632bbf7df93ab8f7a52e2d1','+rA@r)@msq9WFj%WI8w$dud7DP)X&p#4VyMxIwHir/mhaOjFd@J/v6T+o!!AquRi','{}','2019-01-23 11:53:12','2019-01-23 11:53:14'),(20,'kyn',30,'0xfec9ba06907d5b0c7ad890e35dab65380479f37c','nH%5Grf$ODzYLo)nzJy?GGkf2c?c*)netey35V5jyEcdhl)yoh&P#nhzjPCa$rs4','{}','2019-01-23 11:53:15','2019-01-23 11:53:20'),(21,'trst',31,'0xa788a1e4bc7127f4ab8e4cf82a59fdc93f9c8450','VwfC?SzJFaW&G%D/)I7B!na9++F09keNdP&eZCQXMjGjC+UcSWx79R0zEB&ZsPAz','{}','2019-01-23 11:53:16','2019-01-23 11:53:25'); +/*!40000 ALTER TABLE `payment_addresses` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `revenues` +-- + +DROP TABLE IF EXISTS `revenues`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `revenues` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `code` int(11) NOT NULL, + `currency_id` varchar(255) NOT NULL, + `member_id` int(11) DEFAULT NULL, + `reference_id` int(11) DEFAULT NULL, + `reference_type` varchar(255) DEFAULT NULL, + `debit` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `credit` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_revenues_on_currency_id` (`currency_id`), + KEY `index_revenues_on_reference_type_and_reference_id` (`reference_type`,`reference_id`) +) ENGINE=InnoDB AUTO_INCREMENT=121 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `revenues` +-- + +LOCK TABLES `revenues` WRITE; +/*!40000 ALTER TABLE `revenues` DISABLE KEYS */; +INSERT INTO `revenues` VALUES (1,302,'eth',NULL,1,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 09:00:05','2019-01-23 09:00:05'),(2,301,'usd',NULL,1,'Trade',0.0000000000000000,0.0177750000000000,'2019-01-23 09:00:05','2019-01-23 09:00:05'),(3,302,'eth',NULL,2,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(4,301,'usd',NULL,2,'Trade',0.0000000000000000,0.0178500000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(5,302,'eth',NULL,3,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:30:51','2019-01-23 11:30:51'),(6,301,'usd',NULL,3,'Trade',0.0000000000000000,0.0178500000000000,'2019-01-23 11:30:51','2019-01-23 11:30:51'),(7,302,'eth',NULL,4,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:31:21','2019-01-23 11:31:21'),(8,301,'usd',NULL,4,'Trade',0.0000000000000000,0.0177000000000000,'2019-01-23 11:31:21','2019-01-23 11:31:21'),(9,302,'eth',NULL,5,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:31:36','2019-01-23 11:31:36'),(10,301,'usd',NULL,5,'Trade',0.0000000000000000,0.0177000000000000,'2019-01-23 11:31:36','2019-01-23 11:31:36'),(11,302,'eth',NULL,6,'Trade',0.0000000000000000,0.0003000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(12,301,'usd',NULL,6,'Trade',0.0000000000000000,0.0366000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(13,302,'eth',NULL,7,'Trade',0.0000000000000000,0.0003750000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(14,301,'usd',NULL,7,'Trade',0.0000000000000000,0.0438750000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(15,302,'eth',NULL,8,'Trade',0.0000000000000000,0.0002250000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(16,301,'usd',NULL,8,'Trade',0.0000000000000000,0.0261000000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(17,302,'eth',NULL,9,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:32:53','2019-01-23 11:32:53'),(18,301,'usd',NULL,9,'Trade',0.0000000000000000,0.0174000000000000,'2019-01-23 11:32:53','2019-01-23 11:32:53'),(19,302,'eth',NULL,10,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(20,301,'usd',NULL,10,'Trade',0.0000000000000000,0.0183000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(21,302,'eth',NULL,11,'Trade',0.0000000000000000,0.0000750000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(22,301,'usd',NULL,11,'Trade',0.0000000000000000,0.0093750000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(23,302,'eth',NULL,12,'Trade',0.0000000000000000,0.0000750000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(24,301,'usd',NULL,12,'Trade',0.0000000000000000,0.0101250000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(25,302,'eth',NULL,13,'Trade',0.0000000000000000,0.0000450000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(26,301,'usd',NULL,13,'Trade',0.0000000000000000,0.0052200000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(27,302,'eth',NULL,14,'Trade',0.0000000000000000,0.0001050000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(28,301,'usd',NULL,14,'Trade',0.0000000000000000,0.0120750000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(29,302,'eth',NULL,15,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:33:43','2019-01-23 11:33:43'),(30,301,'usd',NULL,15,'Trade',0.0000000000000000,0.0172500000000000,'2019-01-23 11:33:43','2019-01-23 11:33:43'),(31,302,'eth',NULL,16,'Trade',0.0000000000000000,0.0000450000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(32,301,'usd',NULL,16,'Trade',0.0000000000000000,0.0060750000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(33,302,'eth',NULL,17,'Trade',0.0000000000000000,0.0004050000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(34,301,'usd',NULL,17,'Trade',0.0000000000000000,0.0554850000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(35,302,'eth',NULL,18,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:34:46','2019-01-23 11:34:46'),(36,301,'usd',NULL,18,'Trade',0.0000000000000000,0.0172500000000000,'2019-01-23 11:34:46','2019-01-23 11:34:46'),(37,302,'eth',NULL,19,'Trade',0.0000000000000000,0.0000450000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(38,301,'usd',NULL,19,'Trade',0.0000000000000000,0.0051750000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(39,302,'eth',NULL,20,'Trade',0.0000000000000000,0.0001050000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(40,301,'usd',NULL,20,'Trade',0.0000000000000000,0.0120750000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(41,302,'eth',NULL,21,'Trade',0.0000000000000000,0.0001950000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(42,301,'usd',NULL,21,'Trade',0.0000000000000000,0.0224250000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(43,302,'eth',NULL,22,'Trade',0.0000000000000000,0.0001050000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(44,301,'usd',NULL,22,'Trade',0.0000000000000000,0.0120750000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(45,302,'eth',NULL,23,'Trade',0.0000000000000000,0.0001200000000000,'2019-01-23 11:36:23','2019-01-23 11:36:23'),(46,301,'usd',NULL,23,'Trade',0.0000000000000000,0.0138000000000000,'2019-01-23 11:36:23','2019-01-23 11:36:23'),(47,302,'eth',NULL,24,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:37:16','2019-01-23 11:37:16'),(48,301,'usd',NULL,24,'Trade',0.0000000000000000,0.0171000000000000,'2019-01-23 11:37:16','2019-01-23 11:37:16'),(49,302,'eth',NULL,25,'Trade',0.0000000000000000,0.0000300000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(50,301,'usd',NULL,25,'Trade',0.0000000000000000,0.0034500000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(51,302,'eth',NULL,26,'Trade',0.0000000000000000,0.0001200000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(52,301,'usd',NULL,26,'Trade',0.0000000000000000,0.0138000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(53,302,'eth',NULL,27,'Trade',0.0000000000000000,0.0003000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(54,301,'usd',NULL,27,'Trade',0.0000000000000000,0.0345000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(55,302,'eth',NULL,28,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:38:49','2019-01-23 11:38:49'),(56,301,'usd',NULL,28,'Trade',0.0000000000000000,0.0171000000000000,'2019-01-23 11:38:49','2019-01-23 11:38:49'),(57,302,'eth',NULL,29,'Trade',0.0000000000000000,0.0000150000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(58,301,'usd',NULL,29,'Trade',0.0000000000000000,0.0017250000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(59,302,'eth',NULL,30,'Trade',0.0000000000000000,0.0001200000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(60,301,'usd',NULL,30,'Trade',0.0000000000000000,0.0136800000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(61,302,'eth',NULL,31,'Trade',0.0000000000000000,0.0000300000000000,'2019-01-23 11:39:47','2019-01-23 11:39:47'),(62,301,'usd',NULL,31,'Trade',0.0000000000000000,0.0033900000000000,'2019-01-23 11:39:47','2019-01-23 11:39:47'),(63,302,'eth',NULL,32,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(64,301,'usd',NULL,32,'Trade',0.0000000000000000,0.0172500000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(65,302,'eth',NULL,33,'Trade',0.0000000000000000,0.0003000000000000,'2019-01-23 11:40:17','2019-01-23 11:40:17'),(66,301,'usd',NULL,33,'Trade',0.0000000000000000,0.0339000000000000,'2019-01-23 11:40:17','2019-01-23 11:40:17'),(67,302,'eth',NULL,34,'Trade',0.0000000000000000,0.0000450000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(68,301,'usd',NULL,34,'Trade',0.0000000000000000,0.0050850000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(69,302,'eth',NULL,35,'Trade',0.0000000000000000,0.0002550000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(70,301,'usd',NULL,35,'Trade',0.0000000000000000,0.0285600000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(71,302,'eth',NULL,36,'Trade',0.0000000000000000,0.0000450000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(72,301,'usd',NULL,36,'Trade',0.0000000000000000,0.0050400000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(73,302,'eth',NULL,37,'Trade',0.0000000000000000,0.0002550000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(74,301,'usd',NULL,37,'Trade',0.0000000000000000,0.0283050000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(75,302,'eth',NULL,38,'Trade',0.0000000000000000,0.0000150000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(76,301,'usd',NULL,38,'Trade',0.0000000000000000,0.0017250000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(77,302,'eth',NULL,39,'Trade',0.0000000000000000,0.0000450000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(78,301,'usd',NULL,39,'Trade',0.0000000000000000,0.0061650000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(79,302,'eth',NULL,40,'Trade',0.0000000000000000,0.0000900000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(80,301,'usd',NULL,40,'Trade',0.0000000000000000,0.0126000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(81,302,'eth',NULL,41,'Trade',0.0000000000000000,0.0000600000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(82,301,'usd',NULL,41,'Trade',0.0000000000000000,0.0066600000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(83,302,'eth',NULL,42,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(84,301,'usd',NULL,42,'Trade',0.0000000000000000,0.0166500000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(85,302,'eth',NULL,43,'Trade',0.0000000000000000,0.0000900000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(86,301,'usd',NULL,43,'Trade',0.0000000000000000,0.0099000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(87,302,'eth',NULL,44,'Trade',0.0000000000000000,0.0002100000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(88,301,'usd',NULL,44,'Trade',0.0000000000000000,0.0231000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(89,302,'eth',NULL,45,'Trade',0.0000000000000000,0.0000900000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(90,301,'usd',NULL,45,'Trade',0.0000000000000000,0.0099000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(91,302,'eth',NULL,46,'Trade',0.0000000000000000,0.0000600000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(92,301,'usd',NULL,46,'Trade',0.0000000000000000,0.0066000000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(93,302,'eth',NULL,47,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(94,301,'usd',NULL,47,'Trade',0.0000000000000000,0.0165000000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(95,302,'eth',NULL,48,'Trade',0.0000000000000000,0.0006000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(96,301,'usd',NULL,48,'Trade',0.0000000000000000,0.0648000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(97,302,'eth',NULL,49,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(98,301,'usd',NULL,49,'Trade',0.0000000000000000,0.0148500000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(99,302,'eth',NULL,50,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(100,301,'usd',NULL,50,'Trade',0.0000000000000000,0.0180000000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(101,302,'eth',NULL,51,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(102,301,'usd',NULL,51,'Trade',0.0000000000000000,0.0180000000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(103,302,'eth',NULL,52,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(104,301,'usd',NULL,52,'Trade',0.0000000000000000,0.0180000000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(105,302,'eth',NULL,53,'Trade',0.0000000000000000,0.0003000000000000,'2019-01-23 13:49:44','2019-01-23 13:49:44'),(106,301,'usd',NULL,53,'Trade',0.0000000000000000,0.0333000000000000,'2019-01-23 13:49:44','2019-01-23 13:49:44'),(107,302,'eth',NULL,54,'Trade',0.0000000000000000,0.0000450000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(108,301,'usd',NULL,54,'Trade',0.0000000000000000,0.0063000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(109,302,'eth',NULL,55,'Trade',0.0000000000000000,0.0001050000000000,'2019-01-23 13:50:07','2019-01-23 13:50:07'),(110,301,'usd',NULL,55,'Trade',0.0000000000000000,0.0157500000000000,'2019-01-23 13:50:07','2019-01-23 13:50:07'),(111,302,'eth',NULL,56,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 13:51:37','2019-01-23 13:51:37'),(112,301,'usd',NULL,56,'Trade',0.0000000000000000,0.1500000000000000,'2019-01-23 13:51:37','2019-01-23 13:51:37'),(113,302,'eth',NULL,57,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 13:54:25','2019-01-23 13:54:25'),(114,301,'usd',NULL,57,'Trade',0.0000000000000000,0.1500000000000000,'2019-01-23 13:54:25','2019-01-23 13:54:25'),(115,302,'eth',NULL,58,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 13:55:42','2019-01-23 13:55:42'),(116,301,'usd',NULL,58,'Trade',0.0000000000000000,0.0015000000000000,'2019-01-23 13:55:42','2019-01-23 13:55:42'),(117,302,'eth',NULL,59,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 13:56:25','2019-01-23 13:56:25'),(118,301,'usd',NULL,59,'Trade',0.0000000000000000,0.0015000000000000,'2019-01-23 13:56:25','2019-01-23 13:56:25'),(119,302,'eth',NULL,60,'Trade',0.0000000000000000,0.0001500000000000,'2019-01-23 13:58:51','2019-01-23 13:58:51'),(120,301,'usd',NULL,60,'Trade',0.0000000000000000,0.0015000000000000,'2019-01-23 13:58:51','2019-01-23 13:58:51'); +/*!40000 ALTER TABLE `revenues` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `schema_migrations` +-- + +DROP TABLE IF EXISTS `schema_migrations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `schema_migrations` ( + `version` varchar(255) NOT NULL, + UNIQUE KEY `unique_schema_migrations` (`version`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `schema_migrations` +-- + +LOCK TABLES `schema_migrations` WRITE; +/*!40000 ALTER TABLE `schema_migrations` DISABLE KEYS */; +INSERT INTO `schema_migrations` VALUES ('20180112151205'),('20180212115002'),('20180212115751'),('20180213160501'),('20180215124645'),('20180215131129'),('20180215144645'),('20180215144646'),('20180216145412'),('20180227163417'),('20180303121013'),('20180303211737'),('20180305111648'),('20180315132521'),('20180315145436'),('20180315150348'),('20180315185255'),('20180325001828'),('20180327020701'),('20180329145257'),('20180329145557'),('20180329154130'),('20180403115050'),('20180403134930'),('20180403135744'),('20180403145234'),('20180403231931'),('20180406080444'),('20180406185130'),('20180407082641'),('20180409115144'),('20180409115902'),('20180416160438'),('20180417085823'),('20180417111305'),('20180417175453'),('20180419122223'),('20180425094920'),('20180425152420'),('20180425224307'),('20180501082703'),('20180501141718'),('20180516094307'),('20180516101606'),('20180516104042'),('20180516105035'),('20180516110336'),('20180516124235'),('20180516131005'),('20180516133138'),('20180517084245'),('20180517101842'),('20180517110003'),('20180522105709'),('20180522121046'),('20180522165830'),('20180524170927'),('20180525101406'),('20180529125011'),('20180530122201'),('20180605104154'),('20180613140856'),('20180613144712'),('20180704103131'),('20180704115110'),('20180708014826'),('20180708171446'),('20180716115113'),('20180718113111'),('20180719123616'),('20180719172203'),('20180720165705'),('20180726110440'),('20180727054453'),('20180803144827'),('20180808144704'),('20180813105100'),('20180905112301'),('20180925123806'),('20181004114428'),('20181017114624'),('20181027192001'),('20181028000150'),('20181105102116'),('20181105102422'),('20181105102537'),('20181105120211'),('20181120113445'),('20181126101312'),('20181210162905'),('20181219115439'),('20181219133822'),('20181226170925'),('20181229051129'),('20190110164859'),('20190115165813'),('20190116140939'); +/*!40000 ALTER TABLE `schema_migrations` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `trades` +-- + +DROP TABLE IF EXISTS `trades`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `trades` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `price` decimal(32,16) NOT NULL, + `volume` decimal(32,16) NOT NULL, + `ask_id` int(11) NOT NULL, + `bid_id` int(11) NOT NULL, + `trend` int(11) NOT NULL, + `market_id` varchar(20) NOT NULL, + `ask_member_id` int(11) NOT NULL, + `bid_member_id` int(11) NOT NULL, + `funds` decimal(32,16) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_trades_on_ask_id` (`ask_id`) USING BTREE, + KEY `index_trades_on_bid_id` (`bid_id`) USING BTREE, + KEY `index_trades_on_market_id_and_created_at` (`market_id`,`created_at`), + KEY `index_trades_on_ask_member_id_and_bid_member_id` (`ask_member_id`,`bid_member_id`) +) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `trades` +-- + +LOCK TABLES `trades` WRITE; +/*!40000 ALTER TABLE `trades` DISABLE KEYS */; +INSERT INTO `trades` VALUES (1,118.5000000000000000,0.1000000000000000,25,24,1,'ethusd',3,4,11.8500000000000000,'2019-01-23 09:00:04','2019-01-23 09:00:04'),(2,119.0000000000000000,0.1000000000000000,10,26,1,'ethusd',3,4,11.9000000000000000,'2019-01-23 09:02:02','2019-01-23 09:02:02'),(3,119.0000000000000000,0.1000000000000000,10,38,1,'ethusd',3,3,11.9000000000000000,'2019-01-23 11:30:51','2019-01-23 11:30:51'),(4,118.0000000000000000,0.1000000000000000,40,1,0,'ethusd',4,4,11.8000000000000000,'2019-01-23 11:31:21','2019-01-23 11:31:21'),(5,118.0000000000000000,0.1000000000000000,41,1,1,'ethusd',4,4,11.8000000000000000,'2019-01-23 11:31:36','2019-01-23 11:31:36'),(6,122.0000000000000000,0.2000000000000000,11,46,1,'ethusd',3,4,24.4000000000000000,'2019-01-23 11:32:43','2019-01-23 11:32:43'),(7,117.0000000000000000,0.2500000000000000,47,27,0,'ethusd',3,4,29.2500000000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(8,116.0000000000000000,0.1500000000000000,47,28,0,'ethusd',3,4,17.4000000000000000,'2019-01-23 11:32:45','2019-01-23 11:32:45'),(9,116.0000000000000000,0.1000000000000000,48,28,1,'ethusd',4,4,11.6000000000000000,'2019-01-23 11:32:53','2019-01-23 11:32:53'),(10,122.0000000000000000,0.1000000000000000,11,49,1,'ethusd',3,4,12.2000000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(11,125.0000000000000000,0.0500000000000000,32,49,1,'ethusd',3,4,6.2500000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(12,135.0000000000000000,0.0500000000000000,33,49,1,'ethusd',3,4,6.7500000000000000,'2019-01-23 11:33:18','2019-01-23 11:33:18'),(13,116.0000000000000000,0.0300000000000000,50,28,0,'ethusd',4,4,3.4800000000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(14,115.0000000000000000,0.0700000000000000,50,2,0,'ethusd',4,4,8.0500000000000000,'2019-01-23 11:33:28','2019-01-23 11:33:28'),(15,115.0000000000000000,0.1000000000000000,51,2,1,'ethusd',4,4,11.5000000000000000,'2019-01-23 11:33:43','2019-01-23 11:33:43'),(16,135.0000000000000000,0.0300000000000000,33,52,1,'ethusd',3,4,4.0500000000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(17,137.0000000000000000,0.2700000000000000,14,52,1,'ethusd',3,4,36.9900000000000000,'2019-01-23 11:34:00','2019-01-23 11:34:00'),(18,115.0000000000000000,0.1000000000000000,53,2,0,'ethusd',4,4,11.5000000000000000,'2019-01-23 11:34:46','2019-01-23 11:34:46'),(19,115.0000000000000000,0.0300000000000000,54,2,1,'ethusd',4,4,3.4500000000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(20,115.0000000000000000,0.0700000000000000,54,45,1,'ethusd',4,4,8.0500000000000000,'2019-01-23 11:35:10','2019-01-23 11:35:10'),(21,115.0000000000000000,0.1300000000000000,57,45,1,'ethusd',4,4,14.9500000000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(22,115.0000000000000000,0.0700000000000000,57,55,1,'ethusd',4,4,8.0500000000000000,'2019-01-23 11:36:07','2019-01-23 11:36:07'),(23,115.0000000000000000,0.0800000000000000,58,55,1,'ethusd',4,4,9.2000000000000000,'2019-01-23 11:36:23','2019-01-23 11:36:23'),(24,114.0000000000000000,0.1000000000000000,61,29,0,'ethusd',4,4,11.4000000000000000,'2019-01-23 11:37:16','2019-01-23 11:37:16'),(25,115.0000000000000000,0.0200000000000000,58,62,1,'ethusd',4,4,2.3000000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(26,115.0000000000000000,0.0800000000000000,60,62,1,'ethusd',4,4,9.2000000000000000,'2019-01-23 11:37:39','2019-01-23 11:37:39'),(27,115.0000000000000000,0.2000000000000000,60,63,1,'ethusd',4,4,23.0000000000000000,'2019-01-23 11:37:46','2019-01-23 11:37:46'),(28,114.0000000000000000,0.1000000000000000,65,29,0,'ethusd',4,4,11.4000000000000000,'2019-01-23 11:38:49','2019-01-23 11:38:49'),(29,115.0000000000000000,0.0100000000000000,60,66,1,'ethusd',4,3,1.1500000000000000,'2019-01-23 11:38:54','2019-01-23 11:38:54'),(30,114.0000000000000000,0.0800000000000000,67,29,0,'ethusd',4,4,9.1200000000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(31,113.0000000000000000,0.0200000000000000,67,30,0,'ethusd',4,4,2.2600000000000000,'2019-01-23 11:39:46','2019-01-23 11:39:46'),(32,115.0000000000000000,0.1000000000000000,60,68,1,'ethusd',4,4,11.5000000000000000,'2019-01-23 11:40:09','2019-01-23 11:40:09'),(33,113.0000000000000000,0.2000000000000000,69,30,0,'ethusd',4,4,22.6000000000000000,'2019-01-23 11:40:17','2019-01-23 11:40:17'),(34,113.0000000000000000,0.0300000000000000,70,30,1,'ethusd',4,4,3.3900000000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(35,112.0000000000000000,0.1700000000000000,70,3,0,'ethusd',4,4,19.0400000000000000,'2019-01-23 11:40:27','2019-01-23 11:40:27'),(36,112.0000000000000000,0.0300000000000000,71,3,1,'ethusd',4,4,3.3600000000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(37,111.0000000000000000,0.1700000000000000,71,31,0,'ethusd',4,4,18.8700000000000000,'2019-01-23 11:41:20','2019-01-23 11:41:20'),(38,115.0000000000000000,0.0100000000000000,60,72,1,'ethusd',4,4,1.1500000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(39,137.0000000000000000,0.0300000000000000,14,72,1,'ethusd',3,4,4.1100000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(40,140.0000000000000000,0.0600000000000000,34,72,1,'ethusd',3,4,8.4000000000000000,'2019-01-23 11:41:30','2019-01-23 11:41:30'),(41,111.0000000000000000,0.0400000000000000,73,31,0,'ethusd',4,4,4.4400000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(42,111.0000000000000000,0.1000000000000000,73,59,1,'ethusd',4,4,11.1000000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(43,110.0000000000000000,0.0600000000000000,73,44,0,'ethusd',4,4,6.6000000000000000,'2019-01-23 11:41:43','2019-01-23 11:41:43'),(44,110.0000000000000000,0.1400000000000000,74,44,1,'ethusd',4,4,15.4000000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(45,110.0000000000000000,0.0600000000000000,74,56,1,'ethusd',4,4,6.6000000000000000,'2019-01-23 11:42:22','2019-01-23 11:42:22'),(46,110.0000000000000000,0.0400000000000000,76,56,1,'ethusd',4,4,4.4000000000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(47,110.0000000000000000,0.1000000000000000,76,75,1,'ethusd',4,4,11.0000000000000000,'2019-01-23 11:42:54','2019-01-23 11:42:54'),(48,108.0000000000000000,0.4000000000000000,77,4,0,'ethusd',4,4,43.2000000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(49,99.0000000000000000,0.1000000000000000,77,5,0,'ethusd',4,4,9.9000000000000000,'2019-01-23 11:43:32','2019-01-23 11:43:32'),(50,120.0000000000000000,0.1000000000000000,78,86,1,'ethusd',4,3,12.0000000000000000,'2019-01-23 13:38:04','2019-01-23 13:38:04'),(51,120.0000000000000000,0.1000000000000000,78,87,1,'ethusd',4,3,12.0000000000000000,'2019-01-23 13:38:07','2019-01-23 13:38:07'),(52,120.0000000000000000,0.1000000000000000,78,88,1,'ethusd',4,3,12.0000000000000000,'2019-01-23 13:38:08','2019-01-23 13:38:08'),(53,111.0000000000000000,0.2000000000000000,93,79,0,'ethusd',4,4,22.2000000000000000,'2019-01-23 13:49:44','2019-01-23 13:49:44'),(54,140.0000000000000000,0.0300000000000000,34,94,1,'ethusd',3,4,4.2000000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(55,150.0000000000000000,0.0700000000000000,35,94,1,'ethusd',3,4,10.5000000000000000,'2019-01-23 13:50:06','2019-01-23 13:50:06'),(56,1000.0000000000000000,0.1000000000000000,95,96,1,'ethusd',4,3,100.0000000000000000,'2019-01-23 13:51:37','2019-01-23 13:51:37'),(57,1000.0000000000000000,0.1000000000000000,102,100,1,'ethusd',4,4,100.0000000000000000,'2019-01-23 13:54:25','2019-01-23 13:54:25'),(58,10.0000000000000000,0.1000000000000000,104,103,0,'ethusd',4,3,1.0000000000000000,'2019-01-23 13:55:42','2019-01-23 13:55:42'),(59,10.0000000000000000,0.1000000000000000,106,105,1,'ethusd',4,3,1.0000000000000000,'2019-01-23 13:56:25','2019-01-23 13:56:25'),(60,10.0000000000000000,0.1000000000000000,108,107,1,'ethusd',3,3,1.0000000000000000,'2019-01-23 13:58:51','2019-01-23 13:58:51'); +/*!40000 ALTER TABLE `trades` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `transfers` +-- + +DROP TABLE IF EXISTS `transfers`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `transfers` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `key` int(11) NOT NULL, + `kind` varchar(30) NOT NULL, + `desc` varchar(255) DEFAULT '', + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_transfers_on_key` (`key`), + KEY `index_transfers_on_kind` (`kind`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `transfers` +-- + +LOCK TABLES `transfers` WRITE; +/*!40000 ALTER TABLE `transfers` DISABLE KEYS */; +/*!40000 ALTER TABLE `transfers` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `wallets` +-- + +DROP TABLE IF EXISTS `wallets`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `wallets` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `blockchain_key` varchar(32) DEFAULT NULL, + `currency_id` varchar(10) DEFAULT NULL, + `name` varchar(64) DEFAULT NULL, + `address` varchar(255) NOT NULL, + `kind` int(11) NOT NULL, + `nsig` int(11) DEFAULT NULL, + `gateway` varchar(20) NOT NULL DEFAULT '', + `settings` varchar(1000) NOT NULL DEFAULT '{}', + `max_balance` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000', + `parent` int(11) DEFAULT NULL, + `status` varchar(32) DEFAULT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `index_wallets_on_status` (`status`), + KEY `index_wallets_on_kind` (`kind`), + KEY `index_wallets_on_currency_id` (`currency_id`), + KEY `index_wallets_on_kind_and_currency_id_and_status` (`kind`,`currency_id`,`status`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `wallets` +-- + +LOCK TABLES `wallets` WRITE; +/*!40000 ALTER TABLE `wallets` DISABLE KEYS */; +INSERT INTO `wallets` VALUES (1,'eth-rinkeby','eth','Ethereum Deposit Wallet','0x2b9fBC10EbAeEc28a8Fc10069C0BC29E45eBEB9C',100,1,'parity','{\"uri\":\"http://parity:8545\",\"secret\":\"changeme\"}',0.0000000000000000,NULL,'active','2019-01-22 15:18:04','2019-01-22 15:18:04'),(2,'eth-rinkeby','eth','Ethereum Hot Wallet','0x5929589a8a566dab8734e83d6c846ab7b7fb5acd',310,1,'parity','{\"uri\":\"http://parity:8545\",\"secret\":\"test\"}',100.0000000000000000,NULL,'active','2019-01-22 15:18:04','2019-01-22 21:40:02'),(3,'eth-rinkeby','eth','Ethereum Warm Wallet','0x2b9fBC10EbAeEc28a8Fc10069C0BC29E45eBEB9C',320,1,'parity','{\"uri\":\"http://parity:8545\",\"secret\":\"test\"}',1000.0000000000000000,NULL,'active','2019-01-22 15:18:04','2019-01-22 15:18:04'),(4,'eth-rinkeby','kyn','Kayen Deposit Wallet','0xd5b4babbaced6ada70bc5251331f7494ad8f97f5',100,1,'parity','{\"uri\":\"http://parity:8545\",\"secret\":\"changeme\"}',0.0000000000000000,NULL,'active','2019-01-22 18:07:52','2019-01-22 19:26:18'),(5,'eth-rinkeby','trst','TRST Deposit Wallet','0x4f77b1b2b6ce79216fc9cc967a9ed016960acd60',100,1,'parity','{\"uri\":\"http://parity:8545\",\"secret\":\"changeme\"}',0.0000000000000000,NULL,'active','2019-01-22 18:08:08','2019-01-22 19:26:25'),(6,'eth-rinkeby','eth','Ethereum Fee Wallet','0x5929589a8a566dab8734e83d6c846ab7b7fb5acd',200,1,'parity','{\"uri\":\"http://parity:8545\",\"secret\":\"test\"}',0.0000000000000000,NULL,'active','2019-01-22 21:16:15','2019-01-22 21:40:16'),(7,'eth-rinkeby','kyn','KYN Hot Wallet','0x5929589a8a566dab8734e83d6c846ab7b7fb5acd',310,1,'parity','{\"uri\":\"http://parity:8545\",\"secret\":\"test\"}',0.0000000000000000,NULL,'active','2019-01-22 21:53:46','2019-01-22 21:53:46'); +/*!40000 ALTER TABLE `wallets` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `withdraws` +-- + +DROP TABLE IF EXISTS `withdraws`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `withdraws` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `account_id` int(11) NOT NULL, + `member_id` int(11) NOT NULL, + `currency_id` varchar(10) NOT NULL, + `amount` decimal(32,16) NOT NULL, + `fee` decimal(32,16) NOT NULL, + `txid` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, + `aasm_state` varchar(30) NOT NULL, + `block_number` int(11) DEFAULT NULL, + `sum` decimal(32,16) NOT NULL, + `type` varchar(30) NOT NULL, + `tid` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, + `rid` varchar(95) NOT NULL, + `created_at` datetime NOT NULL, + `updated_at` datetime NOT NULL, + `completed_at` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `index_withdraws_on_currency_id_and_txid` (`currency_id`,`txid`), + KEY `index_withdraws_on_currency_id` (`currency_id`), + KEY `index_withdraws_on_aasm_state` (`aasm_state`), + KEY `index_withdraws_on_account_id` (`account_id`), + KEY `index_withdraws_on_member_id` (`member_id`), + KEY `index_withdraws_on_type` (`type`), + KEY `index_withdraws_on_tid` (`tid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `withdraws` +-- + +LOCK TABLES `withdraws` WRITE; +/*!40000 ALTER TABLE `withdraws` DISABLE KEYS */; +/*!40000 ALTER TABLE `withdraws` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2019-01-31 17:58:37 diff --git a/data/parity/.gitkeep b/data/parity/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/QA-troubleshooting.md b/docs/QA-troubleshooting.md new file mode 100644 index 0000000..ae58c44 --- /dev/null +++ b/docs/QA-troubleshooting.md @@ -0,0 +1,94 @@ +
+ +# Alvand-P — QA و عیب‌یابی (Fibitex) + +چک‌لیست عملیاتی برای staging (`beta.fibitex.com`) و لوکال. جزئیات deploy: [`Docs/Fibitex-staging-deploy.md`](../../Docs/Fibitex-staging-deploy.md). + +## قبل از deploy + +- [ ] `git pull` روی `Update2026` +- [ ] `bundle install` (در صورت تغییر Gemfile) +- [ ] `rake render:config` — **بدون EPERM** روی `config/frontend/shahoo.env.js` +- [ ] Vault unsealed — [`scripts/unseal-vault.ps1`](../../scripts/unseal-vault.ps1) یا `rake vault:setup` +- [ ] `COMPOSE_FILE` درست (همه composeهای لازم) + +## render:config / EPERM + +| علامت | رفع | +|--------|-----| +| `shahoo.env.js` directory به‌جای فایل | پوشهٔ اشتباه را حذف؛ `rake render:config` دوباره | +| EPERM روی Windows | ترمینال admin یا exclude antivirus روی `config/` | +| تغییر template اعمال نشد | `rake render:config` نه فقط `restart` | + +## Vault sealed + +
+ +```bash +docker compose exec vault vault status +# Sealed → unseal با keys از ops +``` + +
+ +لوکال: `.\scripts\unseal-vault.ps1` + +## Compose logging — recreate نه restart + +`logging:` در compose فقط هنگام **create** کانتینر اعمال می‌شود. + +
+ +```bash +export COMPOSE_FILE=compose/app.yaml:compose/backend.yaml:compose/gateway.yaml:compose/proxy.yaml:compose/daemons.yaml:compose/frontend.yaml +docker compose -p fibitex up -d --force-recreate +docker inspect fibitex_peatio_1 --format '{{.HostConfig.LogConfig.Type}} {{.HostConfig.LogConfig.Config}}' +``` + +
+ +## دو stack Carbon موازی + +**هرگز** هم‌زمان `carbon` (legacy path) و `carbon_platform` با `-p carbon` up نکنید — لاگ و دیتا duplicate می‌شود. + +فقط: `docker compose -p carbon -f docker-compose.prod.yml -f docker-compose.traefik.yml` + +## Smoke tests + +
+ +```bash +curl -sS -o /dev/null -w '%{http_code}\n' https://beta.fibitex.com/ +curl -sS -o /dev/null -w '%{http_code}\n' https://shahoo.fibitex.com/health +docker compose -p fibitex ps +bash ~/main-code/scripts/check-docker-log-disk.sh +``` + +
+ +## دیسک / لاگ Docker + +| علامت | اقدام | +|--------|--------| +| root >85% | `check-docker-log-disk.sh` exit 1 — `sudo truncate-docker-logs.sh` | +| لاگ یک کانتینر >100MB | truncate (نیاز sudo) یا `--force-recreate` بعد از log rotation | +| cron | `crontab -l` — هر ۶ ساعت → `~/log-disk-check.log` | + +ارجاع: [`Docs/Fibitex-staging-deploy.md`](../../Docs/Fibitex-staging-deploy.md) §۸.۳، [`Docs/07-setup-server.md`](../../Docs/07-setup-server.md) §۶.۲ + +## Shahoo / BFF + +- BFF: [`Shahoo-BFF/README.md`](../../Shahoo-BFF/README.md) +- E2E: `.\scripts\test-shahoo-e2e.ps1` + +## مستندات مرتبط + +| سند | موضوع | +|-----|--------| +| [`Docs/Fibitex-staging-deploy.md`](../../Docs/Fibitex-staging-deploy.md) | Deploy staging | +| [`Docs/07-setup-server.md`](../../Docs/07-setup-server.md) | Production | +| [`Docs/06-setup-local.md`](../../Docs/06-setup-local.md) | لوکال | +| [`Docs/troubleshoot-barong-authz.md`](troubleshoot-barong-authz.md) | Barong authz | +| [`carbon_platform/Docs/QA-troubleshooting.md`](../../carbon_platform/Docs/QA-troubleshooting.md) | Carbon | + +
diff --git a/docs/aws-install.md b/docs/aws-install.md new file mode 100644 index 0000000..fcde79e --- /dev/null +++ b/docs/aws-install.md @@ -0,0 +1,83 @@ +# AWS Installation Guide + +## Step 1: Prepare the infrastructure + +Infrastructural requirements for the installation are: + +- An EC2 m5.xlarge **Debian** instance with a 200 GB disk storage +- An Elastic Container Registry repository with the baseapp image +- A DNS record to point to the machine(e.g. `example.domain.com`) + +Create these resources before starting the installation and provision them with your RSA key to be able to connect to the VM instance using SSH. + +## Step 2: Configure the instance + +Connect to the instance over SSH as a `root`/`admin` user and perform the following steps. + +### Core dependencies + +```bash +apt-get update +apt-get install -y -q git tmux gnupg2 dirmngr dbus htop curl libmariadbclient-dev-compat build-essential +``` + +### Docker installation + +```bash +curl -fsSL https://get.docker.com/ | bash +usermod -a -G docker $USER + +COMPOSE_VERSION="1.23.2" +COMPOSE_URL="https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" + +curl -L "$COMPOSE_URL" -o /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose +``` + +### User creation + +```bash + groupadd app + useradd --create-home --home /home/app --shell /bin/bash \ + --gid app --groups docker,sudo app +``` + +### Ruby installation + +As the `app` user(`sudo su app`), run: + +```bash +gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +curl -sSL https://get.rvm.io | bash -s stable +source /home/app/.rvm/scripts/rvm +rvm install --quiet-curl 2.6.1 +rvm use --default 2.6.1 +gem install bundler +``` + +## Step 3: Prepare the deployment + +Clone the opendax repo to `/home/app` + +```bash +git clone git@git.openware.com:opendax +``` + +`cd` into the `opendax` directory and prepare `config/app.yml` according to the [README](../README.md). + +When the configuration is ready, run + +```bash +bundle install +rake render:config +rake parity:import && \ + until rake wallet:create['deposit','http://0.0.0.0:8545','changeme']; do sleep 15; done && \ + rake wallet:create['hot','http://0.0.0.0:8545','changeme'] && \ + rake wallet:create['warm','http://0.0.0.0:8545','changeme'] && \ + rake render:config && \ + rake service:all && \ + chmod +x bin/install_webhook + ./bin/install_webhook +``` + +After the deployment process is finished, the frontend would be accessible from the domain provided in the configuration. \ No newline at end of file diff --git a/docs/images/OpenDAX-authorization.png b/docs/images/OpenDAX-authorization.png new file mode 100644 index 0000000..3ddc5e5 Binary files /dev/null and b/docs/images/OpenDAX-authorization.png differ diff --git a/docs/troubleshoot-barong-authz.md b/docs/troubleshoot-barong-authz.md new file mode 100644 index 0000000..120f3dc --- /dev/null +++ b/docs/troubleshoot-barong-authz.md @@ -0,0 +1,148 @@ +# Troubleshoot barong authorization process and envoy routing + +## Architecture overview + +Before establishing a connection to a microservice (for example ***rango***) envoy verifies the authorization by sending a request to ***barong authz***. Barong authz verifies the cookie (when using the UI) and the HMAC signature (when using API) and returns a signed token (JWT) if everything is valid. + +![OpenDAX authorization](./images/OpenDAX-authorization.png) + + +## Enable envoy debug logs + +To troubleshoot connection problems with a microservice of the stack, you can enable envoy logs to understand in which step the connection problem appears. + +To do so you need to: + +1. Edit *templates/compose/gateway.yaml.erb* + +2. Change *info* by *debug* in the following lines: + +```yaml + command: /usr/local/bin/envoy -l debug -c /etc/envoy/envoy.yaml +``` + +3. Render the configuration files + +```bash +rake render:config +``` + +4. Restart envoy + +```bash +docker-compose up -dV gateway +``` + +5. Finally you can inspect the envoy logs + +```bash +docker-compose logs -f --tail 100 gateway +``` + +Here are the relevant logs: + +1. Initial websocket connection +```log +gateway_1 | [2020-12-02 07:50:30.169][13][debug][http] [source/common/http/conn_manager_impl.cc:580] [C184][S12609685784760114286] request headers complete (end_stream=false): +gateway_1 | ':authority', 'www.app.local' +gateway_1 | ':path', '/api/v2/ranger/private/?stream=global.tickers' +gateway_1 | ':method', 'GET' +gateway_1 | 'user-agent', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36' +gateway_1 | 'accept-encoding', 'gzip, deflate' +gateway_1 | 'accept-language', 'en-US,en;q=0.9,fr;q=0.8' +gateway_1 | 'cache-control', 'no-cache' +gateway_1 | 'connection', 'Upgrade' +gateway_1 | 'cookie', '_barong_session=4cff598ee40d3d2ec38875ddc904fc46' +gateway_1 | 'origin', 'http://www.app.local' +gateway_1 | 'pragma', 'no-cache' +gateway_1 | 'sec-websocket-key', 'b16LunIyXls4CtNZ1lYWsw==' +gateway_1 | 'sec-websocket-extensions', 'permessage-deflate; client_max_window_bits' +gateway_1 | 'sec-websocket-version', '13' +gateway_1 | 'upgrade', 'websocket' +gateway_1 | 'x-forwarded-for', '172.20.0.1' +gateway_1 | 'x-forwarded-host', 'www.app.local' +gateway_1 | 'x-forwarded-port', '80' +gateway_1 | 'x-forwarded-proto', 'ws' +gateway_1 | 'x-forwarded-server', '41e065adb32e' +gateway_1 | 'x-real-ip', '172.20.0.1' +``` + +2. Request to Barong authz +```log +gateway_1 | [2020-12-02 07:50:30.183][13][debug][router] [source/common/router/router.cc:320] [C0][S3254558628791445120] cluster 'barong' match for URL '/api/v2/auth/api/v2/ranger/private/?stream=global.tickers' +gateway_1 | [2020-12-02 07:50:30.184][13][debug][router] [source/common/router/router.cc:381] [C0][S3254558628791445120] router decoding headers: +gateway_1 | ':method', 'GET' +gateway_1 | ':path', '/api/v2/auth/api/v2/ranger/private/?stream=global.tickers' +gateway_1 | ':authority', 'www.app.local' +gateway_1 | ':scheme', 'http' +gateway_1 | 'content-length', '0' +gateway_1 | 'x-forwarded-for', '172.20.0.1,172.20.0.8' +gateway_1 | 'cookie', '_barong_session=4cff598ee40d3d2ec38875ddc904fc46' +gateway_1 | 'user-agent', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36' +gateway_1 | 'x-forwarded-host', 'www.app.local' +gateway_1 | 'x-forwarded-proto', 'ws' +gateway_1 | 'x-envoy-internal', 'true' +gateway_1 | 'x-envoy-expected-rq-timeout-ms', '1000' +``` + +3. Routing the connection to rango + +```log +gateway_1 | [2020-12-02 07:50:30.220][13][debug][filter] [source/extensions/filters/http/ext_authz/ext_authz.cc:175] [C186][S2592169017517480399] ext_authz filter accepted the request +gateway_1 | [2020-12-02 07:50:30.220][13][debug][router] [source/common/router/router.cc:320] [C186][S2592169017517480399] cluster 'rango' match for URL '/api/v2/ranger/private/?stream=global.tickers' +gateway_1 | [2020-12-02 07:50:30.220][13][debug][router] [source/common/router/router.cc:381] [C186][S2592169017517480399] router decoding headers: +gateway_1 | ':authority', 'www.app.local' +gateway_1 | ':path', '/api/v2/ranger/private/?stream=global.tickers' +gateway_1 | ':method', 'GET' +gateway_1 | ':scheme', 'http' +gateway_1 | 'user-agent', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36' +gateway_1 | 'accept-encoding', 'gzip, deflate' +gateway_1 | 'accept-language', 'en-US,en;q=0.9,fr;q=0.8' +gateway_1 | 'cache-control', 'no-cache' +gateway_1 | 'connection', 'Upgrade' +gateway_1 | 'cookie', '_barong_session=4cff598ee40d3d2ec38875ddc904fc46' +gateway_1 | 'origin', 'http://www.app.local' +gateway_1 | 'pragma', 'no-cache' +gateway_1 | 'sec-websocket-key', 'tocGzAPK8TACk8zzRX7n3g==' +gateway_1 | 'sec-websocket-extensions', 'permessage-deflate; client_max_window_bits' +gateway_1 | 'sec-websocket-version', '13' +gateway_1 | 'upgrade', 'websocket' +gateway_1 | 'x-forwarded-for', '172.20.0.1' +gateway_1 | 'x-forwarded-host', 'www.app.local' +gateway_1 | 'x-forwarded-port', '80' +gateway_1 | 'x-forwarded-proto', 'ws' +gateway_1 | 'x-forwarded-server', '41e065adb32e' +gateway_1 | 'x-real-ip', '172.20.0.1' +gateway_1 | 'content-length', '0' +gateway_1 | 'x-envoy-internal', 'true' +gateway_1 | 'x-request-id', '5b87e64a-4155-498e-916c-b8b998725a71' +gateway_1 | 'x-envoy-expected-rq-timeout-ms', '15000' +gateway_1 | ':status', '200' +gateway_1 | 'authorization', 'Bearer eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2MDY4OTU0MzAsImV4cCI6MTYwNjg5OTAzMCwic3ViIjoic2Vzc2lvbiIsImlzcyI6ImJhcm9uZyIsImF1ZCI6WyJwZWF0aW8iLCJiYXJvbmciXSwianRpIjoiNTllNGIwNTA3YTgyMGNjMzYzMTIiLCJ1aWQiOiJJRDVGRkE5OERDMjciLCJlbWFpbCI6ImFkbWluQGJhcm9uZy5pbyIsInJvbGUiOiJhZG1pbiIsImxldmVsIjozLCJzdGF0ZSI6ImFjdGl2ZSIsInJlZmVycmFsX2lkIjpudWxsfQ.Br6-yujI5MgU_BktVDYNaEPNtHOMxQZbNS89deQfxNiPPkx6B8ZUDXL9og5DQ6nWBExlHydyPPcCSUvO5BCth_UWiuttY_ldy7TIr_JrXT0td8WN8fq8QadOWFuJ7wvMEklRGVKQmvOrooHNKz_WwcY4xmaSO3SVgQdFSkmt626MOXmo9Wa3nYsL6EafCMe--9PHWop4L-B1w5ndvbGuGLbJaqEktXsudOX0A9Js2sKuHPxSe8QJKN5XwmOFPAWM28-VkaU5cmshMK2CwJaSRhVoL0gIi9VUGpFVVJ1ciD0VHjRfxuFTzph7utRuO_M9N-bweLL8YCCA8RkwlVyuLg' +gateway_1 | 'content-type', 'text/html; charset=utf-8' +gateway_1 | 'cache-control', 'no-cache' +gateway_1 | 'set-cookie', '_barong_session=4cff598ee40d3d2ec38875ddc904fc46; path=/; expires=Thu, 03 Dec 2020 07:50:30 GMT; HttpOnly' +gateway_1 | 'x-request-id', '8ff80928-9091-40b0-b6f0-c0b46f8d72fe' +gateway_1 | 'x-runtime', '0.031033' +gateway_1 | 'vary', 'Origin' +gateway_1 | 'transfer-encoding', 'chunked' +gateway_1 | 'x-envoy-upstream-service-time', '37' +``` + + +## Authz configuration + +In case of authorization problem check the following configuration files: + +1. *config/barong/authz_rules.yml* +This file contains the default public endpoints and blocked endpoints. +If you have a problem accessing a public endpoint make sure the URL is present in the *rules.pass* section. + +2. *templates/config/barong/seeds.yml.erb* +Check the *permissions* section to make sure the role of the user is allowed to access the resource. + +Run the following command to apply the changes: + +```bash +rake service:setup +``` diff --git a/docs/ubuntu-install.md b/docs/ubuntu-install.md new file mode 100644 index 0000000..1da7154 --- /dev/null +++ b/docs/ubuntu-install.md @@ -0,0 +1,91 @@ +# Install OpenDax in Ubuntu 18.04 + +## Step 1: Install Docker + +To install Docker you will need to do those steps with `sudo` or login as root user with `sudo -i` + +Create a Unix user for holding your application +``` +groupadd app +useradd -d /home/app -s `which bash` -g app -m app +``` + +### Installing from apt-get + +First, update your existing list of packages: + +``` +apt update +``` + +Next, install a few prerequisite packages which let apt use packages over HTTPS: + +``` +apt install apt-transport-https ca-certificates curl software-properties-common +``` + +Then add the GPG key for the official Docker repository to your system: + +``` +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - +``` + +Add the Docker repository to APT sources: + +``` +add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" +``` + +Next, update the package database with the Docker packages from the newly added repo: + +``` +apt update +``` + +Make sure you are about to install from the Docker repo instead of the default Ubuntu repo: + +Finally, install Docker: + +``` +apt install docker-ce +``` + +Docker should now be installed, the daemon started, and the process enabled to start on boot. Check that it's running: + +``` +systemctl status docker +``` + +Add your app user into the docker group + +``` +usermod -aG docker app +``` + +## Step 2: Install Docker Compose + +Run this command to download the latest version of Docker Compose: + +``` +curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + +chmod +x /usr/local/bin/docker-compose +``` + +## Step 3: Clone OpenDax + +Login to your app user: +``` +su - app +``` + +Clone opendax repository +``` +cd $HOME +git clone https://github.com/rubykube/opendax.git +cd opendax +``` + +## Step 4: Clone your frontend + +Edit config file `config/app.yml` diff --git a/lib/opendax/config_loader.rb b/lib/opendax/config_loader.rb new file mode 100644 index 0000000..ec87aaa --- /dev/null +++ b/lib/opendax/config_loader.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'yaml' + +module Opendax + # Loads config/app.yml and deep-merges an environment overlay when present. + # + # Overlay resolution (first match wins): + # 1. OPENDAX_ENV=local|staging|production → config/app.{env}.yml + # 2. If OPENDAX_ENV unset and config/app.local.yml exists → use local overlay + # + # Never commit real secrets to config/app.yml — use app.local.yml or app.production.yml. + module ConfigLoader + BASE_PATH = 'config/app.yml' + + module_function + + def load + base = load_yaml_hash!(BASE_PATH, 'base config') + overlay_path = resolve_overlay_path + return base unless overlay_path && File.exist?(overlay_path) + + overlay = load_yaml_hash!(overlay_path, 'overlay config') + deep_merge(base, overlay) + end + + def load_yaml_hash!(path, label) + data = YAML.load_file(path) + return data if data.is_a?(Hash) + + raise TypeError, + "#{label} #{path} must be a YAML mapping (Hash), got #{data.class}. " \ + 'Check syntax — quote values that contain colons (e.g. database passwords).' + end + + def resolve_overlay_path + env = ENV['OPENDAX_ENV'].to_s.strip + if env.empty? + return 'config/app.local.yml' if File.exist?('config/app.local.yml') + + return nil + end + + "config/app.#{env}.yml" + end + + def active_overlay + path = resolve_overlay_path + path if path && File.exist?(path) + end + + def deep_merge(base, overlay) + unless base.is_a?(Hash) && overlay.is_a?(Hash) + raise TypeError, + "deep_merge expects Hash + Hash, got #{base.class} + #{overlay.class}" + end + + base.merge(overlay) do |key, old_val, new_val| + if old_val.is_a?(Hash) && new_val.is_a?(Hash) + deep_merge(old_val, new_val) + elsif old_val.is_a?(Hash) && !new_val.is_a?(Hash) + raise TypeError, + "Config type mismatch at #{key}: base has Hash but overlay has " \ + "#{new_val.class}. Quote scalar values in app.staging.yml (passwords with ':' need quotes)." + else + new_val + end + end + end + end +end diff --git a/lib/opendax/payload.rb b/lib/opendax/payload.rb new file mode 100644 index 0000000..b0c9db7 --- /dev/null +++ b/lib/opendax/payload.rb @@ -0,0 +1,46 @@ +require 'jwt' + +module Opendax + + class Error < StandardError + end + + class Payload + def initialize(params) + @secret = params[:secret] + @expire = params[:expire] || 600 + + raise Opendax::Error.new unless @secret + raise Opendax::Error.new unless @expire > 0 + end + + def generate!(params) + raise Opendax::Error.new unless params[:service] + raise Opendax::Error.new unless params[:image] + + token = params.merge({ + 'iat': Time.now.to_i, + 'exp': (Time.now + @expire).to_i + }) + + JWT.encode token, @secret, 'HS256' + end + + def decode!(token) + JWT.decode(token, @secret, true, { + algorithm: 'HS256' + }).first + end + + def safe_decode(token) + begin + decode!(token) + rescue JWT::ExpiredSignature + rescue JWT::ImmatureSignature + rescue JWT::VerificationError + rescue JWT::DecodeError + nil + end + end + end +end diff --git a/lib/opendax/renderer.rb b/lib/opendax/renderer.rb new file mode 100644 index 0000000..1b27e06 --- /dev/null +++ b/lib/opendax/renderer.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +require 'openssl' +require 'sshkey' +require 'pathname' +require 'yaml' +require 'base64' +require 'fileutils' + +module Opendax + # Renderer is class for rendering Opendax templates. + class Renderer + TEMPLATE_PATH = Pathname.new('./templates') + + BARONG_KEY = 'config/secrets/barong.key' + APPLOGIC_KEY = 'config/secrets/applogic.key' + SSH_KEY = 'config/secrets/app.key' + + def render + @config ||= config + @utils ||= utils + @name ||= @config['app']['name'].downcase + @barong_key ||= OpenSSL::PKey::RSA.new(File.read(BARONG_KEY), '') + @applogic_key ||= OpenSSL::PKey::RSA.new(File.read(APPLOGIC_KEY), '') + @barong_private_key ||= Base64.urlsafe_encode64(@barong_key.to_pem) + @barong_public_key ||= Base64.urlsafe_encode64(@barong_key.public_key.to_pem) + @applogic_private_key ||= Base64.urlsafe_encode64(@applogic_key.to_pem) + @applogic_public_key ||= Base64.urlsafe_encode64(@applogic_key.public_key.to_pem) + + Dir.glob("#{TEMPLATE_PATH}/**/*.erb", File::FNM_DOTMATCH).each do |file| + output_file = template_name(file) + FileUtils.chmod 0o644, output_file if File.exist?(output_file) + render_file(file, output_file) + FileUtils.chmod 0o444, output_file if @config['render_protect'] + end + end + + def render_file(file, out_file) + puts "Rendering #{out_file}" + result = ERB.new(File.read(file), trim_mode: '-').result(binding) + dir = File.dirname(out_file) + FileUtils.mkdir(dir) unless Dir.exist?(dir) + File.write(out_file, result) + end + + def ssl_helper(arg) + @config['ssl']['enabled'] ? arg << 's' : arg + end + + def template_name(file) + path = Pathname.new(file) + out_path = path.relative_path_from(TEMPLATE_PATH).sub('.erb', '') + + File.join('.', out_path) + end + + def render_keys + generate_key(BARONG_KEY) + generate_key(APPLOGIC_KEY) + generate_key(SSH_KEY, public: true) + end + + def generate_key(filename, public: false) + return if File.file?(filename) + + key = SSHKey.generate(type: 'RSA', bits: 2048) + File.write(filename, key.private_key) + File.write("#{filename}.pub", key.ssh_public_key) if public + end + + def config + Opendax::ConfigLoader.load + end + + def utils + YAML.load_file('./config/utils.yml') + end + end +end diff --git a/lib/opendax/vault.rb b/lib/opendax/vault.rb new file mode 100644 index 0000000..c404ce4 --- /dev/null +++ b/lib/opendax/vault.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module Opendax + class Vault + POLICIES_NAMES = ["barong", "finex_engine", "peatio_rails", "peatio_crypto", "peatio_upstream", "peatio_matching"] + + def vault_secrets_path + 'config/vault-secrets.yml' + end + + def vault_exec(command) + `docker-compose exec -T vault sh -c '#{command}'` + end + + def secrets(command, endpoints, options = '') + endpoints.each { |endpoint| vault_exec("vault secrets #{command} #{options} #{endpoint}") } + end + + def setup + puts '----- Checking Vault status -----' + vault_status = YAML.safe_load(vault_exec('vault status -format yaml')) + + return if vault_status.nil? + + if vault_status['initialized'] + puts '----- Vault is initialized -----' + begin + vault_secrets = YAML.safe_load(File.read(vault_secrets_path)) + rescue SystemCallError => e + puts 'Vault keys are missing' + return + end + vault_root_token = vault_secrets['root_token'] + unseal_keys = vault_secrets['unseal_keys_b64'][0, 3] + else + puts '----- Initializing Vault -----' + vault_init_output = YAML.safe_load(vault_exec('vault operator init -format yaml --recovery-shares=3 --recovery-threshold=2')) + File.write(vault_secrets_path, YAML.dump(vault_init_output)) + vault_root_token = vault_init_output['root_token'] + unseal_keys = vault_init_output['unseal_keys_b64'][0, 3] + end + + if vault_status['sealed'] + puts '----- Unsealing Vault -----' + unseal_keys.each { |key| vault_exec("vault operator unseal #{key}") } + else + puts '----- Vault is unsealed -----' + end + + return vault_root_token if vault_status['initialized'] + + puts '----- Vault login -----' + vault_exec("vault login #{vault_root_token}") + + puts '----- Configuring the endpoints -----' + secrets('enable', %w[totp transit]) + secrets('disable', ['secret']) + secrets('enable', ['kv'], '-path=secret -version=1') + vault_root_token + end + + def load_policies(deployment_name, vault_root_token) + puts '----- Vault login -----' + vault_exec("vault login #{vault_root_token}") + + tokens = {} + POLICIES_NAMES.each do |policy| + name = "#{deployment_name.downcase}_#{policy}" + + puts "Loading #{name} policy..." + vault_exec("vault policy write #{name} /tmp/policies/#{policy}.hcl") + + puts "Creating the #{name} token..." + vault_token_create_output = YAML.safe_load(vault_exec("vault token create -policy=#{name} -renewable=true -ttl=240h -period=240h -format=yaml")) + tokens["#{policy}_token"] = vault_token_create_output["auth"]["client_token"] + end + + tokens + end + end +end diff --git a/lib/opendax/webhook.rb b/lib/opendax/webhook.rb new file mode 100644 index 0000000..6fb4b7c --- /dev/null +++ b/lib/opendax/webhook.rb @@ -0,0 +1,74 @@ +require 'sinatra/base' +require 'json' +require 'yaml' + +require_relative 'payload' +require_relative 'renderer' + +class Webhook < Sinatra::Base + CONFIG_PATH = 'config/app.yml'.freeze + + set :show_exceptions, false + + def initialize + super + @services = %w[barong peatio frontend AdminTower applogic finex-engine finex-api] + secret = ENV['WEBHOOK_JWT_SECRET'] + raise 'WEBHOOK_JWT_SECRET is not set' if secret.to_s.empty? + @decoder = Opendax::Payload.new(secret: secret) + end + + def update_config(service, image) + config = YAML.load_file(CONFIG_PATH) + config["images"][service] = image + File.open(CONFIG_PATH, 'w') {|f| f.write config.to_yaml } + end + + before do + content_type 'application/json' + end + + get '/deploy/ping' do + 'pong' + end + + get '/deploy/:token' do |token| + decoded = @decoder.safe_decode(token) + return answer(400, 'invalid token') unless decoded + + service = decoded['service'] + image = decoded['image'] + + return answer(400, 'service is not specified') unless service + return answer(400, 'image is not specified') unless image + return answer(404, 'unknown service') unless @services.include? service + return answer(400, 'invalid image') if (%r(^(([-_\w\.]){,20}(\/|:))+([-\w\.]{,20})$) =~ image) == nil + + system "docker image pull #{image}" + + unless $?.success? + system("docker image inspect #{image} > /dev/null") + return answer(404, 'invalid image') unless $?.success? + end + + if $?.success? + update_config(service, image) + + renderer = Opendax::Renderer.new + renderer.render + + system "docker-compose up -Vd #{service}" + end + + return answer(500, 'could not restart container') unless $?.success? + return answer(200, "service #{service} updated with image #{image}") + end + + def answer(response_status, message) + status response_status + + { + message: message + }.to_json + end +end diff --git a/lib/tasks/audit.rake b/lib/tasks/audit.rake new file mode 100644 index 0000000..63cf915 --- /dev/null +++ b/lib/tasks/audit.rake @@ -0,0 +1,22 @@ +namespace :audit do + desc 'Print CVE audit commands (run via Docker on this machine)' + task :help do + puts <<~HELP + Fibitex dependency CVE audit — see Docs/10-cve-audit.md + + Ruby (Dena): + docker run --rm -v "#{Dir.pwd}/../Dena:/app" -w /app ruby:2.6.6 bash -c "gem install bundler:2.1.4 bundler-audit --no-document && bundle audit check --update" + + Ruby (Dalan): + docker run --rm -v "#{Dir.pwd}/../Dalan:/app" -w /app ruby:2.6.6 bash -c "gem install bundler:2.1.4 bundler-audit --no-document && bundle audit check --update" + + OSV (summary): + docker run --rm -v "#{Dir.pwd}/../Dena:/src" ghcr.io/google/osv-scanner:latest -L /src/Gemfile.lock + docker run --rm -v "#{Dir.pwd}/../Dalan:/src" ghcr.io/google/osv-scanner:latest -L /src/Gemfile.lock + docker run --rm -v "#{Dir.pwd}/../Gereh:/src" ghcr.io/google/osv-scanner:latest -L /src/yarn.lock + + Config secrets check: + bundle exec rake config:check + HELP + end +end diff --git a/lib/tasks/config.rake b/lib/tasks/config.rake new file mode 100644 index 0000000..5839c64 --- /dev/null +++ b/lib/tasks/config.rake @@ -0,0 +1,47 @@ +namespace :config do + desc 'Verify config/app.yml contains no real secrets (safe for git)' + task :check do + require_relative '../opendax/config_loader' + + raw = YAML.load_file('config/app.yml') + leaks = [] + + check_value = lambda do |path, value| + return if value.nil? + return unless value.is_a?(String) + + str = value.strip + return if str.empty? || str == 'changeme' + + if str.match?(/\As\.[A-Za-z0-9]{20,}\z/) + leaks << "#{path}: looks like a Vault token" + elsif path.include?('password') && str != 'changeme' + leaks << "#{path}: non-placeholder password" + end + end + + walk = lambda do |node, prefix| + case node + when Hash + node.each { |k, v| walk.call(v, prefix.empty? ? k.to_s : "#{prefix}.#{k}") } + when Array + node.each_with_index { |v, i| walk.call(v, "#{prefix}[#{i}]") } + else + check_value.call(prefix, node) + end + end + + walk.call(raw, '') + + if leaks.any? + puts 'FAIL: config/app.yml may contain secrets:' + leaks.each { |l| puts " - #{l}" } + puts 'Move sensitive values to config/app.local.yml or config/app.production.yml' + exit 1 + end + + overlay = Opendax::ConfigLoader.active_overlay + puts 'OK: config/app.yml looks safe for git' + puts "Active overlay: #{overlay || 'none'}" + end +end diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake new file mode 100644 index 0000000..b0c4b05 --- /dev/null +++ b/lib/tasks/db.rake @@ -0,0 +1,32 @@ +namespace :db do + + def mysql_cli + return "mysql -u root -h db -P 3306 -pchangeme" + end + + desc 'Create database' + task :create do + sh 'docker-compose run --rm peatio bundle exec rake db:create' + sh 'docker-compose run --rm barong bundle exec rake db:create' + end + + desc 'Load database dump' + task :load => :create do + sh %Q{cat data/mysql/peatio_production.sql | docker-compose run --rm db #{mysql_cli} peatio_production} + sh %Q{cat data/mysql/barong_production.sql | docker-compose run --rm db #{mysql_cli} barong_production} + sh 'docker-compose run --rm peatio bundle exec rake db:migrate' + sh 'docker-compose run --rm barong bundle exec rake db:migrate' + end + + desc 'Drop all databases' + task :drop do + sh %q(docker-compose run --rm db /bin/sh -c "mysql -u root -h db -P 3306 -pchangeme -e 'DROP DATABASE peatio_production'") + sh %q(docker-compose run --rm db /bin/sh -c "mysql -u root -h db -P 3306 -pchangeme -e 'DROP DATABASE barong_production'") + sh %q(docker-compose run --rm db /bin/sh -c "mysql -u root -h db -P 3306 -pchangeme -e 'DROP DATABASE superset'") + end + + desc 'Database Console' + task :console do + sh "docker-compose run --rm db #{mysql_cli}" + end +end diff --git a/lib/tasks/docker.rake b/lib/tasks/docker.rake new file mode 100644 index 0000000..9a543b1 --- /dev/null +++ b/lib/tasks/docker.rake @@ -0,0 +1,11 @@ +namespace :docker do + desc 'Stop all runnning docker contrainers' + task :down do + sh 'docker-compose down' + end + + desc 'Clean up all docker volumes' + task :clean do + sh 'docker volume prune -f' + end +end diff --git a/lib/tasks/payload.rake b/lib/tasks/payload.rake new file mode 100644 index 0000000..35c2ebd --- /dev/null +++ b/lib/tasks/payload.rake @@ -0,0 +1,18 @@ +require_relative '../opendax/payload' +require 'faraday' + +namespace :payload do + desc 'Generate JWT' + task :send, [:service, :image, :url] do |_, args| + secret = ENV['WEBHOOK_JWT_SECRET'] + abort 'WEBHOOK_JWT_SECRET not set' if secret.to_s.empty? + coder = Opendax::Payload.new(secret: secret) + jwt = coder.generate!(service: args.service, image: args.image) + url = "#{args.url}/deploy/#{jwt}" + response = Faraday::Connection.new.get(url) do |request| + request.options.timeout = 300 + end + pp response.body + fail unless response.status == 200 + end +end diff --git a/lib/tasks/render.rake b/lib/tasks/render.rake new file mode 100644 index 0000000..f5f1bd5 --- /dev/null +++ b/lib/tasks/render.rake @@ -0,0 +1,17 @@ + +require_relative '../opendax/renderer' + +namespace :render do + desc 'Render configuration and compose files and keys' + task :config do + if (overlay = Opendax::ConfigLoader.active_overlay) + puts "Using config overlay: #{overlay}" + else + puts 'Using config/app.yml only (no overlay)' + end + + renderer = Opendax::Renderer.new + renderer.render_keys + renderer.render + end +end diff --git a/lib/tasks/service.rake b/lib/tasks/service.rake new file mode 100644 index 0000000..24ee63c --- /dev/null +++ b/lib/tasks/service.rake @@ -0,0 +1,347 @@ +namespace :service do + ENV['APP_DOMAIN'] = @config['app']['domain'] + + @switch = Proc.new do |args, start, stop| + case args.command + when 'start' + start.call + when 'stop' + stop.call + when 'restart' + stop.call + start.call + else + puts "unknown command #{args.command}" + end + end + + desc 'Run Traefik (reverse-proxy)' + task :proxy, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting the proxy -----' + File.new('config/acme.json', File::CREAT, 0600) unless File.exist? 'config/acme.json' + sh 'docker-compose up -d proxy' + end + + def stop + puts '----- Stopping the proxy -----' + sh 'docker-compose rm -fs proxy' + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc 'Run backend (vault db redis rabbitmq)' + task :backend, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting dependencies -----' + sh 'docker-compose up -d vault db redis rabbitmq' + sleep 7 # time for db to start, we can get connection refused without sleeping + end + + def stop + puts '----- Stopping dependencies -----' + sh 'docker-compose rm -fs vault db redis rabbitmq' + end + + + @switch.call(args, method(:start), method(:stop)) + end + + desc 'Run influxdb' + task :influxdb, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting influxdb -----' + sh 'docker-compose up -d influxdb' + puts 'Wait 5 second for influx' + sleep(5) + sh 'docker-compose exec influxdb bash -c "cat peatio.sql | influx"' + end + + def stop + puts '----- Stopping influxdb -----' + sh 'docker-compose rm -fs influxdb' + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc '[Optional] Run arke-maker' + task :arke_maker, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting arke -----' + sh 'docker-compose up -d arke-maker' + end + + def stop + puts '----- Stopping arke -----' + sh 'docker-compose rm -fs arke-maker' + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc '[Optional] Run daemons (rango, peatio daemons, barong sidekiq)' + task :daemons, [:command] do |_task, args| + @daemons = %w[rango blockchain cron_job upstream deposit deposit_coin_address withdraw_coin influx_writer barong_sidekiq] + + if @config['finex']['enabled'] + @daemons |= %w[finex-engine finex-api] + else + @daemons |= %w[matching order_processor trade_executor] + end + + args.with_defaults(:command => 'start') + + def start + puts '----- Starting daemons -----' + sh "docker-compose up -d #{@daemons.join(' ')}" + end + + def stop + puts '----- Stopping daemons -----' + sh "docker-compose rm -fs #{@daemons.join(' ')}" + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc '[Optional] Run cryptonodes' + task :cryptonodes, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting cryptonodes -----' + sh 'docker-compose up -d parity' + if @config['bitcoind']['enabled'] + sh 'docker-compose up -d bitcoind' + end + end + + def stop + puts '----- Stopping cryptonodes -----' + sh 'docker-compose rm -fs parity' + if @config['bitcoind']['enabled'] + sh 'docker-compose rm -fs bitcoind' + end + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc 'Run setup hooks for peatio, barong' + task :setup, [:command] => ['vault:setup', 'vault:load_policies'] do |task, args| + if args.command != 'stop' + Rake::Task["render:config"].execute + puts '----- Running hooks -----' + sh 'docker-compose run --rm peatio bash -c "./bin/link_config && bundle exec rake db:create db:migrate"' + sh 'docker-compose run --rm peatio bash -c "./bin/link_config && bundle exec rake db:seed"' + sh 'docker-compose run --rm barong bash -c "./bin/init_config && bundle exec rake db:create db:migrate"' + sh 'docker-compose run --rm barong bash -c "./bin/link_config && bundle exec rake db:seed"' + if ENV.fetch('FIBITEX_SEED_TEST_USERS', 'true') != 'false' + puts '----- Seeding test users and balances -----' + sh 'docker-compose run --rm barong bash -c "bundle exec rails runner ./lib/seed_test_users.rb"' + sh 'docker-compose run --rm peatio bash -c "ruby ./bin/link_config && bundle exec rails runner ./lib/seed_test_balances.rb"' + end + end + end + + desc 'Run mikro app (barong, peatio)' + task :app, [:command] => [:backend, :setup] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting app -----' + sh 'docker-compose up -d peatio barong gateway' + end + + def stop + puts '----- Stopping app -----' + sh 'docker-compose rm -fs peatio barong gateway' + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc 'Run the frontend application' + task :frontend, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting the frontend -----' + sh 'docker-compose up -d frontend' + end + + def stop + puts '----- Stopping the frontend -----' + sh 'docker-compose rm -fs frontend' + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc 'Run the tower application' + task :AdminTower, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting the AdminTower -----' + sh 'docker-compose up -d AdminTower' + end + + def stop + puts '----- Stopping the AdminTower -----' + sh 'docker-compose rm -fs AdminTower' + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc 'Run Mailer' + task :mailer, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting Mailer -----' + sh 'docker-compose up -d mailer' + end + + def stop + puts '----- Stopping Mailer -----' + sh 'docker-compose rm -fs mailer' + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc '[Optional] Run monitoring' + task :monitoring, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting monitoring -----' + sh 'docker-compose up -d prometheus' + sh 'docker-compose up -d grafana' + sh 'docker-compose up -d alertmanager' + sh 'docker-compose up -d loki' + sh 'docker-compose up -d promtail' + sh 'docker-compose up -d scope' + sh 'docker-compose up -d node-exporter' + sh 'docker-compose up -d cadvisor' + end + + def stop + puts '----- Stopping monitoring -----' + sh 'docker-compose rm -fs prometheus' + sh 'docker-compose rm -fs grafana' + sh 'docker-compose rm -fs alertmanager' + sh 'docker-compose rm -fs loki' + sh 'docker-compose rm -fs promtail' + sh 'docker-compose rm -fs scope' + sh 'docker-compose rm -fs node-exporter' + sh 'docker-compose rm -fs cadvisor' + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc '[Optional] Run superset' + task :superset, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + conf = @utils['superset'] + init_params = [ + '--app', 'superset', + '--firstname', 'Admin', + '--lastname', 'Superset', + '--username', conf['username'], + '--email', conf['email'], + '--password', conf['password'] + ].join(' ') + + puts '----- Initializing Superset -----' + sh [ + 'docker-compose run --rm superset', + 'sh -c "', + "fabmanager create-admin #{init_params}", + '&& superset db upgrade', + # '&& superset load_examples', + '&& superset init"' + ].join(' ') + + puts '----- Starting Superset -----' + sh 'docker-compose up -d superset' + end + + def stop + puts '----- Stopping Superset -----' + sh 'docker-compose rm -fs superset' + end + + @switch.call(args, method(:start), method(:stop)) + end + + desc '[Optional] Run Blog' + task :blog, [:command] do |task, args| + args.with_defaults(:command => 'start') + + def start + puts '----- Starting Blog_db -----' + sh 'docker-compose up -d blog_db' + puts '----- Starting Blog -----' + sh 'docker-compose up -d blog' + end + + def stop + puts '----- Stopping Blog -----' + sh 'docker-compose rm -fs blog' + puts '----- Stopping Blog_db -----' + sh 'docker-compose rm -fs blog_db' + end + + @switch.call(args, method(:start), method(:stop)) + end + + + desc 'Set up and start all services with dependencies (does not run optional ones)' + task :all, [:command] => ['versions:update', 'render:config'] do |task, args| + args.with_defaults(:command => 'start') + + def start + Rake::Task["service:proxy"].invoke('start') + Rake::Task["service:backend"].invoke('start') + Rake::Task["service:influxdb"].invoke('start') + puts 'Wait 5 second for backend' + sleep(5) + Rake::Task["service:setup"].invoke('start') + Rake::Task["service:app"].invoke('start') + Rake::Task["service:frontend"].invoke('start') + Rake::Task["service:AdminTower"].invoke('start') + Rake::Task["service:mailer"].invoke('start') + Rake::Task["service:daemons"].invoke('start') + end + + def stop + Rake::Task["service:proxy"].invoke('stop') + Rake::Task["service:backend"].invoke('stop') + Rake::Task["service:influxdb"].invoke('stop') + Rake::Task["service:setup"].invoke('stop') + Rake::Task["service:app"].invoke('stop') + Rake::Task["service:frontend"].invoke('stop') + Rake::Task["service:AdminTower"].invoke('stop') + Rake::Task["service:mailer"].invoke('stop') + Rake::Task["service:daemons"].invoke('stop') + end + + @switch.call(args, method(:start), method(:stop)) + end +end diff --git a/lib/tasks/terraform.rake b/lib/tasks/terraform.rake new file mode 100644 index 0000000..bec608f --- /dev/null +++ b/lib/tasks/terraform.rake @@ -0,0 +1,16 @@ +namespace :terraform do + desc 'Initialize the Terraform configuration' + task :init do + Dir.chdir('terraform') { sh 'terraform init' } + end + + desc 'Apply the Terraform configuration' + task :apply => ['render:config', :init] do + Dir.chdir('terraform') { sh 'terraform apply' } + end + + desc 'Destroy the Terraform infrastructure' + task :destroy do + Dir.chdir('terraform') { sh 'terraform destroy' } + end +end diff --git a/lib/tasks/test_seed.rake b/lib/tasks/test_seed.rake new file mode 100644 index 0000000..b9db917 --- /dev/null +++ b/lib/tasks/test_seed.rake @@ -0,0 +1,15 @@ +namespace :test do + desc 'Seed test users (Barong + Peatio balances) for local/test environments' + task seed: :environment do + if ENV.fetch('FIBITEX_SEED_TEST_USERS', 'true') == 'false' + puts 'SKIP test:seed (FIBITEX_SEED_TEST_USERS=false)' + next + end + + puts '----- Seeding test users (Barong) -----' + sh 'docker-compose run --rm barong bash -c "bundle exec rails runner ./lib/seed_test_users.rb"' + + puts '----- Seeding test balances (Peatio) -----' + sh 'docker-compose run --rm peatio bash -c "ruby ./bin/link_config && bundle exec rails runner ./lib/seed_test_balances.rb"' + end +end diff --git a/lib/tasks/toolbox.rake b/lib/tasks/toolbox.rake new file mode 100644 index 0000000..0caa5ca --- /dev/null +++ b/lib/tasks/toolbox.rake @@ -0,0 +1,12 @@ +namespace :toolbox do + desc 'Run the toolbox' + task :run do + run_cmd = %w[docker-compose run --rm toolbox run] + + YAML.safe_load(File.read('config/toolbox.yaml')) + .transform_keys { |k| '--' << k } + .each_pair { |k, v| run_cmd << k << v.to_s } + + sh *run_cmd + end +end diff --git a/lib/tasks/vault.rake b/lib/tasks/vault.rake new file mode 100644 index 0000000..7fc97ad --- /dev/null +++ b/lib/tasks/vault.rake @@ -0,0 +1,25 @@ + +require_relative '../opendax/vault' + +namespace :vault do + desc 'Initialize, unseal and set secrets for Vault' + task :setup do + vault = Opendax::Vault.new + vault_root_token = vault.setup + unless vault_root_token.nil? + @config["vault"]["root_token"] = vault_root_token + File.open(CONFIG_PATH, 'w') { |f| YAML.dump(@config, f) } + end + end + + task :load_policies do + vault = Opendax::Vault.new + vault_tokens = vault.load_policies(@config["app"]["name"], @config["vault"]["root_token"]) + unless vault_tokens.empty? + vault_tokens.each do |k, v| + @config["vault"][k] = v + File.open(CONFIG_PATH, 'w') { |f| YAML.dump(@config, f) } + end + end + end +end diff --git a/lib/tasks/vendor.rake b/lib/tasks/vendor.rake new file mode 100644 index 0000000..e118736 --- /dev/null +++ b/lib/tasks/vendor.rake @@ -0,0 +1,11 @@ +namespace :vendor do + desc 'Clone the frontend apps repos into vendor/' + task :clone do + puts '----- Clone the frontend apps repos -----' + puts + @config['vendor'].each do |name, repo_url| + sh "git clone #{repo_url} vendor/#{name}" + puts + end + end +end diff --git a/lib/tasks/versions.rake b/lib/tasks/versions.rake new file mode 100644 index 0000000..1f1c56b --- /dev/null +++ b/lib/tasks/versions.rake @@ -0,0 +1,33 @@ +require 'faraday' + +namespace :versions do + desc 'Fetch global image versions and update config/app.yaml' + task :update do + unless @config['updateVersions'] + puts "To enable version updates, set updateVersions to true" + next + end + + puts "Fetching latest global versions" + response = Faraday.get 'https://raw.githubusercontent.com/openware/versions/master/opendax/2-6/versions.yaml' + + if response.status >= 400 || response.status >= 500 + raise "Error fetching global versions, got #{response.body}" + end + + versions = YAML.load(response.body) + + versions.each { |k, v| update_image_tag(k, v['image']['tag']) if @config['images'].key? k } + + File.write(CONFIG_PATH, YAML.dump(@config)) + + puts 'Version update complete!' + end +end + +def update_image_tag(component, tag) + image = @config['images'][component].split(':') + image[-1] = tag + + @config['images'][component] = image.join(':') +end diff --git a/lib/tasks/wallets.rake b/lib/tasks/wallets.rake new file mode 100644 index 0000000..2d1fa52 --- /dev/null +++ b/lib/tasks/wallets.rake @@ -0,0 +1,20 @@ +require 'faraday' +require 'json' +require 'yaml' + +namespace :wallet do + desc 'Generate ethereum wallet from a cryptonode' + task :create, [:kind,:url,:secret] do |_, args| + response = Faraday::Connection.new.post(args.url) do |request| + request.headers["Content-Type"] = "application/json" + request.body = "{\"jsonrpc\":\"2.0\",\"method\":\"personal_newAccount\",\"params\":[\"#{args.secret}\"],\"id\":1}" + request.options.timeout = 300 + end + address = JSON.parse(response.body)['result'] + puts "----- Generating a new #{args.kind} wallet -----", "Address: " + address + + @config['wallets']['eth'].find { |w| w['kind'] == args.kind }.update('address' => address, 'secret' => args.secret) + + File.open(CONFIG_PATH, 'w') {|f| f.write @config.to_yaml } + end +end diff --git a/scripts/bootstrap-app-staging.rb b/scripts/bootstrap-app-staging.rb new file mode 100644 index 0000000..77126b6 --- /dev/null +++ b/scripts/bootstrap-app-staging.rb @@ -0,0 +1,71 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Build config/app.staging.yml from app.production.yml (preferred) or example template. +# Usage: ruby scripts/bootstrap-app-staging.rb +# +# Run from Alvand-P root. Does not overwrite if app.staging.yml is already a valid Hash +# unless BOOTSTRAP_FORCE=1. + +require 'yaml' + +ROOT = File.expand_path('..', __dir__) +STAGING_PATH = File.join(ROOT, 'config/app.staging.yml') +PRODUCTION_PATH = File.join(ROOT, 'config/app.production.yml') +EXAMPLE_PATH = File.join(ROOT, 'config/app.staging.yml.example') + +def load_hash(path) + return nil unless File.exist?(path) + + data = YAML.load_file(path) + return data if data.is_a?(Hash) + + warn "WARN: #{path} is #{data.class}, not Hash — ignored" + nil +end + +def deep_merge(base, overlay) + base.merge(overlay) do |_key, old_val, new_val| + if old_val.is_a?(Hash) && new_val.is_a?(Hash) + deep_merge(old_val, new_val) + else + new_val + end + end +end + +staging_overlay = { + 'app' => { + 'domain' => 'fibitex.com', + 'subdomain' => 'beta', + 'shahoo_subdomain' => 'shahoo' + }, + 'images' => { + 'peatio' => 'custom/dena:1', + 'barong' => 'custom/dalan:1', + 'frontend' => 'custom/gereh:1', + 'gereh' => 'custom/gereh:1', + 'shahoo' => 'custom/shahoo:1', + 'shahoo_bff' => 'custom/shahoo-bff:1' + } +} + +existing = load_hash(STAGING_PATH) +if existing && ENV['BOOTSTRAP_FORCE'] != '1' + puts "OK: #{STAGING_PATH} already exists and is a valid Hash." + puts 'Set BOOTSTRAP_FORCE=1 to regenerate.' + exit 0 +end + +source = load_hash(PRODUCTION_PATH) || load_hash(EXAMPLE_PATH) +unless source + warn 'ERROR: Need config/app.production.yml or config/app.staging.yml.example' + exit 1 +end + +merged = deep_merge(source, staging_overlay) +File.write(STAGING_PATH, merged.to_yaml) +puts "Wrote #{STAGING_PATH}" +puts 'Next:' +puts ' export OPENDAX_ENV=staging' +puts ' bundle exec rake render:config' diff --git a/scripts/check-email-dns.sh b/scripts/check-email-dns.sh new file mode 100644 index 0000000..4ad77b1 --- /dev/null +++ b/scripts/check-email-dns.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# Check SPF/DKIM/DMARC DNS for Fibitex email deliverability. +# Usage: bash scripts/check-email-dns.sh [domain] +# Example: bash scripts/check-email-dns.sh fibitex.com + +set -euo pipefail + +DOMAIN="${1:-fibitex.com}" +MAIL_HOST="mail.${DOMAIN}" + +echo "=== Email DNS check: ${DOMAIN} ===" +echo + +echo "--- Mail server A record (${MAIL_HOST}) ---" +dig +short "${MAIL_HOST}" A || true +echo + +echo "--- SPF (TXT @ ${DOMAIN}) ---" +dig +short "${DOMAIN}" TXT | grep -i spf || echo "WARN: no SPF found" +echo + +echo "--- DKIM (default._domainkey.${DOMAIN}) ---" +dig +short "default._domainkey.${DOMAIN}" TXT || echo "WARN: no DKIM at default selector (try mail._domainkey)" +dig +short "mail._domainkey.${DOMAIN}" TXT 2>/dev/null || true +echo + +echo "--- DMARC (_dmarc.${DOMAIN}) ---" +dig +short "_dmarc.${DOMAIN}" TXT || echo "WARN: no DMARC found" +echo + +echo "--- MX (${DOMAIN}) ---" +dig +short "${DOMAIN}" MX || true +echo + +echo "Done. Fix WARN lines in Cloudflare / mail panel." +echo "Full guide: Docs/13-email-deliverability-fibitex.md" diff --git a/scripts/validate-app-overlay.rb b/scripts/validate-app-overlay.rb new file mode 100644 index 0000000..6287331 --- /dev/null +++ b/scripts/validate-app-overlay.rb @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Validate overlay YAML files parse as Hash. +# Usage: ruby scripts/validate-app-overlay.rb [path] + +require 'yaml' + +path = ARGV[0] || 'config/app.staging.yml' +unless File.exist?(path) + warn "Missing: #{path}" + exit 1 +end + +data = YAML.load_file(path) +if data.is_a?(Hash) + puts "OK: #{path} => Hash (#{data.keys.size} top-level keys)" + puts "Keys: #{data.keys.join(', ')}" + exit 0 +end + +warn "FAIL: #{path} => #{data.class}" +warn 'The file must start with key: value pairs (see config/app.staging.yml.example).' +warn 'If you pasted only a password or IP, recreate the full file.' +exit 1 diff --git a/spec/opendax/payload_spec.rb b/spec/opendax/payload_spec.rb new file mode 100644 index 0000000..5485c23 --- /dev/null +++ b/spec/opendax/payload_spec.rb @@ -0,0 +1,49 @@ +require 'opendax/payload' + +describe Opendax::Payload do + let(:secret) { 'myTailorIsRich42' } + let(:encoder) { Opendax::Payload.new(secret: secret) } + let(:valid_decoder) { encoder } + let(:invalid_decoder) { Opendax::Payload.new(secret: 'randomSecret') } + let(:service) { 'barong' } + let(:image) { 'rubykube/barong:2.0.8-alpha' } + let(:jwt) { encoder.generate!(service: service, image: image) } + + it 'should encode a JWT HMAC' do + token = encoder.generate!(service: service, image: image) + + expect(token).not_to be_nil + expect(token).to match /[A-Za-z0-9\-\._~\+\/]+=*/ + end + + it 'should decode a token with valid secret' do + decoded = valid_decoder.safe_decode(jwt) + + expect(decoded).not_to be_nil + expect(decoded['service']).to eq service + expect(decoded['image']).to eq image + end + + it 'should not decode a token with invalid secret' do + decoded = invalid_decoder.safe_decode(jwt) + + expect(decoded).to be_nil + end + + it 'defines an API' do + pgen = Opendax::Payload.new(secret: '0x42', expire: 600) + token = pgen.generate!(service: service, image: image) + pgen.decode!(token) + pgen.safe_decode(token) + end + + it 'expire time should be configurable' do + exp_time = 4200 + exp_coder = Opendax::Payload.new(secret: 'ab', expire: exp_time) + encoded = exp_coder.generate!(service: service, image: image) + decoded = exp_coder.decode!(encoded) + computed_exp = decoded['exp'] - decoded['iat'] + + expect(computed_exp).to eq exp_time + end +end diff --git a/spec/opendax/renderer_spec.rb b/spec/opendax/renderer_spec.rb new file mode 100644 index 0000000..608fbd6 --- /dev/null +++ b/spec/opendax/renderer_spec.rb @@ -0,0 +1,95 @@ +require 'opendax/renderer' + +describe Opendax::Renderer do + let(:renderer) { Opendax::Renderer.new } + let(:fake_erb_result) { { 'data' => 'this is fake data'} } + let(:config) do + { + 'app' => { + 'name' => 'Opendax', + 'domain' => 'app.test' + }, + 'render_protect' => false, + 'ssl' => { + 'enabled' => 'true', + 'email' => 'support@example.com' + }, + 'images' => { + 'peatio' => 'rubykube/peatio:latest', + 'barong' => 'rubykube/barong:latest', + 'frontend' => 'rubykube/mikroapp:latest', + 'tower' => 'rubykube/tower:latest' + }, + 'vendor' => { + 'frontend' => 'https://github.com/rubykube/mikroapp.git' + } + } + end + + it 'should load configuration' do + allow(YAML).to receive(:load_file).and_return(config) + expect(renderer.config).to eq(config) + end + + describe '.config' do + it 'should load configuration' do + allow(YAML).to receive(:load_file).and_return(config) + expect(renderer.config).to eq(config) + end + end + + describe '.generate_key' do + it 'should generate a private RSA key by default' do + renderer.generate_key('config/secrets/barong.key') + expect(File).to exist('config/secrets/barong.key') + end + + it 'should generate a public RSA key in addition when the flag is passed' do + renderer.generate_key('config/secrets/app.key', public: true) + expect(File).to exist('config/secrets/app.key') + expect(File).to exist('config/secrets/app.key.pub') + end + end + + describe '.render_keys' do + it 'should create files with private and public RSA keys' do + renderer.render_keys + expect(File).to exist('config/secrets/barong.key') + expect(File).to exist('config/secrets/app.key') + expect(File).to exist('config/secrets/app.key.pub') + end + end + + describe '.render_file' do + it 'should render file' do + expect(ERB).to receive(:new).once.and_call_original + expect_any_instance_of(ERB).to receive(:result).once.and_return(fake_erb_result) + expect(File).to receive(:write).with('./config/peatio.env', fake_erb_result).once.and_call_original + + renderer.render_file('./templates/config/peatio.env.erb', './config/peatio.env') + end + end + + describe '.template_name' do + it 'should exclude "templates" directory' do + file_name = renderer.template_name('./templates/config/peatio.env.erb') + expect(file_name).not_to start_with('./templates') + end + + it 'should return relative path to file' do + file_name = renderer.template_name('./templates/compose/app.yaml.erb') + expect(file_name).to start_with('.') + end + end + + let(:renderer) { Opendax::Renderer.new } + + describe '.render' do + it 'should call exact amount of helper functions' do + number_of_files = Dir.glob('./templates/**/*.erb', File::FNM_DOTMATCH).length + expect(renderer).to receive(:render_file).exactly(number_of_files).times + + renderer.render + end + end +end diff --git a/spec/opendax/server_spec.rb b/spec/opendax/server_spec.rb new file mode 100644 index 0000000..e69de29 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..251aa51 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,100 @@ +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # This allows you to limit a spec run to individual examples or groups + # you care about by tagging them with `:focus` metadata. When nothing + # is tagged with `:focus`, all examples get run. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ + # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = "doc" + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/templates/.env.erb b/templates/.env.erb new file mode 100644 index 0000000..45180ba --- /dev/null +++ b/templates/.env.erb @@ -0,0 +1,6 @@ +COMPOSE_PROJECT_NAME=<%= @config['app']['name'].downcase %> +COMPOSE_FILE=compose/app.yaml:compose/backend.yaml:compose/gateway.yaml:compose/proxy.yaml:compose/daemons.yaml:compose/frontend.yaml:compose/cryptonodes.yaml:compose/arke.yaml:compose/superset.yaml:compose/monitoring.yaml +PEATIO_RAILS_VAULT_TOKEN=<%= @config['vault']['peatio_rails_token'] %> +PEATIO_CRYPTO_VAULT_TOKEN=<%= @config['vault']['peatio_crypto_token'] %> +PEATIO_UPSTREAM_VAULT_TOKEN=<%= @config['vault']['peatio_upstream_token'] %> +PEATIO_MATCHING_VAULT_TOKEN=<%= @config['vault']['peatio_matching_token'] %> diff --git a/templates/compose/app.yaml.erb b/templates/compose/app.yaml.erb new file mode 100644 index 0000000..d9c1a3e --- /dev/null +++ b/templates/compose/app.yaml.erb @@ -0,0 +1,77 @@ +version: '3.6' + +# Docker json-file rotation — noisy tier (~30MB cap per container). +x-logging-noisy: &fibitex-logging-noisy + driver: json-file + options: + max-size: "10m" + max-file: "3" + +services: + peatio: + logging: *fibitex-logging-noisy + restart: always + image: "<%= @config['images']['peatio'] %>" + environment: + - VAULT_TOKEN=${PEATIO_RAILS_VAULT_TOKEN} + env_file: + - ../config/peatio.env + expose: + - "8000" + volumes: + - ../config/peatio/seed:/opt/peatio/config/seed + - ../config/peatio/management_api_v1.yml:/opt/peatio/config/management_api_v1.yml + - ../config/peatio/application.yml:/opt/peatio/config/application.yml + - ../config/peatio/plugins.yml:/opt/peatio/config/plugins.yml + - ../config/peatio/abilities.yml:/opt/peatio/config/abilities.yml + - ../config/test_users.yml:/opt/peatio/config/test_users.yml + - ../bin/seed_test_balances.rb:/home/app/lib/seed_test_balances.rb + - ../bin/check_test_balances.rb:/home/app/lib/check_test_balances.rb + - ../bin/sync_peatio_seed.rb:/home/app/lib/sync_peatio_seed.rb + labels: {} + command: bash -c "ruby ./bin/link_config && bundle exec puma --config config/puma.rb" + + barong: + logging: *fibitex-logging-noisy + restart: always + image: "<%= @config['images']['barong'] %>" + env_file: + - ../config/barong.env + volumes: + - ../config/secrets:/secrets:ro + - ../config/barong/seeds.yml:/home/app/config/seeds.yml + - ../config/barong/barong.yml:/home/app/config/barong.yml + - ../config/barong/authz_rules.yml:/home/app/config/authz_rules.yml + - ../config/barong/management_api.yml:/home/app/config/management_api.yml + - ../config/barong/abilities.yml:/home/app/config/abilities.yml + - ../config/test_users.yml:/home/app/config/test_users.yml + - ../bin/seed_test_users.rb:/home/app/lib/seed_test_users.rb + +<% if @config['finex']['enabled'] %> + finex-api: + logging: *fibitex-logging-noisy + restart: always + image: "<%= @config['finex']['image'] %>" + command: "./orderapi" + volumes: + - ../config/finex:/app/config:ro + + finex-engine: + logging: *fibitex-logging-noisy + restart: always + image: "<%= @config['finex']['image'] %>" + command: "./finex" + volumes: + - ../config/finex:/app/config:ro +<% end %> + + applogic: + logging: *fibitex-logging-noisy + restart: always + image: "<%= @utils['images']['applogic'] %>" + env_file: + - ../config/applogic.env + expose: + - "8081" + volumes: + - ../config/applogic/management_api_v2.yml:/home/app/config/management_api_v2.yml diff --git a/templates/compose/arke.yaml.erb b/templates/compose/arke.yaml.erb new file mode 100644 index 0000000..40d4289 --- /dev/null +++ b/templates/compose/arke.yaml.erb @@ -0,0 +1,18 @@ +version: '3.6' + +x-logging-noisy: &fibitex-logging-noisy + driver: json-file + options: + max-size: "10m" + max-file: "3" + +services: + arke-maker: + logging: *fibitex-logging-noisy + restart: always + image: "<%= @utils['images']['arke'] %>" + env_file: + - ../config/arke.env + volumes: + - ../config/arke/strategies.yml:/home/app/config/strategies.yml + command: bundle exec ./bin/arke start diff --git a/templates/compose/backend.yaml.erb b/templates/compose/backend.yaml.erb new file mode 100644 index 0000000..cb386a9 --- /dev/null +++ b/templates/compose/backend.yaml.erb @@ -0,0 +1,79 @@ +version: '3.6' + +# Docker json-file rotation — quiet tier (~10MB cap per container). +x-logging-quiet: &fibitex-logging-quiet + driver: json-file + options: + max-size: "5m" + max-file: "2" + +services: + db: + logging: *fibitex-logging-quiet + restart: always + <%- if @config['database']['adapter'] == 'mysql' %> + image: mysql:8.0.36 + command: --default-authentication-plugin=mysql_native_password + volumes: + - db_data:/var/lib/mysql + - ../config/mysql:/etc/mysql/conf.d:ro + environment: + MYSQL_ROOT_PASSWORD: <%= @config['database']['password'] %> + <%- elsif @config['database']['adapter'] == 'postgresql' %> + image: postgres:13 + volumes: + - db_data:/var/lib/postgresql/data + environment: + POSTGRES_USER: <%= @config['database']['user'] %> + POSTGRES_PASSWORD: <%= @config['database']['password'] %> + <%- end %> + + influxdb: + logging: *fibitex-logging-quiet + image: influxdb:1.7.10 + restart: always + volumes: + - influx_data:/var/lib/influxdb + - ../config/influxdb/build_candles.sql:/build_candles.sql + - ../config/influxdb/arke.sql:/arke.sql + - ../config/influxdb/peatio.sql:/peatio.sql + - ../config/arke/historical_data:/data/historical_data + environment: + INFLUXDB_ADMIN_ENABLED: "true" + INFLUXDB_LOGGING_LEVEL: "warn" + + redis: + logging: *fibitex-logging-quiet + image: redis:7.2.12-alpine + restart: always + volumes: + - redis_data:/data + + rabbitmq: + logging: *fibitex-logging-quiet + image: rabbitmq:3.7.6-management + restart: always + volumes: + - rabbitmq_data:/var/lib/rabbitmq + + vault: + logging: *fibitex-logging-quiet + image: vault:1.3.0 + restart: always + volumes: + - vault_data:/vault + - ../config/vault:/tmp/policies + command: + - server + cap_add: + - IPC_LOCK + environment: + VAULT_LOCAL_CONFIG: '{"storage": {"file": { "path": "/vault/data" }}, "listener": {"tcp":{"address": "0.0.0.0:8200","tls_disable":"1"}}}' + VAULT_ADDR: http://vault:8200 + +volumes: + db_data: + rabbitmq_data: + redis_data: + vault_data: + influx_data: diff --git a/templates/compose/cryptonodes.yaml.erb b/templates/compose/cryptonodes.yaml.erb new file mode 100644 index 0000000..d2ab78a --- /dev/null +++ b/templates/compose/cryptonodes.yaml.erb @@ -0,0 +1,49 @@ +version: '3.6' + +x-logging-noisy: &fibitex-logging-noisy + driver: json-file + options: + max-size: "10m" + max-file: "3" + +services: + parity: + logging: *fibitex-logging-noisy + image: parity/parity:v2.7.2-stable + restart: always + command: | + --chain=kovan + --mode=active + --interface=all + --warp=true + --snapshot-peers=10 + --min-peers=5 + --max-peers=10 + --jsonrpc-interface=0.0.0.0 + --jsonrpc-cors=all + --jsonrpc-hosts=all + --jsonrpc-apis=all + --db-compaction=ssd + --no-persistent-txqueue + volumes: + - ../data/parity:/home/parity/.local/share/io.parity.ethereum + ports: + - "127.0.0.1:8545:8545" + + bitcoind: + logging: *fibitex-logging-noisy + image: quay.io/openware/bitcoind:0.19.1 + restart: always + user: root + command: bitcoind + volumes: + - ../data/bitcoin:/bitcoin + - ../config/bitcoin.conf:/bitcoin/.bitcoin/bitcoin.conf + + litecoind: + logging: *fibitex-logging-noisy + image: quay.io/openware/litecoind:0.16.3 + restart: always + volumes: + - ../data/litecoin:/litecoin + - ../config/litecoin.conf:/litecoin/litecoin.conf diff --git a/templates/compose/daemons.yaml.erb b/templates/compose/daemons.yaml.erb new file mode 100644 index 0000000..cb1c4b9 --- /dev/null +++ b/templates/compose/daemons.yaml.erb @@ -0,0 +1,141 @@ +version: '3.6' + +# Docker json-file rotation. +x-logging-noisy: &fibitex-logging-noisy + driver: json-file + options: + max-size: "10m" + max-file: "3" + +x-logging-quiet: &fibitex-logging-quiet + driver: json-file + options: + max-size: "5m" + max-file: "2" + +x-daemon: &peatio-daemon + image: "<%= @config['images']['peatio'] %>" + restart: always + logging: *fibitex-logging-noisy + env_file: + - ../config/peatio.env + volumes: + - ../config/peatio:/opt/peatio/config:ro + +services: + blockchain: + << : *peatio-daemon + command: bash -c "ruby ./bin/link_config && bundle exec ruby lib/daemons/daemons.rb blockchain" + + cron_job: + << : *peatio-daemon + environment: + - VAULT_TOKEN=${PEATIO_CRYPTO_VAULT_TOKEN} + command: bash -c "ruby ./bin/link_config && bundle exec ruby lib/daemons/daemons.rb cron_job" + + deposit: + << : *peatio-daemon + environment: + - VAULT_TOKEN=${PEATIO_CRYPTO_VAULT_TOKEN} + command: bash -c "ruby ./bin/link_config && bundle exec ruby lib/daemons/daemons.rb deposit" + + upstream: + << : *peatio-daemon + environment: + - VAULT_TOKEN=${PEATIO_UPSTREAM_VAULT_TOKEN} + command: bash -c "ruby ./bin/link_config && bundle exec ruby lib/daemons/daemons.rb upstream" + + deposit_coin_address: + << : *peatio-daemon + environment: + - VAULT_TOKEN=${PEATIO_CRYPTO_VAULT_TOKEN} + command: bash -c "ruby ./bin/link_config && bundle exec ruby lib/daemons/amqp_daemon.rb deposit_coin_address" + + withdraw_coin: + << : *peatio-daemon + environment: + - VAULT_TOKEN=${PEATIO_CRYPTO_VAULT_TOKEN} + command: bash -c "ruby ./bin/link_config && bundle exec ruby lib/daemons/amqp_daemon.rb withdraw_coin" + + influx_writer: + << : *peatio-daemon + command: bash -c "ruby ./bin/link_config && bundle exec ruby lib/daemons/amqp_daemon.rb influx_writer" + + rango: + logging: *fibitex-logging-noisy + restart: always + image: "<%= @config['images']['rango'] %>" + env_file: + - ../config/rango.env + +<% unless @config['finex']['enabled'] %> + matching: + << : *peatio-daemon + environment: + - VAULT_TOKEN=${PEATIO_MATCHING_VAULT_TOKEN} + command: bash -c "ruby ./bin/link_config && bundle exec ruby lib/daemons/amqp_daemon.rb matching" + + order_processor: + << : *peatio-daemon + environment: + - VAULT_TOKEN=${PEATIO_MATCHING_VAULT_TOKEN} + command: bash -c "ruby ./bin/link_config && bundle exec ruby lib/daemons/amqp_daemon.rb order_processor" + + trade_executor: + << : *peatio-daemon + environment: + - VAULT_TOKEN=${PEATIO_MATCHING_VAULT_TOKEN} + command: bash -c "ruby ./bin/link_config && bundle exec ruby lib/daemons/amqp_daemon.rb trade_executor" +<% end %> + + mailer: + logging: *fibitex-logging-quiet + restart: always + image: "<%= @config['images']['barong'] %>" + env_file: + - ../config/barong.env + volumes: + - ../config/secrets:/secrets:ro + - ../config/mailer/templates:/home/app/app/views/postmaster + - ../config/mailer.yml:/home/app/config/mailer.yml + - ../config/barong/seeds.yml:/home/app/config/seeds.yml + - ../config/barong/barong.yml:/home/app/config/barong.yml + - ../config/barong/authz_rules.yml:/home/app/config/authz_rules.yml + - ../config/barong/management_api.yml:/home/app/config/management_api.yml + - ../config/barong/abilities.yml:/home/app/config/abilities.yml + command: bash -c "bin/mailer run" + + applogic_sidekiq: + logging: *fibitex-logging-noisy + restart: always + image: "<%= @utils['images']['applogic'] %>" + env_file: + - ../config/barong.env + volumes: + - ../config/applogic/management_api_v2.yml:/home/app/config/management_api_v2.yml + - ../config/applogic/schedule.yml:/home/app/config/schedule.yml + command: bash -c "bundle exec sidekiq" + + barong_sidekiq: + logging: *fibitex-logging-noisy + restart: always + image: "<%= @config['images']['barong'] %>" + env_file: + - ../config/barong.env + volumes: + - ../config/secrets:/secrets:ro + - ../config/barong/seeds.yml:/home/app/config/seeds.yml + - ../config/barong/barong.yml:/home/app/config/barong.yml + - ../config/barong/authz_rules.yml:/home/app/config/authz_rules.yml + - ../config/barong/management_api.yml:/home/app/config/management_api.yml + command: bash -c "bundle exec sidekiq" + + listener: + logging: *fibitex-logging-noisy + restart: always + image: "<%= @utils['images']['applogic'] %>" + env_file: + - ../config/applogic.env + volumes: + - ../config/applogic/management_api_v2.yml:/home/app/config/management_api_v2.yml + command: bash -c "bundle exec rake event_api_listener" diff --git a/templates/compose/frontend.yaml.erb b/templates/compose/frontend.yaml.erb new file mode 100644 index 0000000..f580f74 --- /dev/null +++ b/templates/compose/frontend.yaml.erb @@ -0,0 +1,131 @@ +version: '3.6' + +# Docker json-file rotation — quiet tier (~10MB cap per container). +x-logging-quiet: &fibitex-logging-quiet + driver: json-file + options: + max-size: "5m" + max-file: "2" + +<% + app_host = "#{@config['app']['subdomain']}.#{@config['app']['domain']}" + shahoo_host = @config['app']['shahoo_host'].to_s.strip + shahoo_host = "#{@config['app']['shahoo_subdomain'] || 'shahoo'}.#{@config['app']['domain']}" if shahoo_host.empty? + shahoo_origin = "#{ssl_helper('http')}://#{shahoo_host}" +%> + +services: + shahoo-bff: + logging: *fibitex-logging-quiet + restart: always + image: "<%= @config['images']['shahoo_bff'] %>" + environment: + PORT: "8082" + DALAN_URL: http://gateway:8099/api/v2/dalan + DENA_URL: http://gateway:8099/api/v2/dena + FIBITEX_HOST: "<%= app_host %>" + BARONG_URL: http://barong:8001 + RANGER_PRIVATE_DIRECT_URL: ws://rango:8080/api/v2/ranger/private + SHAAHO_PUBLIC_URL: "<%= shahoo_origin %>" + CORS_ORIGIN: "<%= shahoo_origin %>,http://localhost:3000,http://127.0.0.1:3000" + REDIS_URL: "redis://redis:6379/1" +<% if @config.dig('dev', 'skip_api_key_2fa') -%> + SKIP_API_KEY_2FA: "true" +<% end -%> + healthcheck: + test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:8082/health"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 15s + labels: + - "traefik.enable=true" + - "traefik.http.routers.shahoo-bff-<%= @name %>.rule=Host(`<%= shahoo_host %>`) && PathPrefix(`/api/1`)" + - "traefik.http.routers.shahoo-bff-<%= @name %>.priority=200" + - "traefik.http.services.shahoo-bff-<%= @name %>.loadbalancer.server.port=8082" + - "traefik.http.services.shahoo-bff-<%= @name %>.loadbalancer.healthcheck.path=/health" + - "traefik.http.services.shahoo-bff-<%= @name %>.loadbalancer.healthcheck.interval=15s" + - "traefik.http.services.shahoo-bff-<%= @name %>.loadbalancer.healthcheck.timeout=5s" + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.shahoo-bff-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.shahoo-bff-<%= @name %>.tls=true" + - "traefik.http.routers.shahoo-bff-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.shahoo-bff-<%= @name %>.entrypoints=web" + <%- end -%> + + shahoo: + logging: *fibitex-logging-quiet + restart: always + image: "<%= @config['images']['shahoo'] %>" + volumes: + - ../config/frontend/shahoo.env.js:/usr/share/nginx/html/config/env.js + healthcheck: + test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:3000/health"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 15s + labels: + - "traefik.enable=true" + - "traefik.http.routers.shahoo-<%= @name %>.rule=Host(`<%= shahoo_host %>`) && PathPrefix(`/`)" + - "traefik.http.routers.shahoo-<%= @name %>.priority=100" + - "traefik.http.services.shahoo-<%= @name %>.loadbalancer.server.port=3000" + - "traefik.http.services.shahoo-<%= @name %>.loadbalancer.healthcheck.path=/health" + - "traefik.http.services.shahoo-<%= @name %>.loadbalancer.healthcheck.interval=15s" + - "traefik.http.services.shahoo-<%= @name %>.loadbalancer.healthcheck.timeout=5s" + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.shahoo-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.shahoo-<%= @name %>.tls=true" + - "traefik.http.routers.shahoo-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.shahoo-<%= @name %>.entrypoints=web" + <%- end -%> + + frontend: + logging: *fibitex-logging-quiet + restart: always + image: "<%= @config['images']['frontend'] %>" + volumes: + - ../config/frontend/env.js:/usr/share/nginx/html/config/env.js + healthcheck: + test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:3000/health"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 15s + labels: + - "traefik.http.routers.frontend-<%= @name %>.rule=Host(`<%= app_host %>`) && PathPrefix(`/`)" + - "traefik.enable=true" + - "traefik.http.services.frontend-<%= @name %>.loadbalancer.server.port=3000" + - "traefik.http.services.frontend-<%= @name %>.loadbalancer.healthcheck.path=/health" + - "traefik.http.services.frontend-<%= @name %>.loadbalancer.healthcheck.interval=15s" + - "traefik.http.services.frontend-<%= @name %>.loadbalancer.healthcheck.timeout=5s" + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.frontend-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.frontend-<%= @name %>.tls=true" + - "traefik.http.routers.frontend-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.frontend-<%= @name %>.entrypoints=web" + <%- end -%> + + AdminTower: + logging: *fibitex-logging-quiet + restart: always + image: "<%= @config['images']['tower'] %>" + volumes: + - ../config/frontend/tower.js:/home/app/env.js + labels: + - "traefik.http.routers.AdminTower-<%= @name %>.rule=Host(`<%= app_host %>`) && PathPrefix(`/tower`)" + - "traefik.enable=true" + - "traefik.http.services.AdminTower-<%= @name %>.loadbalancer.server.port=8080" + - "traefik.http.routers.AdminTower-<%= @name %>.middlewares=auth" + - "traefik.http.middlewares.auth.basicauth.users=yaser:{SHA}ueAuJOSpNyWTyI+JEiX57oeRevg=" + # HaCE4UYTrCTck88uXkd9 + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.AdminTower-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.AdminTower-<%= @name %>.tls=true" + - "traefik.http.routers.AdminTower-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.AdminTower-<%= @name %>.entrypoints=web" + <%- end -%> diff --git a/templates/compose/gateway.yaml.erb b/templates/compose/gateway.yaml.erb new file mode 100644 index 0000000..e7a92e0 --- /dev/null +++ b/templates/compose/gateway.yaml.erb @@ -0,0 +1,45 @@ +version: '3.6' + +# Docker json-file rotation — quiet tier (~10MB cap per container). +x-logging-quiet: &fibitex-logging-quiet + driver: json-file + options: + max-size: "5m" + max-file: "2" + +<% + app_host = "#{@config['app']['subdomain']}.#{@config['app']['domain']}" + shahoo_host = @config['app']['shahoo_host'].to_s.strip + shahoo_host = "#{@config['app']['shahoo_subdomain'] || 'shahoo'}.#{@config['app']['domain']}" if shahoo_host.empty? +%> + +services: + gateway: + logging: *fibitex-logging-quiet + restart: always + image: envoyproxy/envoy:v1.10.0 + volumes: + - ../config/gateway:/etc/envoy/ + command: /usr/local/bin/envoy -l info -c /etc/envoy/envoy.yaml + labels: + - "traefik.http.routers.gateway-<%= @name %>.rule=Host(`<%= app_host %>`) && (PathPrefix(`/api`) || PathPrefix(`/admin`) || PathPrefix(`/assets/`))" + - "traefik.enable=true" + - "traefik.http.services.gateway-<%= @name %>.loadbalancer.server.port=8099" + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.gateway-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.gateway-<%= @name %>.tls=true" + - "traefik.http.routers.gateway-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.gateway-<%= @name %>.entrypoints=web" + <%- end -%> + # WS0.2 — Rango on shahoo.* (same Envoy cluster as www) + - "traefik.http.routers.gateway-shahoo-ranger-<%= @name %>.rule=Host(`<%= shahoo_host %>`) && PathPrefix(`/api/v2/ranger`)" + - "traefik.http.routers.gateway-shahoo-ranger-<%= @name %>.priority=250" + - "traefik.http.routers.gateway-shahoo-ranger-<%= @name %>.service=gateway-<%= @name %>" + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.gateway-shahoo-ranger-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.gateway-shahoo-ranger-<%= @name %>.tls=true" + - "traefik.http.routers.gateway-shahoo-ranger-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.gateway-shahoo-ranger-<%= @name %>.entrypoints=web" + <%- end -%> diff --git a/templates/compose/monitoring.yaml.erb b/templates/compose/monitoring.yaml.erb new file mode 100644 index 0000000..0958a4c --- /dev/null +++ b/templates/compose/monitoring.yaml.erb @@ -0,0 +1,186 @@ +version: '3.6' + +x-logging-quiet: &fibitex-logging-quiet + driver: json-file + options: + max-size: "5m" + max-file: "2" + +services: + prometheus: + logging: *fibitex-logging-quiet + image: prom/prometheus:latest + container_name: monitoring-prometheus + volumes: + - ../config/monitoring/prometheus:/etc/prometheus/ + - prometheus:/prometheus + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/usr/share/prometheus/console_libraries' + - '--web.console.templates=/usr/share/prometheus/consoles' + - '--web.enable-lifecycle' + labels: + - "traefik.enable=true" + - "traefik.http.routers.pro-<%= @name %>.entrypoints=http" + - "traefik.http.routers.pro-<%= @name %>.rule=Host(`pro.<%= @config['app']['domain'] %>`)" + - "traefik.http.services.pro-<%= @name %>.loadbalancer.server.port=9090" + - "traefik.http.routers.pro-<%= @name %>.middlewares=auth" + - "traefik.http.middlewares.auth.basicauth.users=yaser:{SHA}ueAuJOSpNyWTyI+JEiX57oeRevg=" + # HaCE4UYTrCTck88uXkd9 + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.pro-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.pro-<%= @name %>.tls=true" + - "traefik.http.routers.pro-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.pro-<%= @name %>.entrypoints=web" + <%- end -%> + + grafana: + logging: *fibitex-logging-quiet + image: grafana/grafana + container_name: monitoring-grafana + depends_on: + - prometheus + volumes: + - grafana:/var/lib/grafana + environment: + - GF_INSTALL_PLUGINS=https://github.com/raintank/crate-datasource/archive/master.zip;crate-datasource,grafana-clock-panel,grafana-worldmap-panel,natel-plotly-panel,grafana-piechart-panel + labels: + - "traefik.enable=true" + - "traefik.http.routers.gra-<%= @name %>.entrypoints=http" + - "traefik.http.routers.gra-<%= @name %>.rule=Host(`gra.<%= @config['app']['domain'] %>`)" + - "traefik.http.services.gra-<%= @name %>.loadbalancer.server.port=3000" + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.gra-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.gra-<%= @name %>.tls=true" + - "traefik.http.routers.gra-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.gra-<%= @name %>.entrypoints=web" + <%- end -%> + + alertmanager: + logging: *fibitex-logging-quiet + image: prom/alertmanager + container_name: monitoring-alertmanager + volumes: + - ../config/monitoring/alertmanager/:/etc/alertmanager/ + command: + - '--config.file=/etc/alertmanager/config.yml' + - '--storage.path=/alertmanager' + labels: + - "traefik.enable=true" + - "traefik.http.routers.ale-<%= @name %>.entrypoints=http" + - "traefik.http.routers.ale-<%= @name %>.rule=Host(`alert.<%= @config['app']['domain'] %>`)" + - "traefik.http.services.ale-<%= @name %>.loadbalancer.server.port=9093" + - "traefik.http.routers.ale-<%= @name %>.middlewares=auth" + - "traefik.http.middlewares.auth.basicauth.users=yaser:{SHA}ueAuJOSpNyWTyI+JEiX57oeRevg=" + # HaCE4UYTrCTck88uXkd9 + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.ale-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.ale-<%= @name %>.tls=true" + - "traefik.http.routers.ale-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.ale.entrypoints=web" + <%- end -%> + + loki: + logging: *fibitex-logging-quiet + image: grafana/loki:latest + container_name: monitoring-loki + command: -config.file=/etc/loki/local-config.yaml + volumes: + - loki:/tmp/loki + - ../config/monitoring/loki/local-config.yaml:/etc/loki/local-config.yaml + labels: + - "traefik.enable=true" + - "traefik.http.routers.lok-<%= @name %>.entrypoints=http" + - "traefik.http.routers.lok-<%= @name %>.rule=Host(`loki.<%= @config['app']['domain'] %>`)" + - "traefik.http.services.lok-<%= @name %>.loadbalancer.server.port=3100" + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.lok-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.lok-<%= @name %>.tls=true" + - "traefik.http.routers.lok-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.lok-<%= @name %>.entrypoints=web" + <%- end -%> + + scope: + logging: *fibitex-logging-quiet + image: weaveworks/scope:latest + pid: "host" + privileged: true + container_name: monitoring-scope + labels: + - "traefik.enable=true" + - "traefik.http.routers.scop-<%= @name %>.entrypoints=http" + - "traefik.http.routers.scop-<%= @name %>.rule=Host(`scope.<%= @config['app']['domain'] %>`)" + - "traefik.http.services.scop-<%= @name %>.loadbalancer.server.port=4040" + - "traefik.http.routers.scop-<%= @name %>.middlewares=auth" + - "traefik.http.middlewares.auth.basicauth.users=yaser:{SHA}ueAuJOSpNyWTyI+JEiX57oeRevg=" + # HaCE4UYTrCTck88uXkd + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.scop-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.scop-<%= @name %>.tls=true" + - "traefik.http.routers.scop-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.scop-<%= @name %>.entrypoints=web" + <%- end -%> + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:rw" + command: + - "--probe.docker=true" + + node-exporter: + logging: *fibitex-logging-quiet + image: prom/node-exporter:latest + container_name: monitoring-node-exporter + volumes: + - /proc:/host/proc:ro + - /sys:/host/sys:ro + - /:/rootfs:ro + command: + - --path.procfs=/host/proc + - --path.sysfs=/host/sys + - --collector.filesystem.ignored-mount-points + - ^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/) + ports: + - 9100:9100 + + cadvisor: + logging: *fibitex-logging-quiet + image: google/cadvisor:latest + container_name: monitoring-cadvisor + volumes: + - /:/rootfs:ro + - /var/run:/var/run:rw + - /sys:/sys:ro + - /var/lib/docker/:/var/lib/docker:ro + - /dev/disk/:/dev/disk:ro + ports: + <%- if @config['serverip']['enabled'] -%> + - "<%= @config['serverip']['ip'] %>:8080:8080" + <%- else -%> + - 8080:8080 + <%- end -%> + + promtail: + logging: *fibitex-logging-quiet + image: grafana/promtail:latest + container_name: monitoring-promtail + volumes: + - /var/log:/var/log + - ../config/monitoring/promtail/docker-config.yaml:/etc/promtail/docker-config.yaml + command: -config.file=/etc/promtail/docker-config.yaml + ports: + - 9080:9080 + + +volumes: + grafana: + name: grafana + prometheus: + name: prometheus + loki: + name: loki + diff --git a/templates/compose/proxy.yaml.erb b/templates/compose/proxy.yaml.erb new file mode 100644 index 0000000..9aa08e4 --- /dev/null +++ b/templates/compose/proxy.yaml.erb @@ -0,0 +1,81 @@ +version: '3.6' + +# Docker json-file rotation — quiet tier (~10MB cap per container). +x-logging-quiet: &fibitex-logging-quiet + driver: json-file + options: + max-size: "5m" + max-file: "2" + +services: + proxy: + logging: *fibitex-logging-quiet + restart: always + image: traefik:latest + ports: + <%- if @config['serverip']['enabled'] -%> + - "<%= @config['serverip']['ip'] %>:80:80" + - "<%= @config['serverip']['ip'] %>:443:443" + <%- else -%> + - "80:80" + - "443:443" + <%- end -%> + volumes: + - /var/run/docker.sock:/var/run/docker.sock + <%- if @config['ssl']['enabled'] -%> + - ../config/acme.json:/letsencrypt/acme.json + <%- end -%> + command: + - --log.level=INFO + - --api.dashboard=true <%#OK%> + - --providers.docker=true <%#OK%> + - --providers.docker.exposedbydefault=false + - --entryPoints.web.address=:80 <%#OK%> + <%- if @config['ssl']['enabled'] -%> + - --certificatesresolvers.letsencrypt.acme.email=<%= @config['ssl']['email'] %> <%#OK%> + - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json <%#OK%> + - --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory + + - --entrypoints.web.http.redirections.entrypoint.to=websecure <%#OK%> + - --entrypoints.web.http.redirections.entrypoint.scheme=https <%#OK%> + - --entrypoints.websecure.address=:443 <%#OK%> + + - --entrypoints.websecure.http.tls=true <%#OK%> + - --entrypoints.websecure.http.tls.certResolver=letsencrypt <%#OK%> + + + <%# - "--entryPoints.websecure.forwardedHeaders.insecure" %> + <%# - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" + - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" %> + + # Un comment bllow 4 line for request to ssl cert. For now we use universal cloudflare cert + <%# - --certificatesresolvers.letsencrypt.acme.dnschallenge=true + - --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare %> + + <%# environment: + - CF_API_EMAIL=yaser.rezaei@gmail.com + - CF_API_KEY=b988f91ef34cea523436d293f14c327be282e %> + + labels: + - "traefik.enable=true" + - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:[a-z-.]+}`)" + - "traefik.http.routers.http-catchall.entrypoints=web" + - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" + - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" + - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true" + + # dashboard Setting + - "traefik.http.routers.dashboard.rule=Host(`tra.<%= @config['app']['domain'] %>`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))" + - "traefik.http.routers.dashboard.service=api@internal" + - "traefik.http.routers.dashboard.middlewares=auth" + - "traefik.http.middlewares.auth.basicauth.users=yaser:{SHA}ueAuJOSpNyWTyI+JEiX57oeRevg=" + # HaCE4UYTrCTck88uXkd9 + - "traefik.http.routers.dashboard.tls=true" + - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt" + + # global redirect to https + - "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)" + - "traefik.http.routers.redirs.entrypoints=web" + - "traefik.http.routers.redirs.middlewares=redirect-to-https" + <%- end -%> + \ No newline at end of file diff --git a/templates/compose/superset.yaml.erb b/templates/compose/superset.yaml.erb new file mode 100644 index 0000000..fd45b3d --- /dev/null +++ b/templates/compose/superset.yaml.erb @@ -0,0 +1,29 @@ +version: '3.6' + +x-logging-quiet: &fibitex-logging-quiet + driver: json-file + options: + max-size: "5m" + max-file: "2" + +services: + superset: + logging: *fibitex-logging-quiet + image: "<%= @utils['images']['superset'] %>" + restart: always + volumes: + - superset_db:/var/lib/superset + labels: + - "traefik.http.routers.superset-<%= @name %>.rule=Host(`superset.<%= @config['app']['domain'] %>`)" + - "traefik.http.services.superset-<%= @name %>.loadbalancer.server.port=8088" + - "traefik.enable=true" + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.superset-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.superset-<%= @name %>.tls=true" + - "traefik.http.routers.superset-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.superset-<%= @name %>.entrypoints=web" + <%- end -%> + +volumes: + superset_db: diff --git a/templates/compose/vendor.yaml.erb b/templates/compose/vendor.yaml.erb new file mode 100644 index 0000000..b68a9d2 --- /dev/null +++ b/templates/compose/vendor.yaml.erb @@ -0,0 +1,34 @@ +version: '3.6' + +x-logging-quiet: &fibitex-logging-quiet + driver: json-file + options: + max-size: "5m" + max-file: "2" + +services: + frontend: + logging: *fibitex-logging-quiet + image: node:11 + restart: always + user: "${UID}:${GID}" + volumes: + - ../vendor/frontend:/home/node + command: + - sh + - -c + - | + cd /home/node + yarn + yarn start + labels: + - "traefik.http.routers.frontend-<%= @name %>.rule=Host(`<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>`) && PathPrefix(`/`)" + - "traefik.http.services.frontend-<%= @name %>.loadbalancer.server.port=3000" + - "traefik.enable=true" + <%- if @config['ssl']['enabled'] -%> + - "traefik.http.routers.frontend-<%= @name %>.entrypoints=websecure" + - "traefik.http.routers.frontend-<%= @name %>.tls=true" + - "traefik.http.routers.frontend-<%= @name %>.tls.certresolver=letsencrypt" + <%- else -%> + - "traefik.http.routers.frontend-<%= @name %>.entrypoints=web" + <%- end -%> diff --git a/templates/config/applogic.env.erb b/templates/config/applogic.env.erb new file mode 100644 index 0000000..89e4e60 --- /dev/null +++ b/templates/config/applogic.env.erb @@ -0,0 +1,29 @@ +RAILS_ENV=production +RAILS_ROOT=/home/app + +BARONG_URL=http://barong:8001 +PEATIO_URL=http://peatio:8000 +REDIS_URL=redis://redis:6379 + +PORT=8081 +DATABASE_HOST=db +DATABASE_USER=root +DATABASE_PASSWORD=changeme + +EVENT_API_RABBITMQ_HOST=rabbitmq +EVENT_API_RABBITMQ_PORT=5672 +EVENT_API_RABBITMQ_USERNAME=guest +EVENT_API_RABBITMQ_PASSWORD=guest + +BARONG_EVENT_API_JWT_PUBLIC_KEY=<%= @barong_public_key %> +BARONG_EVENT_API_JWT_ALGORITHM=RS256 + +EVENT_API_APPLICATION=barong +EVENT_API_EVENT_CATEGORY=model +EVENT_API_EVENT_NAME=profile.created + +JWT_PUBLIC_KEY=<%= @barong_public_key %> +JWT_PRIVATE_KEY=<%= @applogic_private_key %> + +RAILS_LOG_TO_STDOUT=true +SECRET_KEY_BASE=b609ebad4856c8f8a4f465fa785c74fb diff --git a/templates/config/applogic/management_api_v2.yml.erb b/templates/config/applogic/management_api_v2.yml.erb new file mode 100644 index 0000000..337ed9c --- /dev/null +++ b/templates/config/applogic/management_api_v2.yml.erb @@ -0,0 +1,25 @@ +barong: + keychain: + applogic: + algorithm: RS256 + value: <%= @applogic_private_key %> + + jwt: {} + + actions: + read_users: + required_signatures: ['applogic'] + requires_barong_totp: false + +peatio: + keychain: + applogic: + algorithm: RS256 + value: <%= @applogic_private_key %> + + jwt: {} + + actions: + read_operations: + required_signatures: ['applogic'] + requires_barong_totp: false diff --git a/templates/config/applogic/schedule.yml.erb b/templates/config/applogic/schedule.yml.erb new file mode 100644 index 0000000..a12b6fe --- /dev/null +++ b/templates/config/applogic/schedule.yml.erb @@ -0,0 +1,6 @@ +users_sync_job: + cron: "0 0 * * *" # it will retrieve data every 1 day + class: "UsersSyncWorker" + args: + period: '1' + action: 'sync' # you also can start a new job with action 'reg' to pull new users diff --git a/templates/config/arke.env.erb b/templates/config/arke.env.erb new file mode 100644 index 0000000..362bcfa --- /dev/null +++ b/templates/config/arke.env.erb @@ -0,0 +1,13 @@ +PORT=8081 + +LOG_LEVEL=warn + +DISABLE_SPRING=true + +RAILS_ENV=production + +SECRET_KEY_BASE=64 + +INFLUXDB_HOST=influxdb + +RABBITMQ_HOST=rabbitmq diff --git a/templates/config/arke/strategies.yml.erb b/templates/config/arke/strategies.yml.erb new file mode 100644 index 0000000..4770998 --- /dev/null +++ b/templates/config/arke/strategies.yml.erb @@ -0,0 +1 @@ +<%= @utils['arke'].to_yaml %> diff --git a/templates/config/barong.env.erb b/templates/config/barong.env.erb new file mode 100644 index 0000000..74c86f0 --- /dev/null +++ b/templates/config/barong.env.erb @@ -0,0 +1,107 @@ +PORT=8001 + +LOG_LEVEL=warn + +DISABLE_SPRING=true + +RAILS_ENV=production + +SECRET_KEY_BASE=64 + +<%- if @config['database']['adapter'] == 'postgresql' %> +DATABASE_COLLATION="" +DATABASE_ADAPTER="postgresql" +<%- elsif @config['database']['adapter'] == 'mysql' %> +DATABASE_ADAPTER="mysql2" +<%- end %> +DATABASE_HOST=<%= @config['database']['host'] %> +DATABASE_PORT=<%= @config['database']['port'] %> +DATABASE_USER=<%= @config['database']['user'] %> +DATABASE_PASS=<%= @config['database']['password'] %> + +<%- if @config['twilio']['enabled'] -%> +BARONG_PHONE_VERIFICATION=twilio_sms +BARONG_TWILIO_PHONE_NUMBER=<%= @config['twilio']['phone_number'] %> +BARONG_TWILIO_ACCOUNT_SID=<%= @config['twilio']['account_sid'] %> +BARONG_TWILIO_AUTH_TOKEN=<%= @config['twilio']['auth_token'] %> +<%- end -%> + +BARONG_KYC_PROVIDER=<%= @config['kyc']['provider'] %> + +<%- if @config['kyc']['provider'] == 'kycaid' -%> +BARONG_KYCAID_AUTHORIZATION_TOKEN=<%= @config['kyc']['authorization_token'] %> +BARONG_KYCAID_SANDBOX_MODE=<%= @config['kyc']['sandbox_mode'] %> +BARONG_KYCAID_API_ENDPOINT=<%= @config['kyc']['api_endpoint'] %> +<%- end -%> + +BARONG_STORAGE_PROVIDER=<%= @config['storage']['provider'] %> +BARONG_STORAGE_BUCKET_NAME=<%= @config['storage']['bucketName'] %> +BARONG_STORAGE_ACCESS_KEY=<%= @config['storage']['accessKey'] %> +BARONG_STORAGE_SECRET_KEY=<%= @config['storage']['secretKey'] %> +BARONG_STORAGE_ENDPOINT=<%= @config['storage']['endpoint'] %> +BARONG_STORAGE_SIGNATURE_VERSION=<%= @config['storage']['signatureVersion'] %> +BARONG_STORAGE_REGION=<%= @config['storage']['region'] %> + +BARONG_CAPTCHA=<%= @config['captcha']['type'] %> +<% if @config['captcha']['type'] == 'recaptcha' %> +BARONG_RECAPTCHA_SITE_KEY=<%= @config['captcha']['siteKey'] %> +BARONG_RECAPTCHA_SECRET_KEY=<%= @config['captcha']['secretKey'] %> +<% elsif @config['captcha']['type'] == 'geetest' %> +BARONG_GEETEST_ID=<%= @config['captcha']['siteKey'] %> +BARONG_GEETEST_KEY=<%= @config['captcha']['secretKey'] %> +<% end %> + +JWT_PUBLIC_KEY=<%= @barong_public_key %> +JWT_PRIVATE_KEY_PATH=/secrets/barong.key + +BARONG_VAULT_TOKEN=<%= @config['vault']['barong_token'] %> +BARONG_VAULT_ADDRESS=http://vault:8200 +BARONG_VAULT_APP_NAME=<%= @config['app']['name'].downcase %> + +REDIS_URL=redis://redis:6379 +BARONG_REDIS_URL=redis://redis:6379 + +BARONG_EVENT_API_JWT_PRIVATE_KEY=<%= @barong_private_key %> +BARONG_EVENT_API_JWT_ALGORITHM=RS256 +BARONG_EVENT_API_RABBITMQ_HOST=rabbitmq +BARONG_EVENT_API_RABBITMQ_PORT=5672 +BARONG_EVENT_API_RABBITMQ_USERNAME=guest +BARONG_EVENT_API_RABBITMQ_PASSWORD=guest + +BARONG_SMTP_HOST=<%= @config['smtp']['host'] %> +BARONG_SMTP_PORT=<%= @config['smtp']['port'] %> +BARONG_SMTP_USER=<%= @config['smtp']['user'] %> +BARONG_SMTP_PASSWORD=<%= @config['smtp']['password'] %> +BARONG_SMTP_LOGO_LINK=<%= @config['smtp']['sender_logo'] %> +BARONG_DEFAULT_LANGUAGE=en + +BARONG_SENDER_NAME=<%= @config['smtp']['sender_name'] %> +BARONG_SENDER_EMAIL=<%= @config['smtp']['sender_email'] %> + +BARONG_SMTP_ENABLE_STARTTLS_AUTO=<%= @config['smtp']['starttls_auto'] %> +BARONG_SMTP_OPENSSL_VERIFY_MODE=<%= @config['smtp']['openssl_verify_mode'] %> +BARONG_SMTP_DOMAIN=<%= @config['smtp']['domain'] %> +BARONG_SMTP_AUTH=<%= @config['smtp']['auth'] %> + +BARONG_KYCAID_AUTHORIZATION_TOKEN=<%= @config['kyc']['authorization_token'] %> +BARONG_KYCAID_SANDBOX_MODE=<%= @config['kyc']['sandbox_mode'] %> +BARONG_KYCAID_API_ENDPOINT=<%= @config['kyc']['api_endpoint'] %> + +BARONG_PASSWORD_MIN_ENTROPY=14 +BARONG_PASSWORD_USE_DICTIONARY=false + +BARONG_CSRF_PROTECTION=<%= @config['csrfEnabled'] %> + +BARONG_APP_NAME=<%= @config['app']['name'] %> +BARONG_DOMAIN=<%= ssl_helper('http') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %> + +BARONG_REQUIRED_DOCS_EXPIRE=false + +BARONG_JIBIT_API_URL=<%= @config['jibit']['url'] %> +BARONG_JIBIT_API_KEY=<%= @config['jibit']['key'] %> +BARONG_JIBIT_API_SECRET=<%= @config['jibit']['secret'] %> + +<% if @config.dig('dev', 'skip_api_key_2fa') -%> +BARONG_SKIP_API_KEY_2FA=true +<% end -%> + diff --git a/templates/config/barong/abilities.yml.erb b/templates/config/barong/abilities.yml.erb new file mode 100644 index 0000000..8ca1095 --- /dev/null +++ b/templates/config/barong/abilities.yml.erb @@ -0,0 +1,70 @@ +roles: + - superadmin + - admin + - technical + - accountant + - compliance + - support + +admin_permissions: + superadmin: + manage: + - Ability + - User + - Level + - Label + - Profile + - Activity + - APIKey + - Permission + - Restriction + - Document + admin: + read: + - Activity + manage: + - Ability + - User + - Level + - Label + - Profile + - APIKey + - Restriction + - Document + technical: + read: + - Ability + - User + - Level + - Label + - Profile + - Activity + manage: + - APIKey + - Restriction + accountant: + read: + - Ability + - User + - Level + - Label + - Profile + - Activity + compliance: + read: + - Ability + - Document + manage: + - User + - Level + - Label + - Profile + support: + read: + - Ability + - Label + - Level + - Profile + - Activity + manage: + - User diff --git a/templates/config/barong/management_api.yml.erb b/templates/config/barong/management_api.yml.erb new file mode 100644 index 0000000..b8e2cc8 --- /dev/null +++ b/templates/config/barong/management_api.yml.erb @@ -0,0 +1,11 @@ +keychain: + applogic: + algorithm: RS256 + value: <%= @applogic_public_key %> + +scopes: + read_users: + mandatory_signers: + - applogic + permitted_signers: + - applogic diff --git a/templates/config/barong/seeds.yml.erb b/templates/config/barong/seeds.yml.erb new file mode 100644 index 0000000..d3b6753 --- /dev/null +++ b/templates/config/barong/seeds.yml.erb @@ -0,0 +1,426 @@ +# List of Barong administrators. +# +# Other parameters that you can set here can be found in Account, +# Profile and Phone models (e.g. app/models/account.rb...); all the +# model properties are listed at the very bottom of this models files. +# +# Note: email is the only required field here. +users: + - email: <%= @config['admin']['user'] %> + password: <%= @config['admin']['pass'] %> + role: superadmin + state: active + level: 2 + +levels: + - key: email + id: 1 + value: verified + description: "User enter a valid code after registration" + - key: profile + id: 2 + value: verified + description: "User personal documents have been verified" + - key: access_phone + id: 3 + value: verified + description: "User entered a valid code from sms" + - key: card + id: 4 + value: verified + description: "User card number have been verified" + - key: iban + id: 5 + value: verified + description: "User iban have been verified" + - key: poa + id: 6 + value: verified + description: "User card bank have been verified" + - key: telephone + id: 7 + value: verified + description: "User entered a valid code from ring call" + - key: selfie + id: 8 + value: verified + description: "User selfie documents have been verified" + - key: owner_phone + id: 9 + value: verified + description: "User owner mobile have been verified" + - key: vip + id: 10 + value: verified + description: "User Vip have been verified" + +restrictions: {} +# - { category: whitelist, scope: country, value: UA, state: disabled } +# - { category: maintenance, scope: all, value: all, state: disabled } +# - { category: blacklist, scope: ip, value: 164.116.47.255, state: disabled, code: 433 } +# - { category: blacklist, scope: ip_subnet, value: 164.116.47.0/24, state: disabled, code: 434 } +# - { category: blacklist, scope: country, value: USA, state: disabled, code: 435 } +# - { category: blacklist, scope: continent, value: SA, state: disabled, code: 436 } + +permissions: +# SUPER ADMIN has an access to the whole system without any limits + # so we can just grant him access to /api/v2/* + - { role: superadmin, verb: all, path: api/v2, action: accept } +<%- if @config['finex']['enabled'] -%> + - { role: superadmin, verb: post, path: api/v2/dena/market/orders, action: drop } + - { role: superadmin, verb: post, path: api/v2/dena/admin/orders, action: drop } +<%- end -%> + # Rango(ranger) access + - { role: superadmin, verb: get, path: api/v2/ranger, action: accept } + # we are watching after you 0_0 + - { role: superadmin, verb: post, path: api/v2/, action: audit } + - { role: superadmin, verb: put, path: api/v2/, action: audit } + - { role: superadmin, verb: delete, path: api/v2/, action: audit } + +# ADMIN + # admin has nearly full access to barong and peatio api, except managing permissions + - { role: admin, verb: all, path: api/v2, action: accept } +<%- if @config['finex']['enabled'] -%> + - { role: admin, verb: post, path: api/v2/dena/market/orders, action: drop } + - { role: admin, verb: post, path: api/v2/dena/admin/orders, action: drop } +<%- end -%> + # ranger access + - { role: admin, verb: get, path: api/v2/ranger, action: accept } + # Finex upstream access + - { role: admin, verb: get, path: api/v2/open_finance, action: accept } + # admin doesnt have access to manage platform roles and permissions + - { role: admin, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + # admin doesnt have access to manage roles + - { role: admin, verb: all, path: api/v2/dalan/admin/users/role, action: drop } + # admin doesnt have access to admin activities + - { role: admin, verb: all, path: api/v2/dalan/admin/activities/admin, action: drop } + # we are watching after you 0_0 + - { role: admin, verb: post, path: api/v2/, action: audit } + - { role: admin, verb: put, path: api/v2/, action: audit } + - { role: admin, verb: delete, path: api/v2/, action: audit } + +# ACCOUNTANT + # accountant has a read access to Barong admin + - { role: accountant, verb: get, path: api/v2/dalan/admin, action: accept } + # accountant has a read access to Peatio financial information and creating of adjustments + - { role: accountant, verb: get, path: api/v2/dena/admin/members, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/beneficiaries, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/currencies, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/blockchains, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/wallets, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/trading_fees, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/withdraw_limits, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/orders, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/markets, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/engine, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/trades, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/deposits, action: accept } + - { role: accountant, verb: post, path: api/v2/dena/admin/deposits/new, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/withdraws, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/adjustments, action: accept } + - { role: accountant, verb: post, path: api/v2/dena/admin/adjustments/new, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/assets, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/liabilities, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/revenues, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/expenses, action: accept } + - { role: accountant, verb: get, path: api/v2/dena/admin/internal_transfers, action: accept } + # accountant doesnt have access to see pending documents + - { role: accountant, verb: get, path: api/v2/dalan/admin/users/documents/pending, action: drop } + # accountant doesnt have access to manage platform roles and permissions + - { role: accountant, verb: all, path: api/v2/dalan/admin/users/role, action: drop } + - { role: accountant, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + # accountant doesnt have access to admin activities + - { role: accountant, verb: all, path: api/v2/dalan/admin/activities/admin, action: drop } + # we are watching after you 0_0 + - { role: accountant, verb: post, path: api/v2/, action: audit } + - { role: accountant, verb: put, path: api/v2/, action: audit } + - { role: accountant, verb: delete, path: api/v2/, action: audit } + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: accountant, verb: all, path: api/v2/dena/account, action: accept } + - { role: accountant, verb: all, path: api/v2/dena/market, action: accept } + - { role: accountant, verb: all, path: api/v2/finex/market, action: accept } + - { role: accountant, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: accountant, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: accountant, verb: all, path: api/v2/dena/swagger, action: accept } + # Drop Peatio order endpoint requests +<%- if @config['finex']['enabled'] -%> + - { role: accountant, verb: post, path: api/v2/dena/market/orders, action: drop } + - { role: accountant, verb: post, path: api/v2/dena/admin/orders, action: drop } +<%- end -%> + # ranger access + - { role: accountant, verb: get, path: api/v2/ranger, action: accept } + # applogic access + - { role: accountant, verb: all, path: api/v2/applogic, action: accept } + # get abilities + - { role: accountant, verb: all, path: api/v2/dena/admin/abilities, action: accept } + - { role: accountant, verb: all, path: api/v2/dalan/admin/abilities, action: accept } + +# COMPLIANCE + - { role: compliance, verb: get, path: api/v2/dalan/admin, action: accept } + # has an access to CRUD of user-related resources + - { role: compliance, verb: get, path: api/v2/dena/admin/members, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/beneficiaries, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/currencies, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/trades, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/orders, action: accept } + - { role: compliance, verb: all, path: api/v2/dalan/admin/users, action: accept } + # has ability to see deposit, withdraw, operations (partial) + - { role: compliance, verb: get, path: api/v2/dena/admin/deposits, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/withdraws, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/assets, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/liabilities, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/expenses, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/markets, action: accept } + - { role: compliance, verb: get, path: api/v2/dena/admin/engine, action: accept } + # has no ability to see the configurations + - { role: compliance, verb: all, path: api/v2/dena/admin/adjustments, action: drop } + - { role: compliance, verb: all, path: api/v2/dena/admin/revenues, action: drop } + - { role: compliance, verb: all, path: api/v2/dena/admin/blockchains, action: drop } + - { role: compliance, verb: all, path: api/v2/dena/admin/wallets, action: drop } + - { role: compliance, verb: all, path: api/v2/dena/admin/trading_fees, action: drop } + - { role: compliance, verb: all, path: api/v2/dena/admin/withdraw_limits, action: drop } + - { role: compliance, verb: all, path: api/v2/dalan/admin/restrictions, action: drop } + # compliance doesnt have access to change users roles + - { role: compliance, verb: all, path: api/v2/dalan/admin/users/role, action: drop } + # compliance doesnt have access to admin activities + - { role: compliance, verb: all, path: api/v2/dalan/admin/activities/admin, action: drop } + # compliance doesnt have access to manage platform roles and permissions + - { role: compliance, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + # we are watching after you 0_0 + - { role: compliance, verb: post, path: api/v2/, action: audit } + - { role: compliance, verb: put, path: api/v2/, action: audit } + - { role: compliance, verb: delete, path: api/v2/, action: audit } + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: compliance, verb: all, path: api/v2/dena/account, action: accept } + - { role: compliance, verb: all, path: api/v2/dena/market, action: accept } + - { role: compliance, verb: all, path: api/v2/finex/market, action: accept } + - { role: compliance, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: compliance, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: compliance, verb: all, path: api/v2/dena/swagger, action: accept } + # Drop Peatio order endpoint requests +<%- if @config['finex']['enabled'] -%> + - { role: compliance, verb: post, path: api/v2/dena/market/orders, action: drop } + - { role: compliance, verb: post, path: api/v2/dena/admin/orders, action: drop } +<%- end -%> + # ranger access + - { role: compliance, verb: get, path: api/v2/ranger, action: accept } + # applogic access + - { role: compliance, verb: all, path: api/v2/applogic, action: accept } + # get abilities + - { role: compliance, verb: all, path: api/v2/dena/admin/abilities, action: accept } + - { role: compliance, verb: all, path: api/v2/dalan/admin/abilities, action: accept } + +# TECHNICAL + # has an access to CRUD of peatio admin functionality on market, blockchain, wallets, currencies + - { role: technical, verb: get, path: api/v2/dalan/admin, action: accept } + - { role: technical, verb: get, path: api/v2/dena/admin, action: accept } + # technical has a configuration access to Peatio admin + - { role: technical, verb: all, path: api/v2/dena/admin/blockchains, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/currencies, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/markets, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/wallets, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/trading_fees, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/withdraw_limits, action: accept } + - { role: technical, verb: get, path: api/v2/dena/admin/internal_transfers, action: accept } + - { role: technical, verb: all, path: api/v2/dena/admin/engine, action: accept } + # technical has access to delete orders + - { role: technical, verb: delete, path: api/v2/finex/admin/bulk/orders_by_id, action: accept } + - { role: technical, verb: post, path: api/v2/finex/admin/orders/cancel, action: accept } + # technical has an ability to create and update restrictions + - { role: technical, verb: all, path: api/v2/dalan/admin/restrictions, action: accept } + # has no ability to see and update Deposit, Withdraw, Adjustments + - { role: technical, verb: all, path: api/v2/dena/admin/deposits, action: drop } + - { role: technical, verb: all, path: api/v2/dena/admin/withdraws, action: drop } + - { role: technical, verb: all, path: api/v2/dena/admin/adjustments, action: drop } + # Finex upstream access + - { role: technical, verb: get, path: api/v2/open_finance, action: accept } + # technical doesnt have access to see pending documents + - { role: technical, verb: get, path: api/v2/dalan/admin/users/documents/pending, action: drop } + # technical doesnt have access to admin activities + - { role: technical, verb: all, path: api/v2/dalan/admin/activities/admin, action: drop } + # technical doesnt have access to manage platform roles and permissions + - { role: technical, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + # we are watching after you 0_0 + - { role: technical, verb: post, path: api/v2/, action: audit } + - { role: technical, verb: put, path: api/v2/, action: audit } + - { role: technical, verb: delete, path: api/v2/, action: audit } + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: technical, verb: all, path: api/v2/dena/account, action: accept } + - { role: technical, verb: all, path: api/v2/dena/market, action: accept } + - { role: technical, verb: all, path: api/v2/finex/market, action: accept } + - { role: technical, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: technical, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: technical, verb: all, path: api/v2/dena/swagger, action: accept } + # Drop Peatio order endpoint requests +<%- if @config['finex']['enabled'] -%> + - { role: technical, verb: post, path: api/v2/dena/market/orders, action: drop } + - { role: technical, verb: post, path: api/v2/dena/admin/orders, action: drop } +<%- end -%> + # ranger access + - { role: technical, verb: get, path: api/v2/ranger, action: accept } + # applogic access + - { role: technical, verb: all, path: api/v2/applogic, action: accept } + # get abilities + - { role: technical, verb: all, path: api/v2/dena/admin/abilities, action: accept } + - { role: technical, verb: all, path: api/v2/dalan/admin/abilities, action: accept } + +# SUPPORT + # has read only access to several statistic and user-related endpoints + - { role: support, verb: get, path: api/v2/dalan/admin, action: accept } + - { role: support, verb: get, path: api/v2/dena/admin, action: accept } + # has no ability to see the configurations + - { role: support, verb: all, path: api/v2/dena/admin/adjustments, action: drop } + - { role: support, verb: all, path: api/v2/dena/admin/revenues, action: drop } + - { role: support, verb: all, path: api/v2/dena/admin/blockchains, action: drop } + - { role: support, verb: all, path: api/v2/dena/admin/wallets, action: drop } + - { role: support, verb: all, path: api/v2/dena/admin/trading_fees, action: drop } + - { role: support, verb: all, path: api/v2/dena/admin/withdraw_limits, action: drop } + - { role: support, verb: all, path: api/v2/dalan/admin/restrictions, action: drop } + - { role: support, verb: get, path: api/v2/dena/admin/internal_transfers, action: accept } + - { role: support, verb: get, path: api/v2/dena/admin/engine, action: accept } + # has ability to disable 2FA + - { role: support, verb: post, path: api/v2/dalan/admin/users/update, action: accept } + # support doesnt have access to admin activities + - { role: support, verb: all, path: api/v2/dalan/admin/activities/admin, action: drop } + # support doesnt have access to manage platform roles and permissions + - { role: support, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + - { role: support, verb: all, path: api/v2/dalan/admin/permissions, action: drop } + # we are watching after you 0_0 + - { role: support, verb: post, path: api/v2/, action: audit } + - { role: support, verb: put, path: api/v2/, action: audit } + - { role: support, verb: delete, path: api/v2/, action: audit } + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: support, verb: all, path: api/v2/dena/account, action: accept } + - { role: support, verb: all, path: api/v2/dena/market, action: accept } + - { role: support, verb: all, path: api/v2/finex/market, action: accept } + - { role: support, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: support, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: support, verb: all, path: api/v2/dena/swagger, action: accept } + # Drop Peatio order endpoint requests +<%- if @config['finex']['enabled'] -%> + - { role: support, verb: post, path: api/v2/dena/market/orders, action: drop } + - { role: support, verb: post, path: api/v2/dena/admin/orders, action: drop } +<%- end -%> + # ranger access + - { role: support, verb: get, path: api/v2/ranger, action: accept } + # applogic access + - { role: support, verb: all, path: api/v2/applogic, action: accept } + # get abilities + - { role: support, verb: all, path: api/v2/dena/admin/abilities, action: accept } + - { role: support, verb: all, path: api/v2/dalan/admin/abilities, action: accept } + +# TRADER + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: trader, verb: all, path: api/v2/dena/account, action: accept } +<%- if @config['finex']['enabled'] -%> + - { role: trader, verb: get, path: api/v2/dena/market, action: accept } + - { role: trader, verb: all, path: api/v2/finex/market, action: accept } + - { role: trader, verb: post, path: api/v2/dena/market/orders, action: drop } +<%- else -%> + - { role: trader, verb: all, path: api/v2/dena/market, action: accept } +<%- end -%> + - { role: trader, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: trader, verb: all, path: api/v2/resource, action: accept } + - { role: trader, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: trader, verb: all, path: api/v2/dena/swagger, action: accept } + # ranger access + - { role: trader, verb: get, path: api/v2/ranger, action: accept } + # Finex upstream access + - { role: trader, verb: get, path: api/v2/open_finance, action: accept } + # applogic access + - { role: trader, verb: all, path: api/v2/applogic, action: accept } + +# MEMBER + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: member, verb: all, path: api/v2/dena/account, action: accept } +<%- if @config['finex']['enabled'] -%> + - { role: member, verb: get, path: api/v2/dena/market, action: accept } + - { role: member, verb: all, path: api/v2/finex/market, action: accept } + - { role: member, verb: post, path: api/v2/dena/market/orders, action: drop } +<%- else -%> + - { role: member, verb: all, path: api/v2/dena/market, action: accept } +<%- end -%> + - { role: member, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: member, verb: all, path: api/v2/resource, action: accept } + - { role: member, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: member, verb: all, path: api/v2/dena/swagger, action: accept } + # ranger access + - { role: member, verb: get, path: api/v2/ranger, action: accept } + # Finex upstream access + - { role: member, verb: get, path: api/v2/open_finance, action: accept } + # applogic access + - { role: member, verb: all, path: api/v2/applogic, action: accept } + +# BROKER + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: broker, verb: all, path: api/v2/dena/account, action: accept } +<%- if @config['finex']['enabled'] -%> + - { role: broker, verb: get, path: api/v2/dena/market, action: accept } + - { role: broker, verb: all, path: api/v2/finex/market, action: accept } + - { role: broker, verb: post, path: api/v2/dena/market/orders, action: drop } +<%- else -%> + - { role: broker, verb: all, path: api/v2/dena/market, action: accept } +<%- end -%> + - { role: broker, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: broker, verb: all, path: api/v2/resource, action: accept } + - { role: broker, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: broker, verb: all, path: api/v2/dena/swagger, action: accept } + # ranger access + - { role: broker, verb: get, path: api/v2/ranger, action: accept } + # Finex upstream access + - { role: broker, verb: get, path: api/v2/open_finance, action: accept } + # applogic access + - { role: broker, verb: all, path: api/v2/applogic, action: accept } + +# MAKER + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: maker, verb: all, path: api/v2/dena/account, action: accept } +<%- if @config['finex']['enabled'] -%> + - { role: maker, verb: get, path: api/v2/dena/market, action: accept } + - { role: maker, verb: all, path: api/v2/finex/market, action: accept } + - { role: maker, verb: post, path: api/v2/dena/market/orders, action: drop } +<%- else -%> + - { role: maker, verb: all, path: api/v2/dena/market, action: accept } +<%- end -%> + - { role: maker, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: maker, verb: all, path: api/v2/resource, action: accept } + - { role: maker, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: maker, verb: all, path: api/v2/dena/swagger, action: accept } + # ranger access + - { role: maker, verb: get, path: api/v2/ranger, action: accept } + # Finex upstream access + - { role: maker, verb: get, path: api/v2/open_finance, action: accept } + # applogic access + - { role: maker, verb: all, path: api/v2/applogic, action: accept } + +# Service Account Maker + # has standard user permissions to ACCOUNT, MARKET, RESOURCE modules + - { role: sa_maker, verb: all, path: api/v2/dena/account, action: accept } +<%- if @config['finex']['enabled'] -%> + - { role: sa_maker, verb: get, path: api/v2/dena/market, action: accept } + - { role: sa_maker, verb: all, path: api/v2/finex/market, action: accept } + - { role: sa_maker, verb: post, path: api/v2/dena/market/orders, action: drop } +<%- else -%> + - { role: sa_maker, verb: all, path: api/v2/dena/market, action: accept } +<%- end -%> + - { role: sa_maker, verb: all, path: api/v2/dalan/resource, action: accept } + - { role: sa_maker, verb: all, path: api/v2/dena/account/internal_transfers, action: accept } + - { role: sa_maker, verb: all, path: api/v2/dena/swagger, action: accept } + # Service Account can not interact with Password, 2FA, KYC, API keys, Beneficiary, Deposit and Withdraw + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/otp, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/phones, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/profiles, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/documents, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/addresses, action: drop } + - { role: sa_maker, verb: all, path: api/v2/applogic/private/tenants, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/api_keys, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dalan/resource/users/password, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dena/account/deposit_address, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dena/account/withdraws, action: drop } + - { role: sa_maker, verb: all, path: api/v2/dena/account/beneficiaries, action: drop } + # Finex upstream access + - { role: sa_maker, verb: get, path: api/v2/open_finance, action: accept } + # ranger access + - { role: sa_maker, verb: get, path: api/v2/ranger, action: accept } + # applogic access + - { role: sa_maker, verb: all, path: api/v2/applogic, action: accept } diff --git a/templates/config/bitcoin.conf.erb b/templates/config/bitcoin.conf.erb new file mode 100644 index 0000000..176671b --- /dev/null +++ b/templates/config/bitcoin.conf.erb @@ -0,0 +1,18 @@ +<%- bitcoind = @config['bitcoind'] -%> +txindex=1 +dnsseed=1 +upnp=0 +printtoconsole=1 + +server=1 + +<%- unless bitcoind['network'] == 'mainnet' -%> +<%= "#{bitcoind['network']}=1" %> +[test] +<%- end -%> +rpcuser=<%= bitcoind['rpcuser'] %> +rpcpassword=<%= bitcoind['rpcpassword'] %> +port=<%= bitcoind['port'] %> +rpcport=<%= bitcoind['rpcport'] %> +rpcbind=0.0.0.0 +rpcallowip=0.0.0.0/0 diff --git a/templates/config/finex/config.yaml.erb b/templates/config/finex/config.yaml.erb new file mode 100644 index 0000000..4e34c1f --- /dev/null +++ b/templates/config/finex/config.yaml.erb @@ -0,0 +1,96 @@ +metrics: + enabled: true +license: <%= @config['finex']['license_key'] %> +influx: + host: influxdb + port: 8086 + scheme: http + database: peatio_production +database: + driver: mysql + name: peatio_production + username: <%= @config['database']['user'] %> + password: <%= @config['database']['password'] %> + host: <%= @config['database']['host'] %> + port: <%= @config['database']['port'] %> +log_level: + log_observer: info +vault: + host: http://vault:8200 + token: <%= @config['vault']['finex_engine_token'] %> + app_name: <%= @config['app']['name'].downcase %> +messaging: + driver: amqp + username: guest + password: guest + host: rabbitmq + port: 5672 + exchanges: + - name: finex.orderapi + type: direct + durable: false + - name: finex.events.websocket + type: topic + durable: false + - name: peatio.events.ranger + type: topic + durable: false + - name: peatio.trade + type: headers + durable: false + - name: peatio.events + type: direct + durable: false + - name: peatio.matching + type: direct + durable: false + queues: + - name: finex.gateway + - name: finex.events.processor + - name: finex.influx.writer +orderbook: + max_publish_size: 300 +gateway: + rate: + maker: + - limit: 500 + period: 10s + admin: + - limit: 500 + period: 10s + superadmin: + - limit: 500 + period: 10s + bench: + - limit: 9000 + period: 1s + default: + - limit: 50 + period: 10s + - limit: 10000 + period: 24h +api: + bulk_limit: 100 + rate: + maker: + limit: 500 + period: 10s + admin: + limit: 500 + period: 10s + superadmin: + limit: 500 + period: 10s + default: + limit: 5 + period: 1s + actions: + trade: + min_level: 2 + roles: [member, broker, trader, maker, admin, superadmin] + bulk_api: + min_level: 3 + roles: [maker, admin, superadmin] + admin: + min_level: 3 + roles: [admin, superadmin] diff --git a/templates/config/finex/rsa-key.pub.erb b/templates/config/finex/rsa-key.pub.erb new file mode 100644 index 0000000..7675f5b --- /dev/null +++ b/templates/config/finex/rsa-key.pub.erb @@ -0,0 +1 @@ +<%= Base64.decode64(@barong_public_key) %> diff --git a/templates/config/frontend/env.js.erb b/templates/config/frontend/env.js.erb new file mode 100644 index 0000000..7cd8a56 --- /dev/null +++ b/templates/config/frontend/env.js.erb @@ -0,0 +1,37 @@ +window.env = { + api: { + authUrl: '<%= ssl_helper('http') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>/api/v2/dalan', + tradeUrl: '<%= ssl_helper('http') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>/api/v2/dena', + finexUrl: '<%= ssl_helper('http') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>/api/v2/finex', + applogicUrl: '<%= ssl_helper('http') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>/api/v2/applogic', + rangerUrl: '<%= ssl_helper('ws') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>/api/v2/ranger', + }, + minutesUntilAutoLogout: '35', + withCredentials: false, + finex: <%= config['finex']['enabled'] %>, + gaTrackerKey: '<%= @config['gaTrackerKey'] %>', + ga4TrackerKey: '<%= @config['ga4TrackerKey'] %>', + rangerReconnectPeriod: '1', + msAlertDisplayTime: '5000', + incrementalOrderBook: true, + isResizable: false, + isDraggable: false, + languages: ['en', 'ru'], + sessionCheckInterval: '15000', + balancesFetchInterval: '3000', + passwordEntropyStep: 14, + showLanding: <%= @config['app']['show_landing'] %>, + sentryEnabled: true, + kycSteps: [ + 'profile', + 'access_phone', + 'card', + 'iban', + 'poa', + 'telephone', + 'selfie', + 'owner_phone', + 'vip' + ], + captchaLogin: <%= @config['captchaLogin'] %> +}; diff --git a/templates/config/frontend/shahoo.env.js.erb b/templates/config/frontend/shahoo.env.js.erb new file mode 100644 index 0000000..9cd0a84 --- /dev/null +++ b/templates/config/frontend/shahoo.env.js.erb @@ -0,0 +1,24 @@ +window.env = window.env || {}; +<% domain = @config['app']['domain'].to_s.strip %> +<% brand_slug = domain.split('.').first.to_s.downcase %> +<% brand_name = brand_slug.empty? ? @config['app']['name'].to_s : brand_slug.capitalize %> +<% exchange_slug = brand_slug.empty? ? brand_name.downcase : brand_slug %> +<% shahoo_host = @config['app']['shahoo_host'].to_s.strip %> +<% shahoo_host = "#{@config['app']['shahoo_subdomain'] || 'shahoo'}.#{domain}" if shahoo_host.empty? %> +window.env.app = { + domain: '<%= domain %>', + name: '<%= @config['app']['name'] %>', + brandName: '<%= brand_name %>', + exchangeSlug: '<%= exchange_slug %>', +}; +window.env.api = { + rangerUrl: '<%= ssl_helper('ws') %>://<%= shahoo_host %>/api/v2/ranger', +}; +window.env.rangerEnabled = true; +window.env.incrementalOrderBook = true; +window.env.captcha = { + captchaType: '<%= @config['captcha']['type'] %>', + siteKey: '<%= @config['captcha']['siteKey'] %>', +}; +window.env.captchaLogin = <%= @config['captchaLogin'] %>; +window.env.showLanding = <%= !!@config.dig('app', 'show_landing') %>; diff --git a/templates/config/frontend/tower.js.erb b/templates/config/frontend/tower.js.erb new file mode 100644 index 0000000..c1280ac --- /dev/null +++ b/templates/config/frontend/tower.js.erb @@ -0,0 +1,73 @@ +window.env = { + applogicUrl: '<%= ssl_helper('http') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>/api/v2/applogic', + authUrl: '<%= ssl_helper('http') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>/api/v2/dalan', + peatioUrl: '<%= ssl_helper('http') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>/api/v2/dena', + finexUrl: '<%= ssl_helper('http') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>/api/v2/finex', + msAlertDisplayTime: '5000', + tablePageLimit: 50, + minutesUntilAutoLogout: '35', + finex: <%= config['finex']['enabled'] %>, + aml: false, + captcha: { + captchaType: '<%= @config['captcha']['type'] %>', + siteKey: '<%= @config['captcha']['siteKey'] %>', + }, + labelSwitcher: [ + { name: 'email', label: [{ email: 'verified' }] }, + { name: 'phone', label: [{ phone: 'verified' }] }, + { name: 'identity', label: [{ profile: 'partial' }, { id_document: 'verified' }, { liveness: 'verified' }] }, + { name: 'residence', label: [{ document: 'verified' }] }, + ], + plugins: [], + roleTypes: [ + { + value: 'Admin', + key: 'admin', + }, + { + value: 'Member', + key: 'member', + }, + { + value: 'Super Admin', + key: 'superadmin', + }, + { + value: 'Accountant', + key: 'accountant', + }, + { + value: 'Compliance', + key: 'compliance', + }, + { + value: 'Technical', + key: 'technical', + }, + { + value: 'Support', + key: 'support', + }, + { + value: 'Trader', + key: 'trader', + }, + { + value: 'Broker', + key: 'broker', + }, + ], + allowedRoles: [ + 'admin', + 'superadmin', + 'accountant', + 'compliance', + 'support', + 'technical', + 'manager', + ], + withCredentials: false, + sentryEnabled: false, + devMode: false, + minutesBeforeWarningMessage: '1', +}; diff --git a/templates/config/gateway/envoy.yaml.erb b/templates/config/gateway/envoy.yaml.erb new file mode 100644 index 0000000..4113c97 --- /dev/null +++ b/templates/config/gateway/envoy.yaml.erb @@ -0,0 +1,174 @@ +static_resources: + listeners: + - address: + socket_address: + address: 0.0.0.0 + port_value: 8099 + filter_chains: + - filters: + - name: envoy.http_connection_manager + config: + codec_type: auto + stat_prefix: ingress_http + route_config: + name: local_route + virtual_hosts: + - name: backend + domains: + - "*" + cors: + allow_origin: + - "<%= ssl_helper('http') %>://<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %>" + allow_methods: "PUT, GET, POST" + allow_headers: "content-type, x-grpc-web" + filter_enabled: + default_value: + numerator: 100 + denominator: HUNDRED + runtime_key: cors.www.enabled + routes: + - match: + <%# prefix: "/api/v2/barong" %> + prefix: "/api/v2/dalan" + route: + cluster: barong + prefix_rewrite: "/api/v2/" + - match: + prefix: "/api/v2/applogic" + route: + cluster: applogic + prefix_rewrite: "/api/v2/" + - match: + prefix: "/api/v2/arke" + route: + cluster: arke + prefix_rewrite: "/api/v2/" + - match: + <%# prefix: "/api/v2/peatio" %> + prefix: "/api/v2/dena" + route: + cluster: peatio + prefix_rewrite: "/api/v2/" + - match: + prefix: "/api/v2/finex" + route: + cluster: finex + prefix_rewrite: "/api/v2/" + - match: + prefix: "/admin" + route: + cluster: peatio + - match: + prefix: "/assets/" + route: + cluster: peatio + - match: + prefix: "/api/v2/ranger/public" + route: + cluster: rango + prefix_rewrite: "" + upgrade_configs: + upgrade_type: "websocket" + - match: + prefix: "/api/v2/ranger/private" + route: + cluster: rango + prefix_rewrite: "" + upgrade_configs: + upgrade_type: "websocket" + http_filters: + - name: envoy.cors + typed_config: {} + - name: envoy.ext_authz + config: + with_request_body: + max_request_bytes: 90000000 + allow_partial_message: true + http_service: + authorization_request: + allowed_headers: + patterns: + - exact: cookie + - exact: x-auth-apikey + - exact: x-auth-nonce + - exact: x-auth-signature + - exact: x-csrf-token + - exact: user-agent + - exact: x-forwarded-host + - exact: x-forwarded-for + - exact: from + - exact: x-forwarded-proto + - exact: proxy-authorization + authorization_response: + allowed_upstream_headers: + patterns: + - exact: authorization + allowed_client_headers: + patterns: + - exact: set-cookie + - exact: proxy-authenticate + - exact: www-authenticate + - exact: location + path_prefix: "/api/v2/auth" + server_uri: + cluster: barong + timeout: 1.000s + uri: http://barong:8001 + - name: envoy.router + config: {} + perConnectionBufferLimitBytes: 10000000 + clusters: + - name: barong + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + hosts: + - socket_address: + address: barong + port_value: 8001 + - name: applogic + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + hosts: + - socket_address: + address: applogic + port_value: 8081 + - name: arke + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + hosts: + - socket_address: + address: arke + port_value: 8081 + - name: peatio + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + hosts: + - socket_address: + address: peatio + port_value: 8000 + - name: finex + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + hosts: + - socket_address: + address: finex-api + port_value: 8080 + - name: rango + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + hosts: + - socket_address: + address: rango + port_value: 8080 +admin: + access_log_path: "/dev/null" + address: + socket_address: + address: 0.0.0.0 + port_value: 9099 diff --git a/templates/config/litecoin.conf.erb b/templates/config/litecoin.conf.erb new file mode 100644 index 0000000..b105fa8 --- /dev/null +++ b/templates/config/litecoin.conf.erb @@ -0,0 +1,20 @@ +<%- litecoind = @config['litecoind'] -%> +txindex=1 +dnsseed=1 +upnp=0 +printtoconsole=1 + +server=1 + +onlynet=ipv4 + +<%- unless litecoind['network'] == 'mainnet' -%> +<%= "#{litecoind['network']}=1" %> +[test] +<%- end -%> +rpcuser=<%= litecoind['rpcuser'] %> +rpcpassword=<%= litecoind['rpcpassword'] %> +port=<%= litecoind['port'] %> +rpcport=<%= litecoind['rpcport'] %> +rpcbind=0.0.0.0 +rpcallowip=0.0.0.0/0 diff --git a/templates/config/mailer.yml.erb b/templates/config/mailer.yml.erb new file mode 100644 index 0000000..c7203de --- /dev/null +++ b/templates/config/mailer.yml.erb @@ -0,0 +1,174 @@ +keychain: + barong: + algorithm: RS256 + value: "<%= @barong_public_key %>" + peatio: + algorithm: RS256 + value: "<%= @barong_public_key %>" + +exchanges: + barong_system: + name: barong.events.system + signer: barong + barong_model: + name: barong.events.model + signer: barong + peatio: + name: peatio.events.model + signer: peatio + peatio_system: + name: peatio.events.system + signer: peatio +events: + - name: Email Confirmation + key: user.email.confirmation.token + exchange: barong_system + templates: + en: + subject: Registration Confirmation + template_path: email_confirmation.en.html.erb + ru: + subject: Подтверждение Регистрации + template_path: email_confirmation.ru.html.erb + + - name: Email Confirmation by Code + key: user.email.confirmation.code + exchange: barong_system + templates: + en: + subject: Registration Confirmation + template_path: email_confirmation_code.en.html.erb + + - name: Password Reset + key: user.password.reset.token + exchange: barong_system + templates: + en: + subject: Password Reset + template_path: password_reset.en.html.erb + ru: + subject: Сброс Пароля + template_path: password_reset.ru.html.erb + + - name: Password Reset by confirm code + key: user.password.confirmation.code + exchange: barong_system + templates: + en: + subject: Password Reset + template_path: password_confirmation_code.en.html.erb + + - name: Label Created + key: label.created + exchange: barong_model + expression: | + record.key in ["phone", "profile", "document"] && + record.value in ["verified", "rejected"] + templates: + en: + subject: Label verified + template_path: label.en.html.erb + + - name: otp enable Confirmation by Code + key: user.email.otp.enable + exchange: barong_system + templates: + en: + subject: otp enable code + template_path: email_otp_enable_confirmation_code.en.html.erb + + - name: otp disable Confirmation by Code + key: user.email.otp.disable + exchange: barong_system + templates: + en: + subject: otp disable code + template_path: email_otp_disable_confirmation_code.en.html.erb + + - name: Label Updated + key: label.updated + exchange: barong_model + expression: | + record.key in ["phone", "profile", "document"] && + record.value in ["verified", "rejected"] + templates: + en: + subject: Label Updated + template_path: label.en.html.erb + + - name: Session Create + key: session.create + exchange: barong_system + templates: + en: + subject: New Login + template_path: session_create.en.html.erb + + - name: Session failed + key: session.failed + exchange: barong_system + templates: + en: + subject: Failed Login + template_path: session_failed.en.html.erb + + - name: Deposit Accepted + key: deposit.updated + exchange: peatio + expression: | + changes.state == "submitted" && + record.state == "accepted" templates: + en: + subject: Deposit Accepted + template_path: deposit_accepted.en.html.erb + + - name: Withdrawal Succeed + key: withdraw.updated + exchange: peatio + expression: | + changes.state in ["succeed", "rejected", "canceled", "failed", "accepted"] && + record.state in ["succeed", "rejected", "canceled", "failed"] + templates: + en: + subject: Withdrawal Succeed + template_path: withdraw_succeed.en.html.erb + + - name: New Beneficiary + key: beneficiary.created + exchange: peatio + templates: + en: + subject: New Beneficiary + template_path: new_beneficiary.en.html.erb + + - name: Resend beneficiary + key: beneficiary.updated + exchange: peatio + expression: + and: + record.state: 'pending' + templates: + EN: + subject: Resend Beneficiary + template_path: new_beneficiary.en.html.erb + + - name: New Withdraw Otp + key: user.withdraw.confirm.code + exchange: peatio_system + templates: + en: + subject: New Withdraw Otp + template_path: withdraw_confirmation_code.en.html.erb + + # expression example + # - name: Session Create + # key: session.create + # expression: + # and: # need to use and/or/not operator here + # record.user_ip: '::1' # full patch to key + # record.user.role: 'member' + # exchange: barong_system + # templates: + # en: + # subject: New Login + # template_path: session_create.en.html.erb diff --git a/templates/config/monitoring/alertmanager/config.yml.erb b/templates/config/monitoring/alertmanager/config.yml.erb new file mode 100644 index 0000000..0d4a5c2 --- /dev/null +++ b/templates/config/monitoring/alertmanager/config.yml.erb @@ -0,0 +1,20 @@ +global: + # The smarthost and SMTP sender used for mail notifications. + smtp_smarthost: 'mail.fibitex.com:587' + smtp_from: 'info@fibitex.com' + smtp_auth_username: 'info@fibitex.com' + smtp_auth_password: '1qaz2wsx!QAZ@WSX' + smtp_auth_identity: 'info@fibitex.com' + +route: + group_by: ['instance', 'severity'] + group_wait: 30s + group_interval: 30s + repeat_interval: 30m + receiver: 'stage' + +receivers: +- name: 'stage' + email_configs: + - send_resolved: true + to: 'EMAIL-MAILBOX-FOR-RECEIVER' diff --git a/templates/config/monitoring/loki/local-config.yaml.erb b/templates/config/monitoring/loki/local-config.yaml.erb new file mode 100644 index 0000000..4e42b63 --- /dev/null +++ b/templates/config/monitoring/loki/local-config.yaml.erb @@ -0,0 +1,37 @@ +auth_enabled: false + +server: + http_listen_port: 3100 + grpc_listen_port: 9095 + +ingester: + lifecycler: + address: 127.0.0.1 + ring: + kvstore: + store: inmemory + replication_factor: 1 + chunk_idle_period: 15m + wal: + enabled: true + dir: /loki/wal + +schema_config: + configs: + - from: 2022-01-01 + store: boltdb + object_store: filesystem + schema: v11 + index: + prefix: index_ + period: 168h + +storage_config: + boltdb: + directory: ./loki/index + + filesystem: + directory: ./loki/chunks + +limits_config: + enforce_metric_name: false diff --git a/templates/config/monitoring/prometheus/alert/Alertmanager.rules b/templates/config/monitoring/prometheus/alert/Alertmanager.rules new file mode 100644 index 0000000..5a324ab --- /dev/null +++ b/templates/config/monitoring/prometheus/alert/Alertmanager.rules @@ -0,0 +1,12 @@ +groups: +- name: Alertmanager_Alerts + rules: + + - alert: AlertmanagerConfigurationReload + expr: alertmanager_config_last_reload_successful != 1 + for: 5m + labels: + severity: page + annotations: + summary: "AlertManager configuration reload (instance {{ $labels.instance }})" + description: "AlertManager configuration reload error\n VALUE = {{ $value }}\n LABELS: {{ $labels }}" diff --git a/templates/config/monitoring/prometheus/alert/Prometheus.rules b/templates/config/monitoring/prometheus/alert/Prometheus.rules new file mode 100644 index 0000000..04513f8 --- /dev/null +++ b/templates/config/monitoring/prometheus/alert/Prometheus.rules @@ -0,0 +1,12 @@ +groups: +- name: Prometheus_Alerts + rules: + + - alert: PrometheusConfigurationReload + expr: prometheus_config_last_reload_successful != 1 + for: 2m + labels: + severity: error + annotations: + summary: "Prometheus configuration reload (instance {{ $labels.instance }})" + description: "Prometheus configuration reload error\n VALUE = {{ $value }}\n LABELS: {{ $labels }}" diff --git a/templates/config/monitoring/prometheus/prometheus.yml.erb b/templates/config/monitoring/prometheus/prometheus.yml.erb new file mode 100644 index 0000000..359398b --- /dev/null +++ b/templates/config/monitoring/prometheus/prometheus.yml.erb @@ -0,0 +1,41 @@ +global: + scrape_interval: 30s + evaluation_interval: 30s + + # Attach these labels to any time series or alerts when communicating with + # external systems (federation, remote storage, Alertmanager). + external_labels: + monitor: 'prom' + +# Load and evaluate rules in this file every 'evaluation_interval' seconds. +rule_files: + - 'alerts/*.rules' + +# alert +alerting: + alertmanagers: + - scheme: http + static_configs: + - targets: + - "alertmanager:9093" + +scrape_configs: + - job_name: 'prometheus' + static_configs: + - targets: ['localhost:9090'] + + - job_name: 'alertmanager' + static_configs: + - targets: ['alertmanager:9093'] + + - job_name: 'grafana' + static_configs: + - targets: ['grafana:3000'] + + - job_name: 'cadvisor' + static_configs: + - targets: ['cadvisor:8080'] + + - job_name: 'node-exporter' + static_configs: + - targets: ['node-exporter:9100'] diff --git a/templates/config/monitoring/promtail/docker-config.yaml.erb b/templates/config/monitoring/promtail/docker-config.yaml.erb new file mode 100644 index 0000000..cf1646d --- /dev/null +++ b/templates/config/monitoring/promtail/docker-config.yaml.erb @@ -0,0 +1,19 @@ +server: + http_listen_port: 9080 + grpc_listen_port: 0 + +positions: + filename: /tmp/positions.yaml + +clients: + - url: http://loki:3100/api/prom/push + +scrape_configs: +- job_name: system + static_configs: + - targets: + - localhost + labels: + job: varlogs + host: monitoring + __path__: /var/log/*.log diff --git a/templates/config/mysql/innodb.cnf.erb b/templates/config/mysql/innodb.cnf.erb new file mode 100644 index 0000000..701a230 --- /dev/null +++ b/templates/config/mysql/innodb.cnf.erb @@ -0,0 +1,6 @@ +[mysqld] +innodb_buffer_pool_size = 2G +innodb_buffer_pool_instances = 2 +innodb_log_buffer_size = 128M +innodb_log_file_size = 512M +innodb_flush_log_at_trx_commit = 0 diff --git a/templates/config/peatio.env.erb b/templates/config/peatio.env.erb new file mode 100644 index 0000000..0fd7160 --- /dev/null +++ b/templates/config/peatio.env.erb @@ -0,0 +1,64 @@ +RAILS_ENV=production +RAILS_ROOT=/home/app + +PORT=8000 +URL_HOST=<%= @config['app']['subdomain'] %>.<%= @config['app']['domain'] %> + +LOG_LEVEL=warn + +ADMIN=<%= @config['admin']['user'] %> + +<%- if @config['database']['adapter'] == 'postgresql' %> +DATABASE_COLLATION="" +DATABASE_ADAPTER="postgresql" +<%- elsif @config['database']['adapter'] == 'mysql' %> +DATABASE_ADAPTER="mysql2" +<%- end %> +DATABASE_HOST=<%= @config['database']['host'] %> +DATABASE_PORT=<%= @config['database']['port'] %> +DATABASE_USER=<%= @config['database']['user'] %> +DATABASE_PASS=<%= @config['database']['password'] %> + +VAULT_ADDR=http://vault:8200 +VAULT_TOKEN= +VAULT_APP_NAME=<%= @config['app']['name'].downcase %> + +REDIS_URL=redis://redis:6379 + +RABBITMQ_HOST=rabbitmq + + +MARKETS_CONFIG=/opt/peatio/config/seed/markets.yml +CURRENCIES_CONFIG=/opt/peatio/config/seed/currencies.yml +MANAGEMENT_API_V1_CONFIG=/opt/peatio/config/management_api_v1.yml + +JWT_AUDIENCE=peatio,barong +JWT_PUBLIC_KEY=<%= @barong_public_key %> + +INFLUXDB_HOST=influxdb + +EVENT_API_JWT_PRIVATE_KEY=<%= @barong_private_key %> +EVENT_API_JWT_ALGORITHM=RS256 +EVENT_API_RABBITMQ_HOST=rabbitmq +EVENT_API_RABBITMQ_PORT=5672 +EVENT_API_RABBITMQ_USERNAME=guest +EVENT_API_RABBITMQ_PASSWORD=guest + +MINIMUM_MEMBER_LEVEL_FOR_DEPOSIT=0 +MINIMUM_MEMBER_LEVEL_FOR_WITHDRAW=1 +MINIMUM_MEMBER_LEVEL_FOR_TRADING=0 + + +SECRET_KEY_BASE=dd239be9285b4c3e8b6bc524b3ba7081 +FORCE_SECURE_CONNECTION="false" + +REFERRAL_FEE=0.35 +VIP_1_AMOUNT = 100_000 +VIP_2_AMOUNT = 500_000 +VIP_3_AMOUNT = 1_000_000 +VIP_4_AMOUNT = 5_000_000 + +VANDAR_API_KEY=<%= @config['vandar']['key'] %> +VANDAR_MOBILE=<%= @config['vandar']['mobile'] %> +VANDAR_PASSWORD=<%= @config['vandar']['password'] %> +VANDAR_BUSINESS_NAME=<%= @config['vandar']['name'] %> diff --git a/templates/config/peatio/abilities.yml.erb b/templates/config/peatio/abilities.yml.erb new file mode 100644 index 0000000..3956473 --- /dev/null +++ b/templates/config/peatio/abilities.yml.erb @@ -0,0 +1,190 @@ +roles: + - superadmin + - admin + - technical + - accountant + - compliance + - support + - member + - broker + - trader + - maker + - sa_maker + +admin_permissions: + superadmin: + manage: + - Operations::Account + - Operations::Asset + - Operations::Expense + - Operations::Liability + - Operations::Revenue + - Member + - Account + - Beneficiary + - PaymentAddress + - Deposit + - Withdraw + - WithdrawLimit + - Blockchain + - Currency + - Engine + - Market + - TradingFee + - Wallet + - Adjustment + - InternalTransfer + - WhitelistedSmartContract + read: + - Trade + - Order + create: + - Deposits::Fiat + update: + - Order + admin: + manage: + - Operations::Account + - Operations::Asset + - Operations::Expense + - Operations::Liability + - Operations::Revenue + - Beneficiary + - Deposit + - Withdraw + - WithdrawLimit + - Engine + - Market + - TradingFee + - Wallet + - Adjustment + - InternalTransfer + - WhitelistedSmartContract + - Currency + - Blockchain + read: + - Trade + - Order + - Account + - PaymentAddress + - Member + create: + - Deposits::Fiat + update: + - Order + - Member + technical: + read: + - Operations::Account + - Operations::Asset + - Operations::Expense + - Operations::Liability + - Trade + - Order + - Member + - InternalTransfer + manage: + - WithdrawLimit + - Blockchain + - Currency + - Engine + - Market + - TradingFee + - Wallet + - WhitelistedSmartContract + update: + - Order + accountant: + read: + - Operations::Account + - Operations::Asset + - Operations::Expense + - Operations::Liability + - Operations::Revenue + - Member + - Account + - Beneficiary + - PaymentAddress + - Deposit + - Withdraw + - WithdrawLimit + - Blockchain + - Currency + - Engine + - Market + - TradingFee + - Wallet + - Trade + - Order + - Adjustment + - InternalTransfer + create: + - Deposits::Fiat + - Adjustment + compliance: + read: + - Operations::Account + - Operations::Asset + - Operations::Expense + - Operations::Liability + - Member + - Account + - Beneficiary + - PaymentAddress + - Deposit + - Withdraw + - Currency + - Engine + - Market + - Trade + - Order + support: + read: + - Operations::Account + - Operations::Asset + - Operations::Expense + - Operations::Liability + - Member + - Account + - Beneficiary + - PaymentAddress + - Deposit + - Withdraw + - Currency + - Engine + - Market + - Trade + - Order + - InternalTransfer + +user_permissions: + superadmin: + manage: all + admin: + manage: all + technical: + manage: all + accountant: + manage: all + compliance: + manage: all + support: + manage: all + member: + manage: all + broker: + manage: all + trader: + manage: all + maker: + manage: all + sa_maker: + read: + - Operations::Account + - Order + - Trade + - StatsMemberPnl + create: + - Order + update: + - Order diff --git a/templates/config/peatio/application.yml.erb b/templates/config/peatio/application.yml.erb new file mode 100644 index 0000000..9f5539f --- /dev/null +++ b/templates/config/peatio/application.yml.erb @@ -0,0 +1,135 @@ +defaults: &defaults + TIMEZONE: 'Tehran' + + # Configure Redis URL, for a TCP connection: + # `redis://:[password]@[hostname]:[port]/[db]` + # (password, port and database are optional). + REDIS_PASSWORD: ~ + REDIS_CLUSTER: false + + # Application URL configuration variables. + URL_HOST: fibitex.com + URL_ROOT_PATH: '/' + URL_SCHEME: https + FORCE_SECURE_CONNECTION: 'true' # Set to "true" to disable access via unsecured HTTP, send HSTS headers and use secure cookies. + + # Configuration variables for logger. + LOG_LEVEL: ~ # Default level for production is warn, otherwise – debug. + + # Configuration variables for API CORS. + # + # Set list of allowed origins using the variable below. + # By default it allows access to API from all origins. + # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin + API_CORS_ORIGINS: '*' + # Access-Control-Allow-Credentials response header is not supported + # if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’. + API_CORS_ALLOW_CREDENTIALS: 'false' + # The Access-Control-Max-Age response header indicates how long + # the results of a preflight request can be cached. + # Default value 3600. + API_CORS_MAX_AGE: ~ + + # Configuration variables for Sentry. + SENTRY_DSN_BACKEND: ~ # Specify Sentry DSN used for Rails application. + + # Customize page metadata like title, description & keywords for landing, cabinet & admin modules. + METADATA_TITLE: Fibitex Exchange + METADATA_DESCRIPTION: Next generation of cryptoasset services for Canadians + METADATA_KEYWORDS: cryptoasset,Canadians,Exchange,Cryptocurrency,Bitcoin,Ethereum + + # Configuration variables for JWT verification. + # Get explanation at https://en.wikipedia.org/wiki/JSON_Web_Token. + # + # JWT_PUBLIC_KEY + # + # JWT provider uses private key for encoding JSON Web Tokens + # while public key is used for decoding by resources. + # + # For example, Barong is JWT provider, Peatio is resource accepting JWT. + # Barong must have private key installed, Peatio must have public key installed. + # + # You can generate keypair by running: + # + # ruby -e "require 'openssl'; require 'base64'; OpenSSL::PKey::RSA.generate(2048).tap { |p| puts '', 'PRIVATE RSA KEY (URL-safe Base64 encoded, PEM):', '', Base64.urlsafe_encode64(p.to_pem), '', 'PUBLIC RSA KEY (URL-safe Base64 encoded, PEM):', '', Base64.urlsafe_encode64(p.public_key.to_pem) }" + # + # Copy the generated private key and put it's value to appropriate variable at JWT provider (for example, at Barong it will be JWT_SHARED_SECRET_KEY). + # Copy the generated public key and put it's value to variable JWT_PUBLIC_KEY (at Peatio). + # + # Peatio and JWT provider should have the same keypair installed, or they would not understand each other. + # + # You may want to adjust key length or cipher. + # + # Development and test environments already don't include sample keys. + # + # You can generate valid JWT by running: + # + # JWT.encode(payload, OpenSSL::PKey.read(Base64.urlsafe_decode64(ENCODED_PRIVATE_KEY)), ENV.fetch('JWT_ALGORITHM')) + # + # Replace ENCODED_PRIVATE_KEY with private key printed by previous command. + # + # You can decode JWT by running: + # + # JWT.decode(token, OpenSSL::PKey.read(Base64.urlsafe_decode64(ENCODED_PUBLIC_KEY)), true, algorithms: [ENV.fetch('JWT_ALGORITHM')]) + # + # To authenticate using JWT send it's value in "Authorization" header: + # + # curl -H "Authorization: Bearer TOKEN" http://localhost:3000/api/v2/account/balances + # + JWT_ISSUER: ~ # JWT issuer name (optional). + JWT_DEFAULT_LEEWAY: ~ # Seconds (optional). + JWT_ISSUED_AT_LEEWAY: '180' # Seconds (optional). + JWT_EXPIRATION_LEEWAY: ~ # Seconds (optional). + JWT_NOT_BEFORE_LEEWAY: ~ # Seconds (optional). + PEATIO_JWT_PRIVATE_KEY: ~ + + # Scout APM configuration variables. + SCOUT_KEY: ~ # Your organization key for Scout APM. Found on the settings screen. + SCOUT_APP_NAME: ~ # Application name in APM Web UI. + SCOUT_LOG_LEVEL: warn # Verboseness of logs (debug, info, warn, error) + SCOUT_ENV: production # List of Rails environments for which Scout should be enabled. + + # Configuration variables for dynamic Barong levels (1.8+). + MINIMUM_MEMBER_LEVEL_FOR_DEPOSIT: '0' + MINIMUM_MEMBER_LEVEL_FOR_WITHDRAW: '1' + MINIMUM_MEMBER_LEVEL_FOR_TRADING: '0' + + # Event API configuration. + + # JWT configuration. + # You can generate keypair using: + # + # ruby -e "require 'openssl'; require 'base64'; OpenSSL::PKey::RSA.generate(2048).tap { |p| puts '', 'PRIVATE RSA KEY (URL-safe Base64 encoded, PEM):', '', Base64.urlsafe_encode64(p.to_pem), '', 'PUBLIC RSA KEY (URL-safe Base64 encoded, PEM):', '', Base64.urlsafe_encode64(p.public_key.to_pem) }" + # + + # RabbitMQ configuration. + # You can use just «EVENT_API_RABBITMQ_URL» or specify configuration per separate variable. + EVENT_API_RABBITMQ_URL: ~ + + RANGER_HOST: '0.0.0.0' + RANGER_PORT: '8081' + RANGER_CONNECT_SECURE: 'true' + + BULLET: 'false' + + # Configuration to allow Withdraw via API i.e (POST api/v2/account/withdraws) + ENABLE_ACCOUNT_WITHDRAWAL_API: 'true' + + # Configure to limit currencies and markets on the platform. + MAX_CURRENCIES: ~ + MAX_MARKETS: ~ + +development: + <<: *defaults + + # Development configuration variables for Event API JWT. + # TODO i think below line must be comment + # EVENT_API_JWT_PRIVATE_KEY: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBb3VLVHh2SFVJVDJENmdXaWJRcS9kbW9BUUwyeWJ6SGFiUXRlc1AyL2o1VjkvUExaCmhHNWtLVkpPWjcxVVdMQ3BjZTQxeHZzQ0lKd0Q5MnVDNW5Lak5wblRDTWpwTUJNMGg0aFF4a2VOeHdNeU41N1gKM1QzbWFCVmZzUTNCblErSm84L0tzdUxhODlvY0dDeDgvYlUyOGNld2FxRk8ydUVMWWJiaUZadGFCenFJd0ZCdQpTM3hGQmt6NE16MGgvWEIxTjl5ZDg5d25OMm1oWVBsU0xrTGVUdFoyeWswK2krZHhZd2V4MEozOXJDS0hnRWRKCko1NTZHNmdtZWpJZ3dtcHNVeHJpdkVJRU5jR09POHdmQVBUVy92SFZmc2ROTExHejRtZE9CWmxsa2orcFFQODYKTnFSUjRKSnFDdEg3dHYyaXVBSGI4NnB5anVlZkVGU3ljMmxZRXdJREFRQUJBb0lCQUJrUlViamVZczB5MEdobApzWmVpZmREVmczQnpRVkRIbFZ3TzBlWGZSMm5ya2RZcDhidmwyVmhhcUdKaXl1WlRXZUNFenBYdTcyYmhXK0xxCkV0MHdhMW50MW9LVm1QMmpGd1I4d0NHanhYZ0pUK01yZVFFOWs0WVZOQUxsb1JSdzNiZnVOTDNQRis5TGMrTnMKaFZmdVdhUmdIUkJyL3R6RW9hSEtLWVUxd1djM0poSitNRklNVkZBT0RvaGp6bXNlV2lzTDNnbzVrUC9KYUpVZwprNm13Wnd0QzRvQ3pPQ3FoRGF0WVI3cktJbXMyS1lCNVBwaTRDTThkRzJGTzBwWGxXUU9XT0t2N01TUjlVeEtzCmd4YWFRRlhjajBQM2lSRFVQMDRkSWtqblNtemZmR0F2L3lBTHovZjk0V1lIK3gvd01DWms4ejJ4bnRJclllM3UKN0NOd045RUNnWUVBMEplcThCaXlKczF6YlBpcTlWWnR5L3R0M1dhaXJDbUl4cXRwU2syVU9UNmh2TldiMTUxVwpBMGRWYWEvSVBhdDV4ZkNWdGhkNlB3UGpJbWVPVXQ4Mlhib2JYeE8zREJUcmVzTlRNWUhiMGVUK09sSG04SU5uCnVwOGFxZWpWejc1ME5VYUxGWWpxWk1wVVR1Z2FVREIzNWZ1bXg0SXliNm5LRGMvSStrN25qUlVDZ1lFQXgrZVAKcE4vR1dqYjJUOU1CUm1xdkVtSGxKOXBZSEZpWGZlWnJHdzg3Q2E5WjVDYVp1VzBrSVAwSlhWSDZOOThqL2RvbApDTHZPdE5oZVFoaGUrTU91VXJMT0ttaytpckM5SEk2cW9aT3Nkc0lCc0pXSHdPanB1UW00OWNvdXc0K2ZKOWRxCjN2cTE2bG5EQlNoRU5HTEFhdVBzWDhLRUlYVzhRRnBDM3ppbXFvY0NnWUI2bTh2VVdRL09reEQzeXFyaWpxejMKSzVFR2hKKzF4cXdvNnZSMndtY1B4dXJXemxCT1NxTVdSa1hFVzVpOTl4OGE1REY3MlF6NElWYlBFRU91SHBvYwpPWnFCSmx0LzlJUDlvdll4c1h6K1FUWFdIZkk3Q1dKZFpjd01kMW5HUk5LVnhpTld3eVhUbk1JMXAyUmdJajAzCnA5WCtpMThPRjZVMnZSNExVM256aVFLQmdBVVZzOGFxMW4zRzloN3pyQTJoZXhDSm91MlBsVHdyV0xjZ0hFdFUKNk5pSE9FOGdXRHFxTndnTHg2Z3pCSjFWTkxJcFVWWFdpUng2Z0hOSDhXcDhkN3VzeHFlM2c1cTlnaUh1MHhKSApFbFQyL0ZvRWc2NTVmakJ4dWQydXBkL2RrRnZRRSt6V0RiaUhUZm1jbTVlRmg0VndoTHV1MC9PUjdoYm85TmgrCnRXYVRBb0dCQUwxVjFUTWZZRFhwYjFwaFBaV2pQL29iV1NqK2VyUXlYdit3TTIxVzRYWFI4YTBkV2hOVXdVeDAKdU9WZ2s1ZlN1OExtNG0zWGNYZ09wV0VJVkZJTzFodDFNN0xxZ0VGNGhFOHl6Y0Vldy9HWXR4VkpCTWEyODVpVQpaVUtkeCt6QWd5VFlnYk50VkVseTVobGRuT2orVmNzanVEL3krWEhXWVl5OVpLa2pNdDhECi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== + # Event API JWT public key value is. + # EVENT_API_JWT_PUBLIC_KEY: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFvdUtUeHZIVUlUMkQ2Z1dpYlFxLwpkbW9BUUwyeWJ6SGFiUXRlc1AyL2o1VjkvUExaaEc1a0tWSk9aNzFVV0xDcGNlNDF4dnNDSUp3RDkydUM1bktqCk5wblRDTWpwTUJNMGg0aFF4a2VOeHdNeU41N1gzVDNtYUJWZnNRM0JuUStKbzgvS3N1TGE4OW9jR0N4OC9iVTIKOGNld2FxRk8ydUVMWWJiaUZadGFCenFJd0ZCdVMzeEZCa3o0TXowaC9YQjFOOXlkODl3bk4ybWhZUGxTTGtMZQpUdFoyeWswK2krZHhZd2V4MEozOXJDS0hnRWRKSjU1Nkc2Z21laklnd21wc1V4cml2RUlFTmNHT084d2ZBUFRXCi92SFZmc2ROTExHejRtZE9CWmxsa2orcFFQODZOcVJSNEpKcUN0SDd0djJpdUFIYjg2cHlqdWVmRUZTeWMybFkKRXdJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg== + +test: + <<: *defaults + +production: + <<: *defaults diff --git a/templates/config/peatio/management_api_v1.yml.erb b/templates/config/peatio/management_api_v1.yml.erb new file mode 100644 index 0000000..1be81ae --- /dev/null +++ b/templates/config/peatio/management_api_v1.yml.erb @@ -0,0 +1,13 @@ +keychain: + applogic: + algorithm: RS256 + value: <%= @applogic_public_key %> + +scopes: + read_operations: + mandatory_signers: + - applogic + permitted_signers: + - applogic + +jwt: {} diff --git a/templates/config/peatio/seed/accounts.yml.erb b/templates/config/peatio/seed/accounts.yml.erb new file mode 100644 index 0000000..152bb5f --- /dev/null +++ b/templates/config/peatio/seed/accounts.yml.erb @@ -0,0 +1,69 @@ +- code: 101 + type: asset + kind: main + currency_type: fiat + description: Main Fiat Assets Account + scope: platform + +- code: 102 + type: asset + kind: main + currency_type: coin + description: Main Crypto Assets Account + scope: platform + +- code: 201 + type: liability + kind: main + currency_type: fiat + description: Main Fiat Liabilities Account + scope: member + +- code: 202 + type: liability + kind: main + currency_type: coin + description: Main Crypto Liabilities Account + scope: member + +- code: 211 + type: liability + kind: locked + currency_type: fiat + description: Locked Fiat Liabilities Account + scope: member + +- code: 212 + type: liability + kind: locked + currency_type: coin + description: Locked Crypto Liabilities Account + scope: member + +- code: 301 + type: revenue + kind: main + currency_type: fiat + description: Main Fiat Revenues Account + scope: platform + +- code: 302 + type: revenue + kind: main + currency_type: coin + description: Main Crypto Revenues Account + scope: platform + +- code: 401 + type: expense + kind: main + currency_type: fiat + description: Main Fiat Expenses Account + scope: platform + +- code: 402 + type: expense + kind: main + currency_type: coin + description: Main Crypto Expenses Account + scope: platform diff --git a/templates/config/peatio/seed/blockchains.yml.erb b/templates/config/peatio/seed/blockchains.yml.erb new file mode 100644 index 0000000..4c662ec --- /dev/null +++ b/templates/config/peatio/seed/blockchains.yml.erb @@ -0,0 +1,96 @@ +<% if @config['parity']['enabled'] %> +- key: eth-<%= @config['parity']['network'] %> + name: Ethereum <%= @config['parity']['network'].capitalize %> + client: parity + server: http://<%= @config['parity']['address'] %>:<%= @config['parity']['rpcport'] %> + height: 8670000 + min_confirmations: 6 + explorer: + address: https://etherscan.io/address/#{address} + transaction: https://etherscan.io/tx/#{txid} + status: active +<% end %> + +<% if @config['bitcoind']['enabled'] %> +- key: btc-<%= @config['bitcoind']['network'] %> + name: Bitcoin <%= @config['bitcoind']['network'].capitalize %> + client: bitcoin + server: http://<%= @config['bitcoind']['rpcuser'] %>:<%= @config['bitcoind']['rpcpassword'] %>@<%= @config['bitcoind']['address'] %>:<%= @config['bitcoind']['rpcport'] %> + height: 597000 + min_confirmations: 6 + explorer: + address: https://blockchain.com/address/#{address} + transaction: https://blockchain.com/tx/#{txid} + status: active +<% end %> + +<% if @config['BetaCandaTestNetwork'] %> + +- key: eth-rinkeby + name: Ethereum Rinkeby + client: geth # API client name. + server: http://127.0.0.1:8545 # Public Ethereum node endpoint. IMPORTANT: full syncmode. + height: 4000000 # Initial block number from which sync will be started. + min_confirmations: 6 # Minimal confirmations needed for withdraw and deposit confirmation. + explorer: + address: https://rinkeby.etherscan.io/address/#{address} + transaction: https://rinkeby.etherscan.io/tx/#{txid} + status: active + +- key: btc-testnet + name: Bitcoin Testnet + client: bitcoin # API client name. + server: http://user:password@127.0.0.1:18332 # Public Bitcoin node endpoint. + height: 1500000 # Initial block number from which sync will be started. + min_confirmations: 2 # Minimal confirmations needed for withdraw and deposit confirmation. + explorer: + address: https://testnet.blockchain.com/address/#{address} + transaction: https://testnet.blockchain.com/tx/#{txid} + status: active + +- key: bsc-testnet + name: BSC Testnet + client: bitcoin # API client name. + server: http://user:password@127.0.0.1:18332 # Public Bitcoin node endpoint. + height: 4000000 # Initial block number from which sync will be started. + min_confirmations: 15 # Minimal confirmations needed for withdraw and deposit confirmation. + explorer: + address: https://testnet.bscscan.com/address/#{address} + transaction: https://testnet.bscscan.com/tx/#{txid} + status: active + +- key: trx-testnet + name: Tron Testnet + client: bitcoin # API client name. + server: http://user:password@127.0.0.1:18332 # Public Bitcoin node endpoint. + height: 4000000 # Initial block number from which sync will be started. + min_confirmations: 15 # Minimal confirmations needed for withdraw and deposit confirmation. + explorer: + address: https://tronscan.org/#/address/#{address} + transaction: https://tronscan.org/#/tx/#{txid} + status: active + +- key: xlm-testnet + name: XLM Testnet + client: bitcoin # API client name. + server: http://user:password@127.0.0.1:18332 # Public Bitcoin node endpoint. + height: 4000000 # Initial block number from which sync will be started. + min_confirmations: 1 # Minimal confirmations needed for withdraw and deposit confirmation. + explorer: + address: https://stellarscan.io/address/#{address} + transaction: https://stellarscan.io/tx/#{txid} + status: active + +- key: xrp-testnet + name: XRP Testnet + client: bitcoin # API client name. + server: http://user:password@127.0.0.1:18332 # Public Bitcoin node endpoint. + height: 4000000 # Initial block number from which sync will be started. + min_confirmations: 1 # Minimal confirmations needed for withdraw and deposit confirmation. + explorer: + address: https://xrpscan.com/account/#{address} + transaction: https://xrpscan.com/tx/#{txid} + status: active + + +<% end %> \ No newline at end of file diff --git a/templates/config/peatio/seed/currencies.yml.erb b/templates/config/peatio/seed/currencies.yml.erb new file mode 100644 index 0000000..a16585d --- /dev/null +++ b/templates/config/peatio/seed/currencies.yml.erb @@ -0,0 +1,411 @@ +- id: irt + name: Iranian Toman + type: fiat + precision: 2 + base_factor: 1 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 10 + min_collection_amount: 10 + withdraw_limit_24h: 1000 + withdraw_limit_72h: 2000 + deposit_fee: 0 + withdraw_fee: 0 + position: 100 + options: {} + +<% if @config['BetaCandaTestNetwork'] %> + +- id: cad + name: Canadian Dollar + type: fiat + precision: 2 + base_factor: 1 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 10 + min_collection_amount: 10 + withdraw_limit_24h: 1000 + withdraw_limit_72h: 2000 + deposit_fee: 0 + withdraw_fee: 0 + position: 1 + options: {} + +- id: usdt + name: Tether + blockchain_key: eth-rinkeby + type: coin + precision: 2 + base_factor: 1 + # IMPORTANT: Don't forget to update this variable according + # to your ERC20-based currency requirements (usually can be found on the official website). + visible: true + deposit_enabled: false + withdrawal_enabled: false + # Deposits with less amount are skipped during blockchain synchronization. + # We advise to set value 10 times bigger than the network fee to prevent losses. + # NOTE: Network fee is paid in ETH but min_deposit_amount is in TRST. + min_deposit_amount: 2 + min_collection_amount: 20 + withdraw_limit_24h: 1000 + withdraw_limit_72h: 3000 + deposit_fee: 0 + withdraw_fee: 4 + position: 2 + options: + # ERC20 tx fees configurations. + # Maximum amount of gas you're willing to spend on a particular transaction. + gas_limit: 90_000 + # Internal price that is paid for running a contract on the Ethereum network. + gas_price: 1_000_000_000 + # + # ERC20 configuration. + erc20_contract_address: '0xdac17f958d2ee523a2206206994597c13d831ec7' # Always wrap this value in quotes! + +- id: btc + name: Bitcoin + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 0.00005 + min_collection_amount: 0.0001 + withdraw_limit_24h: 0.1 + withdraw_limit_72h: 0.2 + deposit_fee: 0 + withdraw_fee: 0.0003 + position: 3 + options: {} + +- id: eth + name: Ethereum + blockchain_key: eth-rinkeby + type: coin + precision: 8 + base_factor: 1_000_000_000_000_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 0.00021 + min_collection_amount: 0.00021 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 0 + position: 4 + options: + gas_limit: 21_000 + gas_price: 1_000_000_000 + +- id: etc + name: Ethereum Classic + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 1_000_000_000_000_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 0.00021 + min_collection_amount: 0.00021 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 0 + position: 5 + options: {} + +- id: shib + name: 1000 Shiba Inu + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 6 + options: {} + +- id: bch + name: Bitcoin Cash + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 7 + options: {} + +- id: ltc + name: Litecoin + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 8 + options: {} + +- id: ada + name: Cardano + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 9 + options: {} + +- id: bnb + name: BNB + blockchain_key: btc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 10 + options: {} + +- id: xlm + name: Stellar Lumens + blockchain_key: xlm-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 11 + options: {} + +- id: xrp + name: Ripple + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 12 + options: {} + +- id: trx + name: Tron + blockchain_key: trx-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 13 + options: {} + +- id: doge + name: Dogecoin + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 14 + options: {} + +- id: uni + name: Uniswap + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 15 + options: {} + +- id: link + name: Chainlink + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 16 + options: {} + +- id: dot + name: Polkadot + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 17 + options: {} + +- id: aave + name: AAVE + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 18 + options: {} + +- id: matic + name: Polygon + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 19 + options: {} + +- id: mkr + name: Maker + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 20 + options: {} + +- id: sol + name: Solana + blockchain_key: bsc-testnet + type: coin + precision: 8 + base_factor: 100_000_000 + visible: true + deposit_enabled: false + withdrawal_enabled: false + min_deposit_amount: 1000 + min_collection_amount: 1000 + withdraw_limit_24h: 0.2 + withdraw_limit_72h: 0.5 + deposit_fee: 0 + withdraw_fee: 400 + position: 21 + options: {} +<% end %> diff --git a/templates/config/peatio/seed/deposit_limit.yml.erb b/templates/config/peatio/seed/deposit_limit.yml.erb new file mode 100644 index 0000000..2079050 --- /dev/null +++ b/templates/config/peatio/seed/deposit_limit.yml.erb @@ -0,0 +1,4 @@ +- id: 1 + kind: 'fiat' + kyc_level: 1 + limit_24_hour: 10000 \ No newline at end of file diff --git a/templates/config/peatio/seed/engines.yml.erb b/templates/config/peatio/seed/engines.yml.erb new file mode 100644 index 0000000..07be245 --- /dev/null +++ b/templates/config/peatio/seed/engines.yml.erb @@ -0,0 +1,20 @@ +- name: peatio-default-engine + driver: peatio + state: online +- name: local-finex-spot-engine + driver: finex-spot + state: online +- name: opendax-finex-spot-engine + driver: opendax + url: https://www.opendax.io/api/v2/finex + key: "" + secret: "" + # The data field for store some special data engine + # Can be used in upstream worker + data: | + { + "rest"=>"https://www.opendax.io/api/v2/finex", + "websocket"=>"wss://www.opendax.io/api/v2/ranger", + "trade_proxy"=>true, + } + state: online diff --git a/templates/config/peatio/seed/markets.yml.erb b/templates/config/peatio/seed/markets.yml.erb new file mode 100644 index 0000000..f4a00b1 --- /dev/null +++ b/templates/config/peatio/seed/markets.yml.erb @@ -0,0 +1,524 @@ +- id: usdtirt + engine_name: peatio-default-engine + base_unit: usdt + quote_unit: irt + amount_precision: 2 + price_precision: 4 + min_price: 1000 + max_price: 100000 + min_amount: 1 + position: 1 + state: disabled + data: {} + +<% if @config['BetaCandaTestNetwork'] %> +# CAD Market------------------------------------------ +- id: usdtcad + engine_name: peatio-default-engine + base_unit: usdt + quote_unit: cad + amount_precision: 2 + price_precision: 2 + min_price: 0.1 + max_price: 100 + min_amount: 1 + position: 1 + state: enabled + data: {} + +- id: btccad + engine_name: peatio-default-engine + base_unit: btc + quote_unit: cad + amount_precision: 6 + price_precision: 2 + min_price: 1000 + max_price: 200000 + min_amount: 0.0001 + position: 2 + state: enabled + data: {} + +- id: ethcad + engine_name: peatio-default-engine + base_unit: eth + quote_unit: cad + amount_precision: 5 + price_precision: 2 + min_price: 100 + max_price: 20000 + min_amount: 0.0001 + position: 3 + state: enabled + data: {} + +- id: etccad + engine_name: peatio-default-engine + base_unit: etc + quote_unit: cad + amount_precision: 2 + price_precision: 4 + min_price: 1 + max_price: 500 + min_amount: 0.01 + position: 4 + state: enabled + data: {} + +- id: shibcad + engine_name: peatio-default-engine + base_unit: shib + quote_unit: cad + amount_precision: 0 + price_precision: 6 + min_price: 0.00001 + max_price: 10 + min_amount: 1 + position: 5 + state: enabled + data: {} + +- id: bchcad + engine_name: peatio-default-engine + base_unit: bch + quote_unit: cad + amount_precision: 5 + price_precision: 2 + min_price: 0.1 + max_price: 5000 + min_amount: 0.001 + position: 6 + state: enabled + data: {} + +- id: ltccad + engine_name: peatio-default-engine + base_unit: ltc + quote_unit: cad + amount_precision: 6 + price_precision: 2 + min_price: 0.1 + max_price: 5000 + min_amount: 0.001 + position: 7 + state: enabled + data: {} + +- id: adacad + engine_name: peatio-default-engine + base_unit: ada + quote_unit: cad + amount_precision: 3 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 8 + state: enabled + data: {} + +- id: bnbcad + engine_name: peatio-default-engine + base_unit: bnb + quote_unit: cad + amount_precision: 4 + price_precision: 3 + min_price: 1 + max_price: 5000 + min_amount: 0.01 + position: 9 + state: enabled + data: {} + +- id: xlmcad + engine_name: peatio-default-engine + base_unit: xlm + quote_unit: cad + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 10 + state: enabled + data: {} + +- id: xrpcad + engine_name: peatio-default-engine + base_unit: xrp + quote_unit: cad + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 11 + state: enabled + data: {} + +- id: trxcad + engine_name: peatio-default-engine + base_unit: trx + quote_unit: cad + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 12 + state: enabled + data: {} + +- id: dogecad + engine_name: peatio-default-engine + base_unit: doge + quote_unit: cad + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 1 + position: 13 + state: enabled + data: {} + +- id: unicad + engine_name: peatio-default-engine + base_unit: uni + quote_unit: cad + amount_precision: 4 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.001 + position: 14 + state: enabled + data: {} + +- id: linkcad + engine_name: peatio-default-engine + base_unit: link + quote_unit: cad + amount_precision: 4 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.001 + position: 15 + state: enabled + data: {} + +- id: dotcad + engine_name: peatio-default-engine + base_unit: dot + quote_unit: cad + amount_precision: 3 + price_precision: 4 + min_price: 0.001 + max_price: 100 + min_amount: 0.1 + position: 16 + state: enabled + data: {} + +- id: aavecad + engine_name: peatio-default-engine + base_unit: aave + quote_unit: cad + amount_precision: 4 + price_precision: 6 + min_price: 0.1 + max_price: 5000 + min_amount: 0.0001 + position: 17 + state: enabled + data: {} + +- id: maticcad + engine_name: peatio-default-engine + base_unit: matic + quote_unit: cad + amount_precision: 3 + price_precision: 4 + min_price: 0.001 + max_price: 100 + min_amount: 1 + position: 18 + state: enabled + data: {} + +- id: mkrcad + engine_name: peatio-default-engine + base_unit: mkr + quote_unit: cad + amount_precision: 4 + price_precision: 4 + min_price: 0.1 + max_price: 5000 + min_amount: 0.0001 + position: 19 + state: enabled + data: {} + +- id: solcad + engine_name: peatio-default-engine + base_unit: sol + quote_unit: cad + amount_precision: 4 + price_precision: 6 + min_price: 0.001 + max_price: 100 + min_amount: 0.001 + position: 20 + state: enabled + data: {} + +# USDT Market------------------------------------------ +- id: btcusdt + engine_name: peatio-default-engine + base_unit: btc + quote_unit: usdt + amount_precision: 6 + price_precision: 4 + min_price: 1000 + max_price: 200000 + min_amount: 0.0001 + position: 21 + state: enabled + data: {} + +- id: ethusdt + engine_name: peatio-default-engine + base_unit: eth + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 100 + max_price: 20000 + min_amount: 0.0001 + position: 22 + state: enabled + data: {} + +- id: etcusdt + engine_name: peatio-default-engine + base_unit: etc + quote_unit: usdt + amount_precision: 4 + price_precision: 4 + min_price: 1 + max_price: 500 + min_amount: 0.001 + position: 23 + state: enabled + data: {} + +- id: shibusdt + engine_name: peatio-default-engine + base_unit: shib + quote_unit: usdt + amount_precision: 0 + price_precision: 6 + min_price: 0.000001 + max_price: 10 + min_amount: 1 + position: 24 + state: enabled + data: {} + +- id: bchusdt + engine_name: peatio-default-engine + base_unit: bch + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 0.1 + max_price: 5000 + min_amount: 0.001 + position: 25 + state: enabled + data: {} + +- id: ltcusdt + engine_name: peatio-default-engine + base_unit: ltc + quote_unit: usdt + amount_precision: 6 + price_precision: 4 + min_price: 0.1 + max_price: 5000 + min_amount: 0.0001 + position: 26 + state: enabled + data: {} + +- id: adausdt + engine_name: peatio-default-engine + base_unit: ada + quote_unit: usdt + amount_precision: 3 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 27 + state: enabled + data: {} + +- id: bnbusdt + engine_name: peatio-default-engine + base_unit: bnb + quote_unit: usdt + amount_precision: 4 + price_precision: 3 + min_price: 1 + max_price: 5000 + min_amount: 0.01 + position: 28 + state: enabled + data: {} + +- id: xlmusdt + engine_name: peatio-default-engine + base_unit: xlm + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 29 + state: enabled + data: {} + +- id: xrpusdt + engine_name: peatio-default-engine + base_unit: xrp + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 30 + state: enabled + data: {} + +- id: trxusdt + engine_name: peatio-default-engine + base_unit: trx + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.1 + position: 31 + state: enabled + data: {} + +- id: dogeusdt + engine_name: peatio-default-engine + base_unit: doge + quote_unit: usdt + amount_precision: 5 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 1 + position: 32 + state: enabled + data: {} + +- id: uniusdt + engine_name: peatio-default-engine + base_unit: uni + quote_unit: usdt + amount_precision: 4 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.001 + position: 33 + state: enabled + data: {} + +- id: linkusdt + engine_name: peatio-default-engine + base_unit: link + quote_unit: usdt + amount_precision: 4 + price_precision: 4 + min_price: 0.0001 + max_price: 100 + min_amount: 0.001 + position: 34 + state: enabled + data: {} + +- id: dotusdt + engine_name: peatio-default-engine + base_unit: dot + quote_unit: usdt + amount_precision: 3 + price_precision: 4 + min_price: 0.001 + max_price: 100 + min_amount: 0.1 + position: 35 + state: enabled + data: {} + +- id: aaveusdt + engine_name: peatio-default-engine + base_unit: aave + quote_unit: usdt + amount_precision: 4 + price_precision: 6 + min_price: 0.1 + max_price: 5000 + min_amount: 0.0001 + position: 36 + state: enabled + data: {} + +- id: maticusdt + engine_name: peatio-default-engine + base_unit: matic + quote_unit: usdt + amount_precision: 3 + price_precision: 4 + min_price: 0.001 + max_price: 100 + min_amount: 1 + position: 37 + state: enabled + data: {} + +- id: mkrusdt + engine_name: peatio-default-engine + base_unit: mkr + quote_unit: usdt + amount_precision: 4 + price_precision: 4 + min_price: 0.1 + max_price: 5000 + min_amount: 0.001 + position: 38 + state: enabled + data: {} + +- id: solusdt + engine_name: peatio-default-engine + base_unit: sol + quote_unit: usdt + amount_precision: 4 + price_precision: 6 + min_price: 0.0001 + max_price: 100 + min_amount: 0.001 + position: 39 + state: enabled + data: {} + +<% end %> diff --git a/templates/config/peatio/seed/members.yml.erb b/templates/config/peatio/seed/members.yml.erb new file mode 100644 index 0000000..087ad52 --- /dev/null +++ b/templates/config/peatio/seed/members.yml.erb @@ -0,0 +1,28 @@ +- id: 1 + uid: '1' + email: 'test1@test.com' + level: 2 + role: 'admin' + group: 'vip-3' + state: 'active' + +- id: 2 + uid: '2' + email: 'test2@test.com' + level: 2 + role: 'admin' + group: 'vip-3' + state: 'active' + + + +- id: 3 + uid: '3' + email: 'test3@test.com' + level: 2 + role: 'admin' + group: 'vip-3' + state: 'active' + + + diff --git a/templates/config/peatio/seed/trading_fees.yml.erb b/templates/config/peatio/seed/trading_fees.yml.erb new file mode 100644 index 0000000..a2d01b5 --- /dev/null +++ b/templates/config/peatio/seed/trading_fees.yml.erb @@ -0,0 +1,29 @@ +- market_id: any + group: any + maker: 0.002 + taker: 0.002 + +- market_id: any + group: vip-0 + maker: 0.0030 + taker: 0.0035 + +- market_id: any + group: vip-1 + maker: 0.0025 + taker: 0.0030 + +- market_id: any + group: vip-2 + maker: 0.0020 + taker: 0.0025 + +- market_id: any + group: vip-3 + maker: 0.0015 + taker: 0.0020 + +- market_id: any + group: vip-4 + maker: 0.001 + taker: 0.0015 diff --git a/templates/config/peatio/seed/wallets.yml.erb b/templates/config/peatio/seed/wallets.yml.erb new file mode 100644 index 0000000..3132328 --- /dev/null +++ b/templates/config/peatio/seed/wallets.yml.erb @@ -0,0 +1,30 @@ +<% if @config['parity']['enabled'] %> +<% @config['wallets']['eth'].each do |wallet| -%> +- name: Ethereum <%= wallet['kind'].capitalize %> Wallet + blockchain_key: eth-<%= @config['parity']['network'] %> + currency_ids: eth,trst + address: '<%= wallet['address'] %>' + kind: <%= wallet['kind'] %> + max_balance: <%= wallet['max_balance'] %> + status: active + gateway: parity + settings: + uri: http://<%= @config['parity']['address'] %>:<%= @config['parity']['rpcport'] %> + secret: '<%= wallet['secret'] %>' +<% end %> +<% end %> + +<% if @config['bitcoind']['enabled'] %> +<% @config['wallets']['btc'].each do |wallet| -%> +- name: Bitcoin <%= wallet['kind'].capitalize %> Wallet + blockchain_key: btc-<%= @config['bitcoind']['network'] %> + currency_ids: btc + address: '<%= wallet['address'] %>' + kind: <%= wallet['kind'] %> + max_balance: <%= wallet['max_balance'] %> + status: active + gateway: bitcoind + settings: + uri: http://<%= @config['bitcoind']['rpcuser'] %>:<%= @config['bitcoind']['rpcpassword'] %>@<%= @config['bitcoind']['address'] %>:<%= @config['bitcoind']['rpcport'] %> +<% end %> +<% end %> diff --git a/templates/config/peatio/seed/withdraw_limits.yml.erb b/templates/config/peatio/seed/withdraw_limits.yml.erb new file mode 100644 index 0000000..cb7b3c0 --- /dev/null +++ b/templates/config/peatio/seed/withdraw_limits.yml.erb @@ -0,0 +1,9 @@ +<% if ENV['WITHDRAW_LIMITS_CONFIG'] %> +<%= File.read(ENV['WITHDRAW_LIMITS_CONFIG']) %> +<% else %> +- kyc_level: any + group: any + # limits in USD + limit_24_hour: 100 + limit_1_month: 1000 +<% end %> diff --git a/templates/config/rango.env.erb b/templates/config/rango.env.erb new file mode 100644 index 0000000..8277e85 --- /dev/null +++ b/templates/config/rango.env.erb @@ -0,0 +1,9 @@ +RANGER_HOST=0.0.0.0 +RANGER_PORT=8080 +RANGER_CONNECT_SECURE="true" + +LOG_LEVEL=warn + +RABBITMQ_HOST=rabbitmq + +JWT_PUBLIC_KEY=<%= @barong_public_key %> diff --git a/templates/config/toolbox.yaml.erb b/templates/config/toolbox.yaml.erb new file mode 100644 index 0000000..1b50102 --- /dev/null +++ b/templates/config/toolbox.yaml.erb @@ -0,0 +1,13 @@ +# For other configuration options, see https://github.com/rubykube/toolbox/blob/master/bin/stress_trading + +root-url: http://www.wb.local + +currencies: usd,eur +markets: eurusd + +orders: 100 +traders: 10 +threads: 5 +management-api-v1-jwt-signer: toolbox +api-v2-jwt-key: "<%= @barong_private_key %>" +management-api-v1-jwt-key: "<%= @toolbox_jwt_private_key %>" diff --git a/templates/config/vault/barong.hcl.erb b/templates/config/vault/barong.hcl.erb new file mode 100644 index 0000000..a889271 --- /dev/null +++ b/templates/config/vault/barong.hcl.erb @@ -0,0 +1,32 @@ +# Access system health status +path "sys/health" { + capabilities = ["read", "list"] +} +# Manage the transit secrets engine +path "transit/keys/<%= @config['app']['name'].downcase %>_*" { + capabilities = ["create", "read", "list"] +} +# Encrypt API keys +path "transit/encrypt/<%= @config['app']['name'].downcase %>_apikeys_*" { + capabilities = ["create", "read", "update"] +} +# Decrypt API keys +path "transit/decrypt/<%= @config['app']['name'].downcase %>_apikeys_*" { + capabilities = ["create", "read", "update"] +} +# Renew tokens +path "auth/token/renew" { + capabilities = ["update"] +} +# Lookup tokens +path "auth/token/lookup" { + capabilities = ["update"] +} +# Manage otp keys +path "totp/keys/*" { + capabilities = ["create", "read", "update", "delete"] +} +# Verify an otp code +path "totp/code/*" { + capabilities = ["read","update"] +} diff --git a/templates/config/vault/finex_engine.hcl.erb b/templates/config/vault/finex_engine.hcl.erb new file mode 100644 index 0000000..9552e3a --- /dev/null +++ b/templates/config/vault/finex_engine.hcl.erb @@ -0,0 +1,23 @@ +path "transit/<%= @config['app']['name'].downcase %>_*" { + capabilities = [ "read" ] +} +# Decrypt secrets +path "transit/decrypt/<%= @config['app']['name'].downcase %>_*" { + capabilities = [ "create", "update" ] +} +# Use key for signing +path "transit/sign/<%= @config['app']['name'].downcase %>_*" { + capabilities = ["update"] +} +# Create transit key +path "transit/keys/<%= @config['app']['name'].downcase %>_*" { + capabilities = ["create"] +} +# Renew tokens +path "auth/token/renew" { + capabilities = ["update"] +} +# Lookup tokens +path "auth/token/lookup" { + capabilities = ["update"] +} diff --git a/templates/config/vault/peatio_crypto.hcl.erb b/templates/config/vault/peatio_crypto.hcl.erb new file mode 100644 index 0000000..0dcc1fd --- /dev/null +++ b/templates/config/vault/peatio_crypto.hcl.erb @@ -0,0 +1,24 @@ +# Manage the transit secrets engine +path "transit/keys/<%= @config['app']['name'].downcase %>_*" { + capabilities = ["create", "read", "list"] +} +# Encrypt Payment Addresses secrets +path "transit/encrypt/<%= @config['app']['name'].downcase %>_payment_addresses_*" { + capabilities = ["create", "read", "update"] +} +# Decrypt Payment Addresses secrets +path "transit/decrypt/<%= @config['app']['name'].downcase %>_payment_addresses_*" { + capabilities = ["create", "read", "update"] +} +# Decrypt wallets secrets +path "transit/decrypt/<%= @config['app']['name'].downcase %>_wallets_*" { + capabilities = ["create", "read", "update"] +} +# Renew tokens +path "auth/token/renew" { + capabilities = ["update"] +} +# Lookup tokens +path "auth/token/lookup" { + capabilities = ["update"] +} diff --git a/templates/config/vault/peatio_matching.hcl.erb b/templates/config/vault/peatio_matching.hcl.erb new file mode 100644 index 0000000..9552e3a --- /dev/null +++ b/templates/config/vault/peatio_matching.hcl.erb @@ -0,0 +1,23 @@ +path "transit/<%= @config['app']['name'].downcase %>_*" { + capabilities = [ "read" ] +} +# Decrypt secrets +path "transit/decrypt/<%= @config['app']['name'].downcase %>_*" { + capabilities = [ "create", "update" ] +} +# Use key for signing +path "transit/sign/<%= @config['app']['name'].downcase %>_*" { + capabilities = ["update"] +} +# Create transit key +path "transit/keys/<%= @config['app']['name'].downcase %>_*" { + capabilities = ["create"] +} +# Renew tokens +path "auth/token/renew" { + capabilities = ["update"] +} +# Lookup tokens +path "auth/token/lookup" { + capabilities = ["update"] +} diff --git a/templates/config/vault/peatio_rails.hcl.erb b/templates/config/vault/peatio_rails.hcl.erb new file mode 100644 index 0000000..e85420d --- /dev/null +++ b/templates/config/vault/peatio_rails.hcl.erb @@ -0,0 +1,44 @@ +# Manage the transit secrets engine +path "transit/keys/<%= @config['app']['name'].downcase %>_*" { + capabilities = ["create", "read", "list"] +} +# Encrypt engines secrets +path "transit/encrypt/<%= @config['app']['name'].downcase %>_engines_*" { + capabilities = ["create", "read", "update"] +} +# Encrypt wallets secrets +path "transit/encrypt/<%= @config['app']['name'].downcase %>_wallets_*" { + capabilities = ["create", "read", "update"] +} +# Decrypt wallets secrets +path "transit/decrypt/<%= @config['app']['name'].downcase %>_wallets_*" { +capabilities = ["create", "read", "update"] +} +# Encrypt beneficiaries data +path "transit/encrypt/<%= @config['app']['name'].downcase %>_beneficiaries_*" { + capabilities = [ "create", "read", "update" ] +} +# Decrypt beneficiaries data +path "transit/decrypt/<%= @config['app']['name'].downcase %>_beneficiaries_*" { + capabilities = [ "create", "read", "update" ] +} +# Decrypt Payment Addresses secrets +path "transit/decrypt/<%= @config['app']['name'].downcase %>_payment_addresses_*" { +capabilities = ["create", "read", "update"] +} +# Renew tokens +path "auth/token/renew" { + capabilities = ["update"] +} +# Lookup tokens +path "auth/token/lookup" { + capabilities = ["update"] +} +# Manage otp keys +path "totp/keys/*" { +capabilities = ["create", "read", "update", "delete"] +} +# Verify an otp code +path "totp/code/*" { +capabilities = ["read","update"] +} diff --git a/templates/config/vault/peatio_upstream.hcl.erb b/templates/config/vault/peatio_upstream.hcl.erb new file mode 100644 index 0000000..d6d9de8 --- /dev/null +++ b/templates/config/vault/peatio_upstream.hcl.erb @@ -0,0 +1,16 @@ +# Manage the transit secrets engine +path "transit/keys/<%= @config['app']['name'].downcase %>_*" { + capabilities = ["create", "read", "list"] +} +# Decrypt Engines secrets +path "transit/decrypt/<%= @config['app']['name'].downcase %>_engines_*" { + capabilities = ["create", "read", "update"] +} +# Renew tokens +path "auth/token/renew" { + capabilities = ["update"] +} +# Lookup tokens +path "auth/token/lookup" { + capabilities = ["update"] +} diff --git a/templates/terraform/terraform.tfvars.erb b/templates/terraform/terraform.tfvars.erb new file mode 100644 index 0000000..3eee9b8 --- /dev/null +++ b/templates/terraform/terraform.tfvars.erb @@ -0,0 +1,10 @@ +credentials = "<%= @config['terraform']['credentials'] %>" +project = "<%= @config['terraform']['project'] %>" +region = "<%= @config['terraform']['region'] %>" +zone = "<%= @config['terraform']['zone'] %>" +ssh_user = "deploy" +ssh_public_key = "../config/secrets/app.key.pub" +ssh_private_key = "../config/secrets/app.key" +instance_name = "<%= @config['terraform']['instance_name'] %>" +machine_type = "<%= @config['terraform']['machine_type'] %>" +image = "<%= @config['terraform']['image'] %>" diff --git a/templates/webhook.service b/templates/webhook.service new file mode 100644 index 0000000..b50a4fb --- /dev/null +++ b/templates/webhook.service @@ -0,0 +1,13 @@ +[Unit] +Description=OpenDax Webhook service + +[Service] +User=deploy +Environment="WEBHOOK_JWT_SECRET=GENERATED_HMAC_SECRET" +ExecStart=/bin/bash -c "source ~/.rvm/scripts/rvm; bundle exec rackup config.ru" +Type=simple +Restart=always +WorkingDirectory=OPENDAX_DIRECTORY + +[Install] +WantedBy=multi-user.target diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000..58dc53b --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,120 @@ +provider "google" { + credentials = file(var.credentials) + project = var.project + region = var.region +} + +provider "random" { +} + +resource "random_id" "opendax" { + byte_length = 2 +} + +resource "google_compute_instance" "opendax" { + name = "${var.instance_name}-${random_id.opendax.hex}" + machine_type = var.machine_type + zone = var.zone + + allow_stopping_for_update = true + + boot_disk { + initialize_params { + image = var.image + type = "pd-ssd" + size = 120 + } + } + + network_interface { + network = google_compute_network.opendax.name + + access_config { + nat_ip = google_compute_address.opendax.address + } + } + + service_account { + scopes = ["storage-ro"] + } + + tags = ["allow-webhook"] + + metadata = { + sshKeys = "${var.ssh_user}:${file(var.ssh_public_key)}" + } + + provisioner "local-exec" { + command = "mkdir -p /tmp/upload && rsync -rv --exclude=terraform ../ /tmp/upload/" + } + + provisioner "remote-exec" { + inline = [ + "mkdir -p /home/${var.ssh_user}/opendax", + ] + + connection { + host = self.network_interface[0].access_config[0].nat_ip + type = "ssh" + user = var.ssh_user + private_key = file(var.ssh_private_key) + } + } + + provisioner "file" { + source = "/tmp/upload/" + destination = "/home/${var.ssh_user}/opendax" + + connection { + host = self.network_interface[0].access_config[0].nat_ip + type = "ssh" + user = var.ssh_user + private_key = file(var.ssh_private_key) + } + } + + provisioner "remote-exec" { + script = "../bin/install.sh" + + connection { + host = self.network_interface[0].access_config[0].nat_ip + type = "ssh" + user = var.ssh_user + private_key = file(var.ssh_private_key) + } + } + + provisioner "remote-exec" { + script = "../bin/start.sh" + + connection { + host = self.network_interface[0].access_config[0].nat_ip + type = "ssh" + user = var.ssh_user + private_key = file(var.ssh_private_key) + } + } +} + +resource "google_compute_firewall" "opendax" { + name = "opendax-firewall-${random_id.opendax.hex}" + network = google_compute_network.opendax.name + + allow { + protocol = "tcp" + ports = ["80", "8080", "1337", "443", "22"] + } + + source_ranges = ["0.0.0.0/0"] + + target_tags = ["allow-webhook"] +} + +resource "google_compute_address" "opendax" { + name = "opendax-ip-${random_id.opendax.hex}" +} + +resource "google_compute_network" "opendax" { + name = "opendax-network-${random_id.opendax.hex}" +} + diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000..3b7740a --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,44 @@ +variable "credentials" { + type = string +} + +variable "ssh_user" { + type = string + description = "Name of the SSH user to use" + default = "app" +} + +variable "ssh_public_key" { + type = string + description = "Location of the public RSA key used for SSH-ing onto the main VM" +} + +variable "ssh_private_key" { + type = string + description = "Location of the private RSA key used for SSH-ing onto the main VM" +} + +variable "project" { + type = string +} + +variable "region" { + type = string +} + +variable "zone" { + type = string +} + +variable "machine_type" { + type = string +} + +variable "instance_name" { + type = string +} + +variable "image" { + type = string +} +