From d59bf30ef00ff0bdc21aa6e2cef944b4ae32a00f Mon Sep 17 00:00:00 2001 From: Yaser Date: Thu, 13 Aug 2026 19:42:08 +0330 Subject: [PATCH] Initial commit --- .dockerignore | 6 + .drone.yml | 31 + .env.example | 9 + .gitignore | 28 + .idea/.gitignore | 10 + .idea/alvandp.iml | 134 ++++ .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .rspec | 1 + .ruby-version | 1 + Dockerfile | 17 + Gemfile | 19 + Gemfile.lock | 59 ++ LICENSE | 201 +++++ README.md | 83 ++ Rakefile | 15 + VERSION | 1 + bin/check_member_balance.rb | 18 + bin/check_order.rb | 4 + bin/check_test_balances.rb | 20 + bin/create_admin_user.rb | 23 + bin/install.sh | 56 ++ bin/install_webhook | 10 + bin/quick-test.sh | 7 + bin/seed_test_balances.rb | 110 +++ bin/seed_test_users.rb | 99 +++ bin/set-env.sh | 3 + bin/start.sh | 31 + bin/sync_peatio_seed.rb | 45 ++ bin/test_limit_order.rb | 33 + compose/.gitkeep | 0 config.ru | 5 + config/app.local.yml.example | 48 ++ config/app.production.yml.example | 57 ++ config/app.staging.cutover.yml.example | 15 + config/app.staging.yml.example | 83 ++ config/app.yml | 147 ++++ config/applogic/.gitkeep | 0 config/arke/.gitkeep | 0 config/barong/authz_rules.yml | 18 + config/barong/barong.yml | 52 ++ config/barong/seeds.yml | 382 +++++++++ config/frontend/.gitkeep | 0 config/gateway/.gitkeep | 0 config/influxdb/arke.sql | 79 ++ config/influxdb/build_candles.sql | 11 + config/influxdb/peatio.sql | 66 ++ .../templates/deposit_accepted.en.html.erb | 55 ++ .../templates/email_confirmation.en.html.erb | 73 ++ .../templates/email_confirmation.ru.html.erb | 73 ++ .../email_confirmation_code.en.html.erb | 97 +++ ..._otp_disable_confirmation_code.en.html.erb | 73 ++ ...l_otp_enable_confirmation_code.en.html.erb | 73 ++ config/mailer/templates/label.en.html.erb | 76 ++ .../templates/new_beneficiary.en.html.erb | 55 ++ .../otp_confirmation_code.en.html.erb | 73 ++ .../password_confirmation_code.en.html.erb | 73 ++ .../templates/password_reset.en.html.erb | 97 +++ .../templates/password_reset.ru.html.erb | 73 ++ .../templates/session_create.en.html.erb | 61 ++ .../templates/session_failed.en.html.erb | 61 ++ .../withdraw_confirmation_code.en.html.erb | 73 ++ .../templates/withdraw_succeed.en.html.erb | 55 ++ config/monitoring/alertmanager/.gitkeep | 0 config/monitoring/loki/.gitkeep | 0 config/monitoring/prometheus/.gitkeep | 0 config/monitoring/promtail/.gitkeep | 0 config/mysql/innodb.cnf | 8 + config/peatio/plugins.yml | 22 + config/peatio/seed/.gitkeep | 0 config/peatio/seed/currencies.yml | 411 ++++++++++ config/peatio/seed/markets.yml | 752 ++++++++++++++++++ config/secrets/.gitkeep | 0 config/test_users.yml | 43 + config/utils.yml | 178 +++++ data/mysql/barong_production.sql | 328 ++++++++ data/mysql/peatio_production.sql | 674 ++++++++++++++++ data/parity/.gitkeep | 0 docs/QA-troubleshooting.md | 94 +++ docs/aws-install.md | 83 ++ docs/images/OpenDAX-authorization.png | Bin 0 -> 20517 bytes docs/troubleshoot-barong-authz.md | 148 ++++ docs/ubuntu-install.md | 91 +++ lib/opendax/config_loader.rb | 71 ++ lib/opendax/payload.rb | 46 ++ lib/opendax/renderer.rb | 79 ++ lib/opendax/vault.rb | 81 ++ lib/opendax/webhook.rb | 74 ++ lib/tasks/audit.rake | 22 + lib/tasks/config.rake | 47 ++ lib/tasks/db.rake | 32 + lib/tasks/docker.rake | 11 + lib/tasks/payload.rake | 18 + lib/tasks/render.rake | 17 + lib/tasks/service.rake | 347 ++++++++ lib/tasks/terraform.rake | 16 + lib/tasks/test_seed.rake | 15 + lib/tasks/toolbox.rake | 12 + lib/tasks/vault.rake | 25 + lib/tasks/vendor.rake | 11 + lib/tasks/versions.rake | 33 + lib/tasks/wallets.rake | 20 + scripts/bootstrap-app-staging.rb | 71 ++ scripts/check-email-dns.sh | 36 + scripts/validate-app-overlay.rb | 25 + spec/opendax/payload_spec.rb | 49 ++ spec/opendax/renderer_spec.rb | 95 +++ spec/opendax/server_spec.rb | 0 spec/spec_helper.rb | 100 +++ templates/.env.erb | 6 + templates/compose/app.yaml.erb | 77 ++ templates/compose/arke.yaml.erb | 18 + templates/compose/backend.yaml.erb | 79 ++ templates/compose/cryptonodes.yaml.erb | 49 ++ templates/compose/daemons.yaml.erb | 141 ++++ templates/compose/frontend.yaml.erb | 131 +++ templates/compose/gateway.yaml.erb | 45 ++ templates/compose/monitoring.yaml.erb | 186 +++++ templates/compose/proxy.yaml.erb | 81 ++ templates/compose/superset.yaml.erb | 29 + templates/compose/vendor.yaml.erb | 34 + templates/config/applogic.env.erb | 29 + .../config/applogic/management_api_v2.yml.erb | 25 + templates/config/applogic/schedule.yml.erb | 6 + templates/config/arke.env.erb | 13 + templates/config/arke/strategies.yml.erb | 1 + templates/config/barong.env.erb | 107 +++ templates/config/barong/abilities.yml.erb | 70 ++ .../config/barong/management_api.yml.erb | 11 + templates/config/barong/seeds.yml.erb | 426 ++++++++++ templates/config/bitcoin.conf.erb | 18 + templates/config/finex/config.yaml.erb | 96 +++ templates/config/finex/rsa-key.pub.erb | 1 + templates/config/frontend/env.js.erb | 37 + templates/config/frontend/shahoo.env.js.erb | 24 + templates/config/frontend/tower.js.erb | 73 ++ templates/config/gateway/envoy.yaml.erb | 174 ++++ templates/config/litecoin.conf.erb | 20 + templates/config/mailer.yml.erb | 174 ++++ .../monitoring/alertmanager/config.yml.erb | 20 + .../monitoring/loki/local-config.yaml.erb | 37 + .../prometheus/alert/Alertmanager.rules | 12 + .../prometheus/alert/Prometheus.rules | 12 + .../monitoring/prometheus/prometheus.yml.erb | 41 + .../promtail/docker-config.yaml.erb | 19 + templates/config/mysql/innodb.cnf.erb | 6 + templates/config/peatio.env.erb | 64 ++ templates/config/peatio/abilities.yml.erb | 190 +++++ templates/config/peatio/application.yml.erb | 135 ++++ .../config/peatio/management_api_v1.yml.erb | 13 + templates/config/peatio/seed/accounts.yml.erb | 69 ++ .../config/peatio/seed/blockchains.yml.erb | 96 +++ .../config/peatio/seed/currencies.yml.erb | 411 ++++++++++ .../config/peatio/seed/deposit_limit.yml.erb | 4 + templates/config/peatio/seed/engines.yml.erb | 20 + templates/config/peatio/seed/markets.yml.erb | 524 ++++++++++++ templates/config/peatio/seed/members.yml.erb | 28 + .../config/peatio/seed/trading_fees.yml.erb | 29 + templates/config/peatio/seed/wallets.yml.erb | 30 + .../peatio/seed/withdraw_limits.yml.erb | 9 + templates/config/rango.env.erb | 9 + templates/config/toolbox.yaml.erb | 13 + templates/config/vault/barong.hcl.erb | 32 + templates/config/vault/finex_engine.hcl.erb | 23 + templates/config/vault/peatio_crypto.hcl.erb | 24 + .../config/vault/peatio_matching.hcl.erb | 23 + templates/config/vault/peatio_rails.hcl.erb | 44 + .../config/vault/peatio_upstream.hcl.erb | 16 + templates/terraform/terraform.tfvars.erb | 10 + templates/webhook.service | 13 + terraform/main.tf | 120 +++ terraform/variables.tf | 44 + 173 files changed, 11702 insertions(+) create mode 100644 .dockerignore create mode 100644 .drone.yml create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/alvandp.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .rspec create mode 100644 .ruby-version create mode 100644 Dockerfile create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 LICENSE create mode 100644 README.md create mode 100644 Rakefile create mode 100644 VERSION create mode 100644 bin/check_member_balance.rb create mode 100644 bin/check_order.rb create mode 100644 bin/check_test_balances.rb create mode 100644 bin/create_admin_user.rb create mode 100644 bin/install.sh create mode 100644 bin/install_webhook create mode 100644 bin/quick-test.sh create mode 100644 bin/seed_test_balances.rb create mode 100644 bin/seed_test_users.rb create mode 100644 bin/set-env.sh create mode 100644 bin/start.sh create mode 100644 bin/sync_peatio_seed.rb create mode 100644 bin/test_limit_order.rb create mode 100644 compose/.gitkeep create mode 100644 config.ru create mode 100644 config/app.local.yml.example create mode 100644 config/app.production.yml.example create mode 100644 config/app.staging.cutover.yml.example create mode 100644 config/app.staging.yml.example create mode 100644 config/app.yml create mode 100644 config/applogic/.gitkeep create mode 100644 config/arke/.gitkeep create mode 100644 config/barong/authz_rules.yml create mode 100644 config/barong/barong.yml create mode 100644 config/barong/seeds.yml create mode 100644 config/frontend/.gitkeep create mode 100644 config/gateway/.gitkeep create mode 100644 config/influxdb/arke.sql create mode 100644 config/influxdb/build_candles.sql create mode 100644 config/influxdb/peatio.sql create mode 100644 config/mailer/templates/deposit_accepted.en.html.erb create mode 100644 config/mailer/templates/email_confirmation.en.html.erb create mode 100644 config/mailer/templates/email_confirmation.ru.html.erb create mode 100644 config/mailer/templates/email_confirmation_code.en.html.erb create mode 100644 config/mailer/templates/email_otp_disable_confirmation_code.en.html.erb create mode 100644 config/mailer/templates/email_otp_enable_confirmation_code.en.html.erb create mode 100644 config/mailer/templates/label.en.html.erb create mode 100644 config/mailer/templates/new_beneficiary.en.html.erb create mode 100644 config/mailer/templates/otp_confirmation_code.en.html.erb create mode 100644 config/mailer/templates/password_confirmation_code.en.html.erb create mode 100644 config/mailer/templates/password_reset.en.html.erb create mode 100644 config/mailer/templates/password_reset.ru.html.erb create mode 100644 config/mailer/templates/session_create.en.html.erb create mode 100644 config/mailer/templates/session_failed.en.html.erb create mode 100644 config/mailer/templates/withdraw_confirmation_code.en.html.erb create mode 100644 config/mailer/templates/withdraw_succeed.en.html.erb create mode 100644 config/monitoring/alertmanager/.gitkeep create mode 100644 config/monitoring/loki/.gitkeep create mode 100644 config/monitoring/prometheus/.gitkeep create mode 100644 config/monitoring/promtail/.gitkeep create mode 100644 config/mysql/innodb.cnf create mode 100644 config/peatio/plugins.yml create mode 100644 config/peatio/seed/.gitkeep create mode 100644 config/peatio/seed/currencies.yml create mode 100644 config/peatio/seed/markets.yml create mode 100644 config/secrets/.gitkeep create mode 100644 config/test_users.yml create mode 100644 config/utils.yml create mode 100644 data/mysql/barong_production.sql create mode 100644 data/mysql/peatio_production.sql create mode 100644 data/parity/.gitkeep create mode 100644 docs/QA-troubleshooting.md create mode 100644 docs/aws-install.md create mode 100644 docs/images/OpenDAX-authorization.png create mode 100644 docs/troubleshoot-barong-authz.md create mode 100644 docs/ubuntu-install.md create mode 100644 lib/opendax/config_loader.rb create mode 100644 lib/opendax/payload.rb create mode 100644 lib/opendax/renderer.rb create mode 100644 lib/opendax/vault.rb create mode 100644 lib/opendax/webhook.rb create mode 100644 lib/tasks/audit.rake create mode 100644 lib/tasks/config.rake create mode 100644 lib/tasks/db.rake create mode 100644 lib/tasks/docker.rake create mode 100644 lib/tasks/payload.rake create mode 100644 lib/tasks/render.rake create mode 100644 lib/tasks/service.rake create mode 100644 lib/tasks/terraform.rake create mode 100644 lib/tasks/test_seed.rake create mode 100644 lib/tasks/toolbox.rake create mode 100644 lib/tasks/vault.rake create mode 100644 lib/tasks/vendor.rake create mode 100644 lib/tasks/versions.rake create mode 100644 lib/tasks/wallets.rake create mode 100644 scripts/bootstrap-app-staging.rb create mode 100644 scripts/check-email-dns.sh create mode 100644 scripts/validate-app-overlay.rb create mode 100644 spec/opendax/payload_spec.rb create mode 100644 spec/opendax/renderer_spec.rb create mode 100644 spec/opendax/server_spec.rb create mode 100644 spec/spec_helper.rb create mode 100644 templates/.env.erb create mode 100644 templates/compose/app.yaml.erb create mode 100644 templates/compose/arke.yaml.erb create mode 100644 templates/compose/backend.yaml.erb create mode 100644 templates/compose/cryptonodes.yaml.erb create mode 100644 templates/compose/daemons.yaml.erb create mode 100644 templates/compose/frontend.yaml.erb create mode 100644 templates/compose/gateway.yaml.erb create mode 100644 templates/compose/monitoring.yaml.erb create mode 100644 templates/compose/proxy.yaml.erb create mode 100644 templates/compose/superset.yaml.erb create mode 100644 templates/compose/vendor.yaml.erb create mode 100644 templates/config/applogic.env.erb create mode 100644 templates/config/applogic/management_api_v2.yml.erb create mode 100644 templates/config/applogic/schedule.yml.erb create mode 100644 templates/config/arke.env.erb create mode 100644 templates/config/arke/strategies.yml.erb create mode 100644 templates/config/barong.env.erb create mode 100644 templates/config/barong/abilities.yml.erb create mode 100644 templates/config/barong/management_api.yml.erb create mode 100644 templates/config/barong/seeds.yml.erb create mode 100644 templates/config/bitcoin.conf.erb create mode 100644 templates/config/finex/config.yaml.erb create mode 100644 templates/config/finex/rsa-key.pub.erb create mode 100644 templates/config/frontend/env.js.erb create mode 100644 templates/config/frontend/shahoo.env.js.erb create mode 100644 templates/config/frontend/tower.js.erb create mode 100644 templates/config/gateway/envoy.yaml.erb create mode 100644 templates/config/litecoin.conf.erb create mode 100644 templates/config/mailer.yml.erb create mode 100644 templates/config/monitoring/alertmanager/config.yml.erb create mode 100644 templates/config/monitoring/loki/local-config.yaml.erb create mode 100644 templates/config/monitoring/prometheus/alert/Alertmanager.rules create mode 100644 templates/config/monitoring/prometheus/alert/Prometheus.rules create mode 100644 templates/config/monitoring/prometheus/prometheus.yml.erb create mode 100644 templates/config/monitoring/promtail/docker-config.yaml.erb create mode 100644 templates/config/mysql/innodb.cnf.erb create mode 100644 templates/config/peatio.env.erb create mode 100644 templates/config/peatio/abilities.yml.erb create mode 100644 templates/config/peatio/application.yml.erb create mode 100644 templates/config/peatio/management_api_v1.yml.erb create mode 100644 templates/config/peatio/seed/accounts.yml.erb create mode 100644 templates/config/peatio/seed/blockchains.yml.erb create mode 100644 templates/config/peatio/seed/currencies.yml.erb create mode 100644 templates/config/peatio/seed/deposit_limit.yml.erb create mode 100644 templates/config/peatio/seed/engines.yml.erb create mode 100644 templates/config/peatio/seed/markets.yml.erb create mode 100644 templates/config/peatio/seed/members.yml.erb create mode 100644 templates/config/peatio/seed/trading_fees.yml.erb create mode 100644 templates/config/peatio/seed/wallets.yml.erb create mode 100644 templates/config/peatio/seed/withdraw_limits.yml.erb create mode 100644 templates/config/rango.env.erb create mode 100644 templates/config/toolbox.yaml.erb create mode 100644 templates/config/vault/barong.hcl.erb create mode 100644 templates/config/vault/finex_engine.hcl.erb create mode 100644 templates/config/vault/peatio_crypto.hcl.erb create mode 100644 templates/config/vault/peatio_matching.hcl.erb create mode 100644 templates/config/vault/peatio_rails.hcl.erb create mode 100644 templates/config/vault/peatio_upstream.hcl.erb create mode 100644 templates/terraform/terraform.tfvars.erb create mode 100644 templates/webhook.service create mode 100644 terraform/main.tf create mode 100644 terraform/variables.tf 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 0000000000000000000000000000000000000000..3ddc5e56a32b67621c72fb939125deeee5d97a9e GIT binary patch literal 20517 zcmeIabySq!_dhy>f`N!4D5)SNC5m*6f`CX!2uLbO3rKhPHUKG+27yr|l#-TKi9vE` zX^El3p_{uOe1E>*`@O$)|NH%OV=dQ0W|-%B&N=(+ym~Q&htSWR0hO#zVU-t-2`gxm=G_l_P9j+r_HGnha zxfJJ%=d>3ZFjs#xJpbc{8DZx0sGR$>$Kk7_l)tj2|Dw{mH>Xmg$R*n@TerySyB!Mk z?JMsWcuut6Q51@Z4uvAMK%q`!i2i+{{|Y?t|N8Rb-(|vE|MRc^>*Lul&i}s1f4z)c zwfKL>%}%AHr1a(*9W0hFg&r)9)dhtyNm^|c9V`x&(<;}+$GxSbyKv!W6T=kE&y{MQ zJ&!X7t(x8|apw+pcn(|*D?M)bYi-UOB`eM_EKjy199!r?>2jduZ5L-}b#dP~lD!-z z8p3IE&KXx%KV*pJGw5$`r^+1r8Nm^8x6Q`J#@&*VN#gtp@AK!+-S^w1cIFobO2)S^ zo3FME@=T|Ciobep*e=wHMBhDVol5qV60de~b={cXeYLSTln^xM$QMs(?d<0EbzNb9 z8Q0x!iJXiT+b>faC}D~43;{sh@xZG7l*{#Szj+z?d0hHcrW8$zmh{jc50$z zbz>t;^dN*@n0=e7pf*!Gw?mp6t=hdkKQj}TGN<8}WHUCs_bboj1T9~djTsH*nL91U zZm6utjWBktJNrQa`z@u}YASmhY$#(MmdE^8weLZ>>k{eo7YBT!$nN=r^env+zTqhP z_a-f2>DqG5XX)8|r`x0t26veQ$KM4O>$Dw(fi#Wi`z5_48OJxpv<aBB5&(3b+V~l1O#ZrtpO;(31J@t5GVu-}9Ja5eWG`<|cp_*eRK8S|KrzA*Q&Ki}U2!>UyO?;DppnPIEmmliQ~APjiom6+Uw@6!H&%F*EfE=JTaw3GDUrKdSuwhnW@ip zmv**pw=}akTd%~p8^6(0X_nIiv)kBZxWkrfSSco7E_DJ&T!`XDlQcg=?ZKl}2oF|z zZfuU6zavm>|IU1F`Hx}5^ji1`J&}{cfu-TCmEmt^DR86hDe|Ryx8>#KSK{~$D`Gvh zKH9zQe9G`MxcXERmjqK}x6b9|-41FO@BP@CQDr{#)FUE}ZF~3HJkCoIo5eGZ(hl-z z4qv_qc($oN@@wUG@4#OPs~2JX&Ue9F^)vgy(1Z^i{#EP`RAS>)te)t>PNxBNx)6Hm zt;GI&QRxaHBGPFt+`vG>#;dc8;k;okB~M3xC~gMuY;JjSJu&$D^!<~xkS*8wUuq=@ z&UFRmZKoK;3L&1BUssZUlHUCzlXBU6t|xo7{gbMBv&-_t&-}JKUfabs1Ga--1@04V zmsB$`r?`81g*FkQ1@W)}LbOcIl8}&Woi&O3L=&iU_PzV@aw+VYP)70Sm-saYNUR5WQ;J@m__x)xl?;zDX+8C{)F~PY8 zJN)T(>b6z=YZsU`cWk)FuxI3Z@we;kYtKs`aF&IoU$=UeIA@#H`qH z2;G}6H+G!z<)tz79D2GN<}9o{??BJiM0i5b?^=>*n#y3AbBAo%Q;Xs|XR6Plh&SI4RKu(nugb>zC)b;F++^Q5XzNiqKVC>zGL4$UdL`z*eDrD=EZo|ma}FHu%2J+2wtO2`d*B?N+SoEQZLQsCxX(VW zpX~fx^Kv^oGo5ACBIl%g9^s)0Xa|Q1NrR+ z?yxv(SL>}?F9VNG@16~y&@7({HmOs*Y_nXA{r+f3&nSdru-C?{)$WP9K7FFp6<_hZ z+hgBS+CO|?w{i;2yn{>^kMmnna$IM|yq|cW)%@CAZ-|He#IJZ)f?B&=>Y4K1{r&xG z?t-%=_j**-l;wDtMy?VY_gPTgFtRzJHT)baCFXnYl;zp8J{R=v;{Q7k+WTw7tYxFxq=4oB8 z?&I-bee855R)?1$TrGU?JmM72a&YmrSJoM<9o|JXfqhQ`TW!fshrxCdOD3TbI~~0$ zH{0v@OB_PEwd{sE`SI^nD%kd(G|^q6)h41Nou0XGXhRdmk@upa=Cj~KZ3n9^8&h%9 z)IIjMMy7e@t?#&8)1rFAYZtyCgs2ck0lb0K9n zv1E8R+WQ7u>h9PGCtdebo@qf|O35x0FBv!f#D z$;5p8+%@Fft{9a)9lhoLRh=u3ASfkPT_WTqxI{8^StTly<%b7;(Bny({?RdWovrX5 z+qC=|RnzMs?s&9KMU(VsgK7~)wA$rmJKo8xU4|qjbZQm zEd0uhk)MoWHfxTXi{x~UI^{MqUHJ1D1KKai*i{E8>* zv#7X>SKbf4IctfrWe&@@=18KH%3)MWmYdycosfHl0|OE1*wUMEuC!u4zoV(RxyM=0 zD4vshN3&dMadFH!;UGoPx{EDO$vLX2SW4F~R7Y#$-X;IojC5{!TX#upwbn+ZKpw-b zavtfZ)3^*bB^ER`m*2nLW}x_fqnDJBwYt!6QIORkN}-O4Wa|7p{#_TtJNKHB%co_BlO_4S!`5S9Ie zF{kUqL@dNme#0+B)=V#N1aK zLJdtYd7AqF&hNXCK9Erse{%Dl_`BN+OciQ%%t0+HviD;9Q3eSQuiSU&>Qi=j+I9LY zo!rIGzw+^EKVRM)j~OVjD*qZ8QWQemD1QPMvRJ1hSD*hdrln0e=TXSpxElEf;W4Hu zKfew^{mx@|WY27gr#iioXB@GlpQIfB7M0i*EL<(d;{Usm?F-)Q^KNb9s~QQ_p`C)$@OC)uWs>g=!VdpYOEQ`C%++jlFyaDlxR~12FTQWiTU@95y8^43aJ!6 z^(0OaZ7trSSFk4Tw7rk@TbEOgSe(X8dHLnM3$~^1YV>(sI%zAFrPoJN-aLZ0EmWhR zc5uAS#^&qhmm~N9FLuK`zn_mgswVK*nta%4$SScvc23nh#0T@9yYG;4b=#iUX*WG2 z2hA&N9QVe-KIC2huJ1^(jou>ufotC0-k!!846D=R(aC`JkYa<{?;NU0f~8}{cNCLk z{rG(KorA20#xt&^NAE<-rDp6#5`uqf3{3y>lC6`Io?y>jdmvh6UTPPN($>3bg_oPY zLpI%?q*g?B&?2ndN0m8WFEkFTY}(^q8AVh!C@dt3dp)8c6~c z}t`M4iy_f0Ttf$zB)HSzj9&FSz4pd*&bdy4u0* zfn812MGnas)KEsbO5Y9BW*PjT(mg{b0T@^N=@0lcE)pjxd(D~f?uoD3en*KsJfgH~ zl%}bzqB9Q^Z^VsTuGCG&z8#Uec1?Z#p{{smi4xo3n6>(vfMxt_!}AF$s^N&lLZbZBLv76m@ZuS6m0WORlGKB zX<;E`!3Wym8FHMn_^S3qrpbzkbtfYxrBJvm><%53M3t{Q-`qIav{$o)H&L1UNbJ@H zj3cEpQa3GQ96JCtCXC1wxu38|-7yPIcV1HOdEBP6XiguJch#(X21|)k*1G+oebDiu zRo1vN{y4^+qsig%tH%4!O?CK5T3$rXT$bVt4Q2UopU>D@owXQE8|qLII%w|wnRpd& zW#i6u;iaAnxzRJCOjx=AHqGs7m4(|c@a*Rcq`g;sh&!n;P4zob+}ib*YGG-{FBa#M zC4{09eO+5}aj{i2)5n}g8zhUH*24+A|1?_5m`k9il6;i;ww0EDo<1CdcIdj8*=Np5 zpS>~$^%6A*ff!-3BCk57t{zc6rRkmKhkktiud;1uu2i?V<(z3U;;{;n^B2U2JmvPb zV_AqAisWd&p3dNVvG{Jv(mk!b5Mrl@oL~6!6R=8COkB!GYd(7^J}_6k;}`la#&LIh zZ4S$D@Kv8)`PIHfeg``hCIvHD5-ghKwkV>R7CmzUmsjuL`l+?GRWAKObstLUke zmy_x9%agIoD1#)c^D8VrBrrbip|%p$7&(%gtqOj82l&bHoUdmuk>i+EMPEOix4}x& z$oFaKCOA31vX&aWY1_)R<2U)8^UB_5YesPw9;t1341DkYCQ(^Mx~`3RkN$WMlbK+c zZAcY*%idXj8(^ZL6nR{2h6~=nEIwGlz=hV58k69p!l~CNt?SpyEH+u(pqI__f|&_p z;yr1S-H>Q<>M23bK4GJA@0FGB361lZrdETNFcT~Tw@o97le+`vCzWMioyBnyC)-_H z!xs*B5@0x?d#LG1u!^&8;!0vhoR9{opyP)7N-ERJ!}|#i`{5Jo!;(;3`}nhAL=UQgW9EhB+o1 zt`B8pk2XGKIJlKES#s^As*`5F$CG)U#9ezg9R|q#6 zntJViLote8EO}EW$1sI)7FD~k<;yMH`H5j&X;JP76YuyKS8fTSg5gOw;1H za{p4(BbxN9=ong3;q6v@rDnPWI!4|V(EO8p%jK=g#_Y6ZDmSm6a(4Xwt8oOB0h3%$ zwyo8G6Dbr%>9@;1oNA*tKJ}-B@@#12S?46!HyM&TtH#JHwXJB*#x6@4hAeh7oHI`e z-ft&%s*M~T9(GuL-XGr3*cv}>cZ|=|A~LZd#kkd|+?_Z`j9qv_SbEJU^U0`fm#l6v zu~vUc;~#3H{KYeko+83_0@;$=+iy??M_UkDV=>P-vSe^d665I&Tg}`$_b|kJ+)}*W=L<<=NN-hc)EFS z;TN66h@DC;=?u8ka#9;5LgJb7^Noxas*RXNdqdU5l!?Tw;wo;kD)pL8=PS!YY1tkR z+*1=Jx1ZgmD>AYD9eBZ*mc}zRfAs3QMTi61wD5OQQd0h8=sg{wx^9+X)rGc0MgKh5Wi8EJ zc#+e<*YLMUwYL6hf}wU>h5{zC4K zhTMgWtmw_@e2YYJ*F~9I=q-w-d(QK}@^myA?(KDGzHTyoZoM0NrTr4I{(>8IluS{+ zhG+9Tnk3(TTN%E3^EzsTo7t_bayN!Aq?_rSdTo`$AJIsxYs0_?p%(4Wg*pS_CmU^#nsPMt z3;k9^T@mgiJ38H8|9Mj@d?v*yLk+e5hpUluygiR=r*)2nbFfrRyrX80 z*Ve_W*yX+GUyBQ)h|g-{bi<1UzO0oCqkJ8bP|o@BjQYSC(QJV0yo-cvtb?BY!%92pizU$`l7Zlu^?p80pJ)VCM&NSn=|%(*g9V$ znk4rsQ+Cv0YIq_kr@C_K?maz1j8RHOp_d%7Q`h})GrF~whVq@w&*PN2MO2rp=Ex|S zCdzo16(g*7=)C>QT-_`$vpnfLmhaLcZydVK<9a>Y#>h_at&`ZW!isAIvb3 zm9-nPo%^Cg0&`*hvGJD(WaLhtwBXOFIwqa296y%-r2SM>XsHR|J05oK*W;(#P9IY4 z`0-&MDUJPpR7T>o-Jhpy?ORGP{UCvTX1pIqjzmxJukUsHoNt}tj8c+9Nol?tOO#Ay z)OODG=E~nrh^7%Q4-E}v_St+S(R6{4F~s1Jxw-j1JK%QwyZuy@U zVCh+Sd4ksAQnPiMZS}9l?Pd;&`T{9tNe^oJoF~h{$`=Ik?x-~f*$f}}NX!-dl&__0 zu)pHMW7+nG#GAo<5+B1=y?E3rKbxL$ub%Rf6kl%iFTwB!opqnKHpJUUe43MoMOukC zmp}tZNRyBc7iw`krC^*Cd%dI&8y|e;?MQ6(ogrUoDd9xQ;4$h<$r6Ha|DMWfN$12! z*vKsgfqE4Yv!J#R1AE(h4Qs70S~rP^R|^9wyEg~Ku}?;h_|3ctORM({=Yz%KBNjwy zd`M4E&&^!|wo+N{0k7SH;J${9AHwY7{)yMmeTScui{>}74S9yVbTt=$mx+F;+VSDT zi$=XV;vYCKqEFyZ&HSoK5Re#aQOCW<}S&3m3%uNyEbDdM@#z{b(>mu|_Nc z+V!oOMfT(M?1>+Vh;;pqKJ;-19u;_}x%z1+DHA}4TVKn8%aVMPSc6srs^B|Fpqqqo zKw=E%&%3Qohj$Z`<4`F06O}qI zwc=XeSIeCRaFijUMH_NdAWqKjx& zc&5`-ly zy|$Kt*OxljU6C-2pRjY=+g{t>_aQ2aA}&m0hVI|uq0sF7yneNh_rfX&A3ce~4gA%+ z`47MUvzhS2Ng@>G4Ygi7*HC#RCJZkxry3TNJ0U|MZGWOWpk|f35mmj;jx_aHK;Fc0@Gn(Ad(d~a<_oKI(Hktn5_Hi8H$kLOtd>m&%0mb?JACd>G4Qn#(kKmVn-Ck??{hDclSJCU4B1M~De4Kk>`p*xa2L^9(IA zAEy**T1ZyyZWxG+JwJN%Xh&z)4LnGs#D!`ir!n8{C9baZz_&?g005a1)(m!*CwC8>dz?;p4PbB_KxKA%&~erk}u-J-rCL5rt9=Oi@u$(QU(0n1hK{iLVZq`-jS1 zt2eD@#(n@75@~8T__e*Wv$MPV{>}{5po!Xy!#DXbrn=59W*I*hs`n#l0F?xP%?8*(fhx6i4 zGUWV@`h{KYu#%U@)`!qLdOAA59)L*f+7UIZv>%s?_kr@AFD>_Rwjq~GFCB}w`POOC zi5H*2~`m5X8oCtr|sdNOKb*c_*367I!?BQ^Z~cK8e6dJJ=VFhL4{d+ zhTKV%eJwACao=6&G$!Q7GbA%V>pPbS`?I{fylLPQISxtP%|z>d-;@|D`E|ZL1W<~< z@ej;K_TOZWsVcD>0o8Z|IEDiE4NkW50ALU1UqOCHVnHhS>?73Qxq~9MjZ}|sN>Jp~ ze0>l8O+c`gMip)ZM4k6qaw`+@-7u68*)rVf0Cl#kyqt`TtSJzr22ofw5Pr((17b)m zQjpjfcYA2YAnNe=`#(n@CCtsuiTmts(i(ZS_w*D)2_{?~cbsayJ@~39B>a8Z zg?FZY2yb)mM`IK>C8L-V1Yw(R$!g`Upy3(J5eq1Ba_fF*R%q#icj-z?PZoh+;dSgl zXXo|F0hkYsYfR>T$VT+i=aE(pqYTmU`u*)$z&zw7m9w28U%73X-H&Nhc}Bi<9tEQY z5#9ORhTLSYiQrcpIfA?m;V0_j6Z3YwmiQLmf4 z{Q@)P=Ic!)t9v^ezT4KWi-XYdo;#dIl&&-ylHe2Ra5e`+ZCeKuCw zq^G1BBgk5kksw7MCqOG@Y`W?lX z4t=#}H8$F9(O87RY*h*h%GdUhe?2jKXZ#`P7S%A5kf{jk&z?PVkPQXm3ue#^3<5J9 zsrYjt1)}I=5&N;-C6z?6BA12!*z*VfAZfudY1|Ey<8)^PYK)bUVyP&xlNEhv#m-pn zjinz{cGaLFrEHc%8s5aY*-12^?xIdtB;&&OHLMZwt{^jP}6JVYp``n08*6aSgJv}3k3y5-H&mZ ze}gpkn%!_k;6u7RJ1~S$nS%%A+)Qyn!S$iR%QvnkOSoUVKL!R`%->SyI)NWNBY1 zv(W5}hU@!5p$od^Ezx43RZE7iK8x$Qb zeXx=3R@^b7V`DW8Q7VRoV~AmvaQkA`5+AGM@=?V&4ngT9vOjVLtHiz5`^<};xdGuG zqQ1PpVW#J&A|M=i?)=;(rV6jE{9u^kq?V=ESOI+3Ck;{blvF1dDa@8=#|p3>9Vb~? zSuOKE4T&9@rl1#^s2v;`Vb<{3C1BllcehsD?3$UE6m#Vw!?X`m%SnzOe)g~DZxo$) z;`2PJ4_Ec)5|Kyu=lhu>dc{v3DAt4cRoho66m_a3 zhehN`4tqe91p$?~y0%ug3Nw}}bq?YxG#%C{LCB^bE;y^9c63@t#mBA@8-+?VLjY$i zk(hVtpf9U$n!KU53mz?JbrxH;D}BY z+YQ}x*8W|qJt{fha^LzmI=t)WWE!%RPSrrT2p50K)j^a?7Z20aF9F7rWAW4EX1X-WzT z19;GpdsjQ2E^bm$UU_bI8SF$~A#FiJ?>_LOE11#lPIkNdmH->Yc6fSv;HU95cxoZL zVV*;L7D0%q-ZcfCfM>N+Rl2C8Bt7Bt1pA-j;$m24MP{gUsE5})JUsTBe7E>bgKbk$ zl44?IR^6Z3?nX06daOeDa;UruNQXFT6m}6fPDU&!5=s^u8}Qu7d+k2p3g2zj1FpJh zt>d^)stq{?btEGbYz+< z{RCW(SnylL@Xy+f`MJ4r==y5>DGzq1qz`%=cyZa(m~KFj83QQsxVV^Gj`)PTKame~ zjmntl7cK<4N_uY>Rus5a5gK2-lk{|ftm169WK4aE z)Z!@vB{}Z;X$)(EoQIV2tfr|)+2}e<^jNo(_%}l4n_PN-)8z38?4uSE4$l2-5ndV)lw;6*^Dt zEFCq^n0crsaubqXn@?vOs2-Jhfd_H3iN6}S0ZxwkNQE-4CENZ&uHh=UD^T4G7$ook z54cqJj*KLGn%3?b^+ebuopF@&+kYcxK}*GgPO&BV5)l`Vk`xg+-@ZQEof$O~u4Up; z=D|PaEWx*QWE06XXY#&!-Bk+gqNham88ma)PN1?RJ=Z5tl@J)QOe?jkt5zN+%_H}x z=jVg92m1RPRR_zQtt$+mWqozbk>%tY=QJTSvy_)ehZTPLJK!=o-Jvg!WIRBzYl)qj z%dLj?$+qjI31om${xygiW5tE9%%i`*KPPl-txPoqLerl8!VPH~QKZus$Z<$wgnvV3 zGiNzeCb(e429U-;pDjg63JPkL-pcDZcDYCny9zt4-~N`d$8I;--w(%~#AS|TDk-(p zgqyY<*dk?+&DlQ5$&ZhpMTw}aquC3(g4kFOZ_QoUA%u>Z&h&rVUm_xpS0ql0pTqf2 zKe4vfyVnNYSUNv?q{6)bGAUHz#W!uhpQarycU2d%-18@KkP|-_qM_nm`7j$My{{8@ z{l=~IrsJS=Kz{J;%Qqz`(}mo3g(T5WWBqTAntv?i;x}CCXs)NH=bju1+m}bTFr)Z_ z$l5Ixl3@r+K_;Ydb=-PK;-ombMfZJ@NbJ^1f06aLOoBeE+xF^A>;XL7zZDRoh@HfV zZDzR2TRdrTpd{C&wY|OFv?&_d{g=eGvUSgevEG;GsRH&&B7_vK*@!jr-E*e9nCtGR zGTy@o+djQotCjhYq?B!k@G1?2b6oX1a+1f1pD1uMuejX5g$TYFEVAy64|dooBgNQ)P(}e;qJ?N17QQK(mwSm?#B+Y2gr8zh;NR+ptgOo3|h-9I^*IxNxOEUkM z)Z#FNhK~OFiM)Z(Eq`xw0(blzu^?|v;8k=F)!$b9H2m;}wIuqlN3us|M;D$0@|7Vn z%wSYDl98Kp%N7#ssbB$TQq{sOezFL-lB_~w99hPGidib_9#WpIhuX_hzN?16 zalQx7{)p$g8;g?e8O*t3M0C_wi0Ix#lUm%q1@Bt)r7=%F_UpO%lxh8VRP;x-+r&h4 zr!mm6y&QMLKd{ukOlpDl(<;x9o_z8+JUY^aNH_d6rhWA}DtjMZ?>_>U@sn!-D#QgD zN~(dM*5&!f_Z+!2i3|I0e~f*wjpkk;E@Zhhhk@tHlzs!3IJ_|qxdePBl`YjE{NBHJ z37}rt5;1hw>PMavd5T#|=Y-{~LhduKU!atmg!V4NB~D|a{yv2ojI5iP9H&^0%2xRG z6Ek@W9u)kC^2~pq<1r)k6;g{evW~YMISQO-@=wM4AlD==Ed2QQiWKBHE81{lDP}Bp zn_@Z3B{T{0(0lJ~HIkx`r-Vg^=|L_*T-d>f<~~C#2rE~(O+ut=Nego+exXYrxdf5N z_B2U$;R)R97g^75!CdU4b=6@Ew{P{_?4(4l=@#*Rzx6T%2zGc)H%q*sB&0*!~7YyQCIUV+c2<=^)cR45|lY zFOL(I#Rb%H@fnplaS1Ef0hCC~(k=QdgzjB~ngaQ*yo10RG$U*`?6tq^j+Z%N@$Y>f zsR-{~RV7&kFnQqtK$?P%YL;cE&P+Yp29}^RkArvNwp(1N-ATnN`;~pdQ z6_`8v*;-o%UDyV@`YY-f01ECfpw;(OStg?PU7YG7p)rSR1?}l|BC(g_0d;_bkvvd~iYG-Kf3(Y!wr?-QF&BxZ0;q?Bg5YtICViBVNd zLR=Fn@o4pl@PZ>2&I$j<-=5I%bBbF(+8&f}g=wH4TWyX*lJ*wW(^8AUch03E1SSg!f;-TJN+Av7vNoJnVvp1ie zDSh(H7Mx`6LDU5}h6R#6=opjZ8#!dsdZ3e2eJ4Uy9n@9rYhl4@6gcqsH(lzU2{`^& zm599z2)0Pz{%q=rHKfr#M#>I?we8kT}VP ztj=x#{C#$*#!gOG@q-1gg;nGD6UCpD^t&G~#Jg70aD7buS%j8v ze=YNU#`f9%`hcC|C!eilQ;8P*130TeBo?|*1oW^UO479GuI*iM?`@}vaR<`r$1udH zu#6{T$fjA&6ksEkmG%Gr{X5iNpjbXOa<$Re1*W_Igjf&x!bEG3v=O17mg?lP>bKP-&0QcCg#lIPxxIV1GHL+G_$eG%(-^=tN{V zCP#xPc1~?(6e|$jd|-v+JiRmoy~!00 z2+)S?V|ne>+q0SaPu|9k!lp|KW&Hh)6OvYT7bIIre-ft`lTgPq;Dkc;j;oqBm#^ao zTi`=W;ZRRpT$(r<4pn&6yrO_pIe_r3?Cip>T^AHAv}pfuj$4aC!tD=WHOnt`U18GZ zi(T}WhbTFR2m1Qr^3`mhVI&i~_Q0z#J=sTBv}EOyja)s_((l!Jg4xrtdk*j*&kHO8S?V&Ys;k zP|@$gYI7`B@An>fn2+sG9qcCi#(&j$#?LVg3`qocWw_=3q}~1`mf3fACHY|2p4h4C zfti(As33#rr{*HAy^ma6Zc#TmLUbdZYo?x%A3`Nw+xAbN((E6p@}?iTV(jgesoAfW zbv$@&o&Nw|y&HBwkWP#40!N2??e^>Z=1AHEDX-0|p)tt*8F%1$KOaGJJze9tn%}rR z!}F++PIpCy^g0B}Mi_;hiM4GKV-x?Tqjs<*eK6&_Vz=J{4EUttzxCVv_KDSlZKDJ3 zu_v;5z6AdLy35N(0Z*^DW46Ftc;`j`!TQMlz-8i9>D?M>C6=s%p^?2IS;}Lf%+kZa zi?-K<`R?T&tTD55cW>vth#X26M{6Hdt?=G)F?9;Pb~gR=J2|svAPgckmSc&wp)?Qz zA=xn}C8b2xZwD&T_yVtbfGbO@P!ME(nbJW#WTBV-YT}&-C9@Pmo`_A4$TUPtu6`?1P|FonjQFVVrWlEohQ;!nJ1#+QDm#ib8oK3x)Z)(@Sa(-X4m>AI1TU#Re_ z^vTInrzSO+Enj@#w9_!WJm%+~Lw)RlKUX>>(#-iz-w>oqiK-U8#P-qhO56BJ995!* zc5j1>UWx6(+}vFmv9!UnD?m+TEV>_b#fzBvEdtbPi1IH>SngmNy%Ua*Df7@&1E2^` zO8J}<9LY>ymR|_)M_)+&w@T$r^*G>EW&{^dQ?gKapNXEu_`iDP0|*gLL}`l+-#!)4 z&t`aqBhB-;79Tx-s@km7Zk7{k44=X0;1@XK6cN$T&*F!@4-P+RO=!ShF*a))L?zsTx-#F4auHyRxo zT2N7a-EW5~2&m2$hcRF@a$eW!&#cE^x3`jQrU;qA3DCUtYz&=Z`LTPGc{p6gFX`|p zSS7KK?u(Ke9LJiPZ~wy9U($$7mB0h_8RFhC6Yy*9IBvbLP^ptLn*n1I<_me)3-2b1 zQLk79)}X$2`4ziBs=Mj+AtJH+($EjFyhKTQ6M4Y#zsgEU_B5Jl&Th-A`3$d&Uy&=O2cUXF)dFI-MGBxP}7DR9}mtnTbt- z+?_nuXaofr3wc6AI*&Cr7cYvTJdQLEAw_p*Q3j>G{lLPo?t}&h7Zw$z;@HvVLF$TGZ;|4ze4>34P-Ee^~NQHtY)8lW~ad(n&^Z7u-0Y&#nvy!X&V?e8>GPp z@B*-4a8<_o=yaEGii4z^1W+tLM{E3>9`SwnlS2T2RNUAe&m`q_{+PJyC?|G8 z44UT4OP{jo#l*#-b7xg22i=_faB-N6TmrN7PgO*{I;B9u8x=Eso5vQ)eW1HUd2BxL zNaTH=qQv%HoSmWlUWZeuTxdIBvnaSu3wT3P+v?%a9?9G>&CxG?Yg7ib9vwM<$s_F? z)i66lmjW6tQVYvFh(P*M(Qp5JQ4{1Ht0jg6kLxk6S5;^Owb|u9ggj>WB=*7a#f;m# zS3?R!Wgui!Qr{6~n&KS%ICoq0w4Le6p~j0@mKELPeJpkIX_SS9mjQm|pE`bSMG~D} zb-@{1l-;}q{YZZxLb(DpSu*0|32c!UHLm(RJdX^A}-_m^>O??bRMM-7p!Y6+F(o5LqL9sjS>ocG#DA(Lp)vYA} z&nEwrmg^%MDXCgLH_}g&6SY&z89s=k8Anig; zKg8nT;Q>9l_abUCOITe>x|d|-$GYJe_0XOLcpY?9U)l-^99|J z=@Fl$jS3LU16nOVP6>L01jxmZ3n$B+gAtzUki`HN#xJdoWEJFk8jvLm>`vi;33X2r zT$XbI+mPTM9IyUF?-b9Zdc@)e?O$?+=wEV%AW+b1p6ng%VN~J1!kz?j^+&zI8zE0jOf1?G z;W4VJSi~N~{iR)4ULHm)M32wTx(!{sXwXT61b=lIXV9+|L@U$NIh02#JxdV3{8t7s zr)kO+y{gC;Gzc6=vb2w(>?UH+0}JQ1#f1e)h`@z=PNVQr%t&U%HdI2v%65t}lVqCQ z;WFo@MMhGKO*eqrmwCC)yq2{F8W;B;Kh|~11R#QL0w;rzV18N`rwpHUC2JsFfJ1ic zoWc=xAl@D=;>dLImvezR3MJ-3IKIKBn|~f9k|zYLr6}Nt;iIsdKg|G4Mr;)Q53U_b z5zS*LZ)iam7Z>}}u_Hlb$-etrApG}cJtzP>7fcj%Qosj-QeweCOge2wv<=M1Px(!% zw3Y0NBNjxuoneULeGx5u0`~}3S|AM4!M}myC5#fA$AQc;afAD6H|HNy>#ra>t(cz;x{zB zg0qei@Lds$=1X{?8EOoo1c0Ls968{Rigx9s#{5S}=O^+QDs!HZ;tCHQCjiI*mqH0- z56JeZ7myTqNTvF0j{3Wu{=2tJ9pM*xb$ z_g(NP2d5*76A_Y5!H%{Pw83I-{R|hOV}ZwYg)h_)lsS$A zK^)L~;NUK(lwhQgt3W<? zju;2h3bmZu75HSLor##K<@V1`Ei?Am9#xv8d9c zySqEe5LgkUOu~S{M=0&N1S#t;pml5g@^MN37Bb=8e3C z>=Z*lI=L8_ay{`}Fjw=D6$bugH4}q|sRIO6WeA zN6Nu0_UF%^)gyh_Fy;e9t_noOGoofe zfk>5EpMM}x1vCsyNwes+Yx(eO4Y&dcbh4DU2e>g#90x5j{9`&-L;c%vRu-8<2PEzv z#J=HriDenl{24@-x2BT8uPw|rd74Y~hBOD1X1EfkCCewLfmu_EIm_OooB|D z;0+LZT@c^E?s%B=WQlyNVWEZE$BBL^9He6_6Rr&^N)tesc@|l+aV8tHi`<2=g$XdSMP7nNwEE} zR{}Cu^Av6rn1D|^^0jz{vb>DO-Mn{-excO_kt%dj0mMNi-HE_jhCqpuQ0#NJGRsbO zL<$Bk_thWVEcS?NW-*#uR)Z_Ez&_-aT5jV)>GZ8SNLBAhsh){r@o;%RB zZACZaLp1Q|VVbl7Wc=#siT1A$idr#P&nzdB#U&B_$;;=gW0eNaxB%E}P<&6NI9e<5_(AL}d|dfU0ME zIjN|aP`jrA+>KVrP2nO6#8Y!*I-u03r;`)y56IUETyRZfCa)j>ir`4HV2^w}0_cmF zk<+Dza+x3HjX=~M3~Bj8rTXJ4w;5o#32q=VhV%y}kWPdAQM(F(W9yT<7@}DW7RcdY zL$EuCK`b)HN!2ZW|9-RP7ntYA-TeB_U}}KA?1v_1AdUW+$nqTGX@Ny}S|#^|fzty7 zNM&ND+0yW6jp2yYleiI|9UIf11d)~lpjvxg?c`SPdvuW4BM_^3j_!vdD)uvq@n-P? zLfj^TPbw)%${P$dvr^%c?y!++dmza4!R!D{@UnIMC^-1w@@3msht5kFDeD}=QPpZ! zxPr?;$3ZC=&8%wT!IT1XDqMx;xpc#Fsw)Q(1EG|I@1gT)lO^>O4~t!G&$0?9V)QJu z)JVFt>?A5Bmx4-^>&Pf%(XM}1<$K^$Isww~_-`MI_m@uVrrMh%@6rdUH z*Sh!K*MooA$+WhN=ZEdk1@#m5LpRgLQ@h^jyBq`rM(t1o;N^&B5U5;?3Y`h^Zm=Oo z6x7KZ96wNLtmqO6WP^f=eCS&Re?T;ns;<^R_wcvpQObJtFtTQXkuO-`= zePT8g|N9UR%iohW|9y1me>ouZzw<27{|j!@Y<$3cz&jV-^xZ@WzA_JW=eCM$&aH?4 F{2v(GO^W~k literal 0 HcmV?d00001 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 +} +