├── lib ├── tasks │ ├── .gitkeep │ └── deploy.rake ├── assets │ └── .gitkeep ├── peatio │ └── version.rb ├── aasm │ └── locking.rb ├── generators │ ├── deposit │ │ ├── USAGE │ │ └── templates │ │ │ ├── model.rb.erb │ │ │ └── controller.rb.erb │ └── withdraw │ │ ├── USAGE │ │ └── templates │ │ ├── model.rb.erb │ │ └── controller.rb.erb ├── daemons │ ├── k_ctl │ ├── stats_ctl │ ├── hot_wallets_ctl │ ├── websocket_api_ctl │ ├── global_state_ctl │ ├── withdraw_audit_ctl │ ├── payment_transaction_ctl │ ├── daemons │ ├── matching_ctl │ ├── withdraw_coin_ctl │ ├── market_data_ctl │ ├── deposit_coin_ctl │ ├── notification_ctl │ └── hot_wallets.rb ├── whitelist_constraint.rb ├── datagrid │ └── naming.rb ├── benchmark │ └── amqp_mock.rb ├── templates │ └── slim │ │ └── scaffold │ │ └── _form.html.slim ├── kline_db.rb ├── security_middleware.rb └── market_constraint.rb ├── app ├── mailers │ ├── .gitkeep │ ├── deposit_mailer.rb │ ├── base_mailer.rb │ ├── token_mailer.rb │ ├── ticket_mailer.rb │ ├── comment_mailer.rb │ └── withdraw_mailer.rb ├── models │ ├── .gitkeep │ ├── two_factor │ │ ├── email.rb │ │ └── wechat.rb │ ├── bank.rb │ ├── member_tag.rb │ ├── withdraws │ │ ├── bank.rb │ │ └── satoshi.rb │ ├── deposits │ │ ├── satoshi.rb │ │ └── bank.rb │ ├── audit │ │ ├── audit_log.rb │ │ └── transfer_audit_log.rb │ ├── partial_tree.rb │ ├── concerns │ │ ├── hash_currencible.rb │ │ ├── aasm_absolutely.rb │ │ ├── deposits │ │ │ └── bankable.rb │ │ ├── channelable.rb │ │ ├── withdraws │ │ │ └── bankable.rb │ │ ├── currencible.rb │ │ ├── international.rb │ │ └── fund_sourceable.rb │ ├── payment_transaction │ │ └── normal.rb │ ├── token │ │ └── activation.rb │ ├── worker │ │ ├── pusher_market.rb │ │ ├── pusher_member.rb │ │ └── trade_executor.rb │ ├── asset.rb │ ├── withdraw_channel.rb │ ├── deposit_channel.rb │ ├── active_yaml_base.rb │ ├── matching │ │ ├── constants.rb │ │ └── price_level.rb │ ├── running_account.rb │ └── fund_source.rb ├── assets │ ├── javascripts │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── funds │ │ │ ├── models │ │ │ │ ├── .gitkeep │ │ │ │ ├── currency.js.coffee │ │ │ │ ├── member.js.coffee │ │ │ │ ├── fund_source.js.coffee │ │ │ │ ├── withdraw_channel.js.coffee │ │ │ │ └── deposit_channel.js.coffee │ │ │ └── filters │ │ │ │ └── translate_filters.js.coffee │ │ ├── component_ui │ │ │ ├── range_switch.js.coffee │ │ │ ├── key_bind.js.coffee │ │ │ ├── market_ticker.js.coffee │ │ │ ├── push_button.js.coffee │ │ │ ├── market_trades.js.coffee │ │ │ └── order_total.js.coffee │ │ ├── html5.js │ │ ├── locales │ │ │ ├── en.js.erb │ │ │ └── zh-CN.js.erb │ │ ├── templates │ │ │ ├── hint_order_success.jst.eco │ │ │ ├── hint_order_warning.jst.eco │ │ │ ├── ticker.jst.eco │ │ │ ├── order_book_bid.jst.eco │ │ │ ├── order_book_ask.jst.eco │ │ │ └── market_trade.jst.eco │ │ ├── component_mixin │ │ │ └── notification.js.coffee │ │ ├── admin.js │ │ ├── lib │ │ │ ├── pusher_connection.js.coffee │ │ │ ├── sfx.js.coffee │ │ │ └── tiny-pubsub.js │ │ └── swagger-ui │ │ │ └── lib │ │ │ └── jquery.slideto.min.js │ ├── stylesheets │ │ ├── custom │ │ │ └── market.css.scss │ │ ├── features │ │ │ ├── _custom.css.scss │ │ │ ├── _documents.css.scss │ │ │ ├── _id_document.css.scss │ │ │ └── _history.css.scss │ │ ├── vars │ │ │ ├── _custom.css.scss │ │ │ ├── _market.css.scss │ │ │ ├── _market_light.css.scss │ │ │ └── _basic.css.scss │ │ ├── market_light.css.scss │ │ └── layouts │ │ │ └── _custom.css.scss │ └── images │ │ ├── logo.png │ │ └── favicon.ico ├── views │ ├── private │ │ ├── markets │ │ │ ├── _status.html.slim │ │ │ ├── _depths.html.slim │ │ │ ├── _mask.html.slim │ │ │ ├── _chat.html.slim │ │ │ ├── _candlestick.html.slim │ │ │ ├── _ticker.html.slim │ │ │ ├── _balance.html.slim │ │ │ ├── _range_switch.html.slim │ │ │ ├── _market_switch.html.slim │ │ │ ├── show.json.jbuilder │ │ │ └── _settings.html.slim │ │ ├── api_tokens │ │ │ ├── index.html.slim │ │ │ └── new.html.slim │ │ ├── history │ │ │ ├── _tabs.html.slim │ │ │ ├── _transaction.html.slim │ │ │ ├── _trade.html.slim │ │ │ └── _order.html.slim │ │ ├── tickets │ │ │ └── new.html.slim │ │ ├── assets │ │ │ ├── _liability_proof.html.slim │ │ │ ├── partial_tree.js.erb │ │ │ ├── index.html.slim │ │ │ └── _cny_assets.html.slim │ │ ├── account_versions │ │ │ └── index.html.slim │ │ └── shared │ │ │ └── _balances.html.slim │ ├── api │ │ └── v1 │ │ │ ├── prices │ │ │ └── show.jbuilder │ │ │ ├── trades │ │ │ └── show.jbuilder │ │ │ ├── deeps │ │ │ └── show.jbuilder │ │ │ └── tickers │ │ │ └── show.jbuilder │ ├── admin │ │ ├── proofs │ │ │ ├── index.html.slim │ │ │ └── edit.html.slim │ │ ├── documents │ │ │ ├── edit.html.slim │ │ │ ├── new.html.slim │ │ │ └── index.html.slim │ │ ├── deposits │ │ │ ├── index.html.slim │ │ │ ├── edit.html.slim │ │ │ └── banks │ │ │ │ └── index.html.slim │ │ ├── members │ │ │ ├── toggle.js.erb │ │ │ └── show.json.jbuilder │ │ ├── statistic │ │ │ ├── orders │ │ │ │ └── show.html.slim │ │ │ ├── trades │ │ │ │ └── show.html.slim │ │ │ ├── deposits │ │ │ │ └── show.html.slim │ │ │ └── withdraws │ │ │ │ └── show.html.slim │ │ └── withdraws │ │ │ ├── banks │ │ │ └── index.html.slim │ │ │ └── satoshis │ │ │ └── index.html.slim │ ├── system_mailer │ │ ├── balance_warning.text.erb │ │ └── trade_execute_error.text.erb │ ├── errors │ │ └── connection.html.slim │ ├── shared │ │ ├── _html5.html.slim │ │ ├── admin │ │ │ ├── _member_accounts.html.slim │ │ │ └── _account.html.slim │ │ ├── market │ │ │ ├── _chart.html.slim │ │ │ └── _market_sel.html.slim │ │ ├── _meta.html.slim │ │ ├── _document.html.slim │ │ └── _header_lang_sel.html.slim │ ├── members │ │ └── edit.html.slim │ ├── token_mailer │ │ ├── reset_password.html.erb │ │ └── activation.html.erb │ ├── comment_mailer │ │ ├── user_notification.html.erb │ │ └── admin_notification.html.erb │ ├── ticket_mailer │ │ ├── author_notification.html.erb │ │ └── admin_notification.html.erb │ ├── member_mailer │ │ ├── notify_signin.html.erb │ │ ├── reset_password_done.html.erb │ │ ├── sms_auth_activated.html.erb │ │ ├── sms_auth_deactivated.html.erb │ │ ├── google_auth_activated.html.erb │ │ ├── google_auth_deactivated.html.erb │ │ └── phone_number_verified.html.erb │ ├── reset_passwords │ │ ├── edit.html.slim │ │ └── new.html.slim │ ├── deposit_mailer │ │ └── accepted.html.erb │ ├── withdraw_mailer │ │ ├── done.html.erb │ │ ├── processing.html.erb │ │ ├── submitted.html.erb │ │ └── withdraw_state.html.erb │ ├── identities │ │ ├── edit.html.slim │ │ └── new.html.slim │ ├── two_factors │ │ └── index.html.slim │ ├── verify │ │ └── google_auths │ │ │ └── edit.html.slim │ ├── datagrid │ │ ├── _head.html.erb │ │ ├── _row.html.erb │ │ ├── _form.html.erb │ │ └── _order_for.html.erb │ ├── authentications │ │ ├── identities │ │ │ └── new.html.slim │ │ └── emails │ │ │ └── new.html.slim │ ├── forum │ │ └── index.html.slim │ ├── documents │ │ └── show.html.slim │ ├── activations │ │ └── new.html.slim │ ├── kaminari │ │ ├── _gap.html.slim │ │ ├── _last_page.html.slim │ │ ├── _first_page.html.slim │ │ ├── _next_page.html.slim │ │ ├── _prev_page.html.slim │ │ └── _page.html.slim │ └── layouts │ │ └── landing.html.slim ├── observers │ ├── audit_observer.rb │ └── transfer_observer.rb ├── controllers │ ├── welcome_controller.rb │ ├── admin │ │ ├── statistic │ │ │ ├── base_controller.rb │ │ │ ├── members_controller.rb │ │ │ ├── withdraws_controller.rb │ │ │ └── deposits_controller.rb │ │ ├── dashboard_controller.rb │ │ ├── two_factors_controller.rb │ │ ├── deposits │ │ │ └── base_controller.rb │ │ └── id_documents_controller.rb │ ├── concerns │ │ ├── withdraws │ │ │ ├── ctrl_coinable.rb │ │ │ └── ctrl_bankable.rb │ │ ├── token_management.rb │ │ └── deposits │ │ │ └── ctrl_coinable.rb │ ├── private │ │ ├── withdraws │ │ │ ├── banks_controller.rb │ │ │ ├── satoshis_controller.rb │ │ │ └── base_controller.rb │ │ ├── deposits │ │ │ ├── banks_controller.rb │ │ │ ├── satoshis_controller.rb │ │ │ └── base_controller.rb │ │ ├── settings_controller.rb │ │ ├── withdraws_controller.rb │ │ ├── trade_states_controller.rb │ │ ├── account_versions_controller.rb │ │ ├── payment_addresses_controller.rb │ │ ├── order_asks_controller.rb │ │ ├── order_bids_controller.rb │ │ └── pusher_controller.rb │ ├── api │ │ └── v1 │ │ │ ├── base_controller.rb │ │ │ ├── tickers_controller.rb │ │ │ ├── deeps_controller.rb │ │ │ └── trades_controller.rb │ ├── forum_controller.rb │ ├── members_controller.rb │ └── authentications │ │ └── weibo_accounts_controller.rb ├── api │ └── api_v2 │ │ ├── entities │ │ ├── order_book.rb │ │ ├── base.rb │ │ ├── account.rb │ │ ├── member.rb │ │ ├── market.rb │ │ ├── deposit.rb │ │ └── trade.rb │ │ ├── markets.rb │ │ ├── members.rb │ │ └── tickers.rb ├── validators │ ├── ticket_validator.rb │ ├── withdraw_blacklist_validator.rb │ ├── email_validator.rb │ └── strength_validator.rb ├── grids │ ├── documents_grid.rb │ └── proofs_grid.rb ├── helpers │ └── private │ │ ├── assets_helper.rb │ │ ├── history_helper.rb │ │ └── tickets_helper.rb └── uploaders │ └── file_uploader.rb ├── vendor └── plugins │ └── .gitkeep ├── .rspec ├── config ├── initializers │ ├── withdraw_blacklist.rb │ ├── date_time_format.rb │ ├── carrierwave.rb │ ├── secret_token.rb │ ├── activerecord.rb │ ├── mime_types.rb │ ├── filter_parameter_logging.rb │ ├── pusher.rb │ ├── kaminari_config.rb │ ├── datagrid │ │ └── filters │ │ │ └── date_time_filter.rb │ ├── dirty_ext.rb │ ├── backtrace_silencers.rb │ └── check_env.rb ├── locales │ ├── custom │ │ ├── server.en.yml │ │ ├── server.zh-CN.yml │ │ ├── client.en.yml │ │ └── client.zh-CN.yml │ ├── client.cs.yml │ ├── server.cs.yml │ ├── server.de.yml │ ├── client.de.yml │ ├── server.zh-TW.yml │ └── client.zh-TW.yml ├── daemons.yml ├── environment.rb ├── nginx_maintenance.conf ├── member_tag.yml ├── boot.rb ├── slack.yml.example ├── database.yml.example ├── markets.yml.example ├── withdraw_channels.yml ├── deposit_channels.yml ├── maintenance.sh └── logrotate.conf ├── public ├── templates │ └── funds │ │ ├── deposits.html │ │ ├── withdraws.html │ │ ├── _qrcode.html │ │ ├── _flash.html │ │ ├── deposit_btc.html │ │ ├── withdraw_btc.html │ │ ├── deposit.html │ │ └── withdraw.html ├── peatio.png ├── favicon.ico ├── icon-btc.png ├── icon-cny.png ├── throbber.gif ├── ZeroClipboard.swf ├── languages │ ├── en.png │ ├── ko.png │ └── zh-CN.png ├── sounds │ ├── success.mp3 │ └── warning.mp3 ├── btsx.chongzhi.yunbi.png ├── peatio-notification-logo.png └── robots.txt ├── spec ├── support │ ├── i18n_helper.rb │ ├── cookie_helper.rb │ ├── two_factor_helper.rb │ ├── pusher.rb │ ├── rspec_matchers.rb │ └── deposit_helper.rb ├── routing │ ├── admin │ │ ├── members_spec.rb │ │ └── two_factors_spec.rb │ ├── two_factors_spec.rb │ ├── api_v1_spec.rb │ ├── trade_spec.rb │ └── verify │ │ └── sms_auths_spec.rb ├── models │ ├── global_spec.rb │ ├── partial_tree_spec.rb │ ├── bank_spec.rb │ ├── identity_spec.rb │ ├── deposit_channel_spec.rb │ ├── matching │ │ └── order_book_manager_spec.rb │ ├── payment_address_spec.rb │ ├── proof_spec.rb │ ├── fund_source_spec.rb │ └── token │ │ └── activation_spec.rb ├── factories │ ├── documents.rb │ ├── api_tokens.rb │ ├── proofs.rb │ ├── id_document.rb │ ├── tickets.rb │ ├── partial_trees.rb │ ├── token.rb │ ├── account.rb │ ├── comments.rb │ ├── payment_transactions.rb │ ├── authentications.rb │ ├── identity.rb │ ├── trade.rb │ ├── two_factor.rb │ ├── deposits.rb │ ├── fund_source.rb │ └── payment_addresses.rb ├── controllers │ ├── admin │ │ ├── members_controller_spec.rb │ │ └── id_documents_controller_spec.rb │ ├── reset_password_controller_spec.rb │ ├── private │ │ └── settings_controller_spec.rb │ └── application_controller_spec.rb ├── fixtures │ ├── banks.yml │ ├── markets.yml │ ├── withdraw_channels.yml │ ├── deposit_channels.yml │ └── currencies.yml ├── api │ └── api_v2 │ │ ├── markets_spec.rb │ │ ├── entities │ │ └── account_spec.rb │ │ └── auth │ │ └── utils_spec.rb ├── features │ └── tag_spec.rb ├── mailers │ ├── deposit_mailer_spec.rb │ └── member_mailer_spec.rb ├── services │ └── coin_rpc_spec.rb ├── helpers │ └── private │ │ └── assets_helper_spec.rb └── observers │ └── transfer_observer_spec.rb ├── bin ├── rake ├── bundle ├── rails ├── init_config └── rspec ├── db └── migrate │ ├── 20130919091853_add_sn_to_orders.rb │ ├── 20140328101707_add_type_to_deposits.rb │ ├── 20140416194209_remove_table_invitations.rb │ ├── 20140819085359_add_index_to_order_state.rb │ ├── 20140416194300_remove_table_members_trades.rb │ ├── 20131224162832_add_sn_to_withdraws.rb │ ├── 20140404074816_add_currency_index_to_trades.rb │ ├── 20140421080408_add_type_to_two_factors.rb │ ├── 20140507120249_add_addresses_to_proofs.rb │ ├── 20140806141419_add_index_to_trades.rb │ ├── 20140826083906_add_label_to_api_token.rb │ ├── 20141014085101_add_nickname_to_members.rb │ ├── 20140303060739_add_activated_to_members.rb │ ├── 20140702035833_add_balance_to_proofs.rb │ ├── 20130915150504_add_payment_id_to_withdraws.rb │ ├── 20130918143551_add_ref_to_account_versions.rb │ ├── 20140312061206_add_aasm_state_to_withdraws.rb │ ├── 20140416143352_add_phone_number_to_members.rb │ ├── 20140524014413_add_ord_type_to_orders.rb │ ├── 20130904215802_add_is_active_to_two_factors.rb │ ├── 20140102024125_add_fun_to_account_versions.rb │ ├── 20140306021833_add_verified_to_id_documents.rb │ ├── 20140319022202_add_partial_tree_to_accounts.rb │ ├── 20140327105217_remove_fund_sources_account_id.rb │ ├── 20140416143239_add_country_code_to_members.rb │ ├── 20130905025823_fix_account_id_by_reset_pin.rb │ ├── 20131208012814_fix_payment_address_currecny.rb │ ├── 20140312071704_add_sum_to_withdraws.rb │ ├── 20140712030803_add_disabled_to_members.rb │ ├── 20140715083857_add_aasm_state_to_id_document.rb │ ├── 20140531054739_add_used_funds_to_trades.rb │ ├── 20140618004355_add_displayname_to_members.rb │ ├── 20140803202610_remove_channel_id_from_fund_sources.rb │ ├── 20140826093508_add_refreshed_at_to_two_factors.rb │ ├── 20141015034040_add_nickname_to_authentications.rb │ ├── 20140418082715_add_sum_to_proofs.rb │ ├── 20140721125900_remove_column_verified_from_id_documents.rb │ ├── 20140724033014_add_trusted_ip_list_to_api_tokens.rb │ ├── 20140804002557_add_api_disabled_to_members.rb │ ├── 20140819090417_add_index_on_orders_member_id_and_state.rb │ ├── 20130926170008_change_ref_to_text_in_account_versions.rb │ ├── 20130928122042_rename_account_logs_to_account_versions.rb │ ├── 20140703065321_add_order_id_indices_to_trades.rb │ ├── 20131001103847_add_deleted_at_to_withdraw_addresses.rb │ ├── 20140416151403_add_phone_number_verified_to_members.rb │ ├── 20140421061712_add_index_on_accounts.rb │ ├── 20141003061259_add_txout_to_deposits.rb │ ├── 20141010083930_remove_phone_number_verified_from_members.rb │ ├── 20130912144526_add_receive_at_to_payment_transactions.rb │ ├── 20131110214254_add_currency_to_payment_transactions.rb │ ├── 20140324060148_rename_withdraw_addresses_to_fund_sources.rb │ ├── 20140329070543_remove_channel_id.rb │ ├── 20140331084541_fund_sources_is_locked_default_to_false.rb │ ├── 20140407011310_add_source_to_orders.rb │ ├── 20141003040822_add_payment_transaction_id_to_deposits.rb │ ├── 20141012124243_set_token_is_used_to_false_as_default.rb │ ├── 20140327065708_rename_fund_sources_category_to_channel_id.rb │ ├── 20130928194048_add_alipay_address_to_members.rb │ ├── 20140101175408_add_fee_to_account_versions.rb │ ├── 20140703070953_add_funds_received_to_orders.rb │ ├── 20140303080054_rename_is_active_to_activated.rb │ ├── 20140806141035_add_index_to_orders.rb │ ├── 20140405053744_remove_withdraws_state_and_channel_id.rb │ ├── 20140804151249_change_default_of_withdrao_fee.rb │ ├── 20140718141345_rename_id_documents_column_from_sn_to_id_document_number.rb │ ├── 20140718134132_rename_id_documents_column_category_to_id_document_type.rb │ ├── 20130928113620_delete_table_account_versions.rb │ ├── 20141002075102_add_tx_out_to_payment_transactions.rb │ ├── 20140715040545_remove_name_field_from_members_table.rb │ ├── 20131022035138_add_in_out_to_accounts.rb │ ├── 20140530133210_add_locked_to_orders.rb │ ├── 20130925171856_change_to_enumerize_in_accounts.rb │ ├── 20131130190923_remove_pin_digest_from_identities.rb │ ├── 20141107031140_add_deleted_at_to_api_tokens_and_oauth_tokens.rb │ ├── 20130906073020_create_payment_addresses.rb │ ├── 20140709085158_create_comments.rb │ ├── 20130929012418_create_invitations.rb │ ├── 20140319022302_create_proofs.rb │ ├── 20130928190156_rename_member_id_to_identity_id.rb │ ├── 20130930183833_migrate_withdraw_addresses.rb │ ├── 20140717033231_add_assets_table.rb │ ├── 20131009132505_create_documents.rb │ ├── 20141105090746_add_oauth_columns_to_api_tokens.rb │ ├── 20140709084906_create_tickets.rb │ ├── 20130905132250_add_balance_to_account_versions.rb │ ├── 20130926011813_change_to_enumerize_in_payment_transactions.rb │ ├── 20140306020939_create_id_documents.rb │ ├── 20140326191837_add_deposit_id_to_payment_transactions.rb │ ├── 20131003003357_add_address_to_deposits.rb │ ├── 20140105034746_drop_reset_passwords.rb │ ├── 20140327062025_add_memo_and_remove_fund_source_to_deposits.rb │ ├── 20131204020953_add_currency_to_account_versions.rb │ ├── 20140302094520_rename_identity_id_to_member_id.rb │ ├── 20130928165236_add_alipay_to_members.rb │ ├── 20140327044440_change_withdraws.rb │ ├── 20131002012809_add_fee_to_withdraws.rb │ ├── 20140404101823_add_ask_member_id_and_bid_member_id_to_trades.rb │ ├── 20140428203350_add_desc_and_keyword_to_documents.rb │ ├── 20130925165804_change_to_enumerize_in_trades.rb │ ├── 20131003021225_rename_txid_to_payment_transactions.rb │ ├── 20140304015055_create_documents_translations.rb │ ├── 20130907124647_create_deposits.rb │ ├── 20130907110146_create_withdraws.rb │ ├── 20130925175113_change_to_enumerize_in_deposits.rb │ ├── 20130926014845_change_to_enumerize_in_withdraws.rb │ ├── 20131002190141_rebuild_deposits.rb │ ├── 20130906073931_create_payment_transactions.rb │ ├── 20131201011127_drop_reset_pins.rb │ ├── 20140402043033_create_partial_trees.rb │ ├── 20140403070840_add_type_to_withdraws.rb │ ├── 20140902112641_create_simple_captcha_data.rb │ ├── 20140320142701_create_versions.rb │ ├── 20131006183340_create_tokens.rb │ ├── 20140302161905_create_authentications.rb │ ├── 20140920062130_add_type_to_payment_transactions.rb │ ├── 20140715002401_add_more_fields_to_id_documents_table.rb │ ├── 20131027012836_change_in_out_to_accounts.rb │ ├── 20140403031847_create_api_tokens.rb │ ├── 20140326170234_change_deposits.rb │ ├── 20140714143823_unread_migration.rb │ ├── 20130901010953_create_orders.rb │ ├── 20141119155043_create_running_accounts.rb │ ├── 20140707115022_create_audit_logs.rb │ └── 20130629015414_create_identities.rb ├── .travis.markets.yml ├── config.ru ├── script └── pre-commit.sh ├── CHANGELOG.md ├── .travis.database.yml ├── Rakefile ├── .travis.currencies.yml └── .tx └── config /lib/tasks/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/mailers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --colour 2 | --profile 3 | -------------------------------------------------------------------------------- /app/assets/javascripts/helpers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/private/markets/_status.html.slim: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/initializers/withdraw_blacklist.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/javascripts/funds/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/stylesheets/custom/market.css.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/stylesheets/features/_custom.css.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/stylesheets/vars/_custom.css.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/stylesheets/market_light.css.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/assets/stylesheets/vars/_market.css.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/assets/stylesheets/vars/_market_light.css.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/javascripts/component_ui/range_switch.js.coffee: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/api/v1/prices/show.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @price 2 | -------------------------------------------------------------------------------- /app/views/api/v1/trades/show.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @trades 2 | -------------------------------------------------------------------------------- /public/templates/funds/deposits.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /public/templates/funds/withdraws.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /spec/support/i18n_helper.rb: -------------------------------------------------------------------------------- 1 | def t(key) 2 | I18n.t(key) 3 | end 4 | -------------------------------------------------------------------------------- /lib/peatio/version.rb: -------------------------------------------------------------------------------- 1 | module Peatio 2 | VERSION = "0.2.1" 3 | end 4 | -------------------------------------------------------------------------------- /app/views/admin/proofs/index.html.slim: -------------------------------------------------------------------------------- 1 | = datagrid_table @grid, @assets 2 | -------------------------------------------------------------------------------- /public/peatio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/peatio.png -------------------------------------------------------------------------------- /app/assets/javascripts/html5.js: -------------------------------------------------------------------------------- 1 | //= require html5shiv 2 | //= require respond.min 3 | -------------------------------------------------------------------------------- /app/models/two_factor/email.rb: -------------------------------------------------------------------------------- 1 | class TwoFactor::Email < ::TwoFactor 2 | 3 | end 4 | -------------------------------------------------------------------------------- /app/models/two_factor/wechat.rb: -------------------------------------------------------------------------------- 1 | class TwoFactor::Wechat < ::TwoFactor 2 | 3 | end 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/favicon.ico -------------------------------------------------------------------------------- /public/icon-btc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/icon-btc.png -------------------------------------------------------------------------------- /public/icon-cny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/icon-cny.png -------------------------------------------------------------------------------- /public/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/throbber.gif -------------------------------------------------------------------------------- /public/ZeroClipboard.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/ZeroClipboard.swf -------------------------------------------------------------------------------- /public/languages/en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/languages/en.png -------------------------------------------------------------------------------- /public/languages/ko.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/languages/ko.png -------------------------------------------------------------------------------- /app/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/app/assets/images/logo.png -------------------------------------------------------------------------------- /config/locales/custom/server.en.yml: -------------------------------------------------------------------------------- 1 | # Put your customized locale translations here. 2 | 3 | en: 4 | -------------------------------------------------------------------------------- /public/languages/zh-CN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/languages/zh-CN.png -------------------------------------------------------------------------------- /public/sounds/success.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/sounds/success.mp3 -------------------------------------------------------------------------------- /public/sounds/warning.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/sounds/warning.mp3 -------------------------------------------------------------------------------- /app/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/app/assets/images/favicon.ico -------------------------------------------------------------------------------- /app/assets/stylesheets/layouts/_custom.css.scss: -------------------------------------------------------------------------------- 1 | #kline_chart { 2 | .panel-body { padding: 0; } 3 | } 4 | -------------------------------------------------------------------------------- /config/locales/custom/server.zh-CN.yml: -------------------------------------------------------------------------------- 1 | # Put your customized locale translations here. 2 | 3 | zh-CN: 4 | -------------------------------------------------------------------------------- /spec/routing/admin/members_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe '/admin/members' do 4 | end 5 | -------------------------------------------------------------------------------- /app/assets/javascripts/locales/en.js.erb: -------------------------------------------------------------------------------- 1 | //= require i18n 2 | <%= JsLocaleHelper.output_locale(:en) %> 3 | 4 | -------------------------------------------------------------------------------- /app/views/admin/documents/edit.html.slim: -------------------------------------------------------------------------------- 1 | .row 2 | .col-xs-12 3 | = render 'form', document: @document 4 | -------------------------------------------------------------------------------- /app/views/admin/documents/new.html.slim: -------------------------------------------------------------------------------- 1 | .row 2 | .col-xs-12 3 | = render 'form', document: @document 4 | -------------------------------------------------------------------------------- /app/views/private/markets/_depths.html.slim: -------------------------------------------------------------------------------- 1 | #depths_wrapper 2 | #depths 3 | a.hand-point: i.fa.fa-close 4 | -------------------------------------------------------------------------------- /public/btsx.chongzhi.yunbi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/btsx.chongzhi.yunbi.png -------------------------------------------------------------------------------- /app/views/admin/deposits/index.html.slim: -------------------------------------------------------------------------------- 1 | .row: .col-xs-12 2 | = datagrid_table(@admin_deposits_grid, @assets) 3 | -------------------------------------------------------------------------------- /app/views/api/v1/deeps/show.jbuilder: -------------------------------------------------------------------------------- 1 | json.asks @asks.reverse() 2 | json.bids @bids 3 | json.at DateTime.now.to_i 4 | -------------------------------------------------------------------------------- /app/views/system_mailer/balance_warning.text.erb: -------------------------------------------------------------------------------- 1 | System Balance <%= @balance %> 2 | Withdraw Amount <%= @amount %> 3 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /app/assets/javascripts/locales/zh-CN.js.erb: -------------------------------------------------------------------------------- 1 | //= require i18n 2 | <%= JsLocaleHelper.output_locale(:'zh-CN') %> 3 | 4 | -------------------------------------------------------------------------------- /app/views/errors/connection.html.slim: -------------------------------------------------------------------------------- 1 | h1.text-error CoinRPC::ConnectionRefusedError 2 | p Have you started bitcoind? 3 | -------------------------------------------------------------------------------- /app/views/private/markets/_mask.html.slim: -------------------------------------------------------------------------------- 1 | - unless current_user 2 | .mask 3 | p.text-center == "#{t('.warning')}" 4 | -------------------------------------------------------------------------------- /app/views/shared/_html5.html.slim: -------------------------------------------------------------------------------- 1 | == "" 4 | -------------------------------------------------------------------------------- /public/peatio-notification-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lite/peatio/master/public/peatio-notification-logo.png -------------------------------------------------------------------------------- /app/assets/javascripts/templates/hint_order_success.jst.eco: -------------------------------------------------------------------------------- 1 | <%= @msg %> 2 | 3 | -------------------------------------------------------------------------------- /app/assets/stylesheets/features/_documents.css.scss: -------------------------------------------------------------------------------- 1 | #documents-show { 2 | .panel-body { word-wrap: break-word; } 3 | } 4 | -------------------------------------------------------------------------------- /config/locales/custom/client.en.yml: -------------------------------------------------------------------------------- 1 | # Put your customized locale translations here. 2 | 3 | en: 4 | js: 5 | brand: Peatio 6 | -------------------------------------------------------------------------------- /lib/aasm/locking.rb: -------------------------------------------------------------------------------- 1 | module AASM::Locking 2 | def aasm_write_state(state) 3 | lock! 4 | super(state) 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/models/global_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Global do 4 | let(:global) { Global['btccny'] } 5 | end 6 | 7 | -------------------------------------------------------------------------------- /config/initializers/date_time_format.rb: -------------------------------------------------------------------------------- 1 | Date::DATE_FORMATS[:short] = '%m-%d' 2 | Time::DATE_FORMATS[:default] = "%Y-%m-%d %H:%M:%S" 3 | -------------------------------------------------------------------------------- /config/locales/custom/client.zh-CN.yml: -------------------------------------------------------------------------------- 1 | # Put your customized locale translations here. 2 | 3 | zh-CN: 4 | js: 5 | brand: Peatio 6 | -------------------------------------------------------------------------------- /app/observers/audit_observer.rb: -------------------------------------------------------------------------------- 1 | class AuditObserver < ActiveRecord::Observer 2 | def current_user 3 | Member.current 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/members/edit.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @member do |f| 2 | = f.input :display_name 3 | = f.button :wrapped, t('actions.submit') 4 | -------------------------------------------------------------------------------- /app/controllers/welcome_controller.rb: -------------------------------------------------------------------------------- 1 | class WelcomeController < ApplicationController 2 | layout 'landing' 3 | 4 | def index 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/views/system_mailer/trade_execute_error.text.erb: -------------------------------------------------------------------------------- 1 | Payload: <%= @payload.inspect %> 2 | Exception: <%= @error %> 3 | Backtrace: <%= @backtrace %> 4 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /spec/support/cookie_helper.rb: -------------------------------------------------------------------------------- 1 | def clear_cookie 2 | page.driver.cookies.each do |k, v| 3 | page.driver.remove_cookie k 4 | end 5 | end 6 | 7 | -------------------------------------------------------------------------------- /app/views/admin/deposits/edit.html.slim: -------------------------------------------------------------------------------- 1 | .row 2 | .col-xs-8 3 | .row: .col-xs-12 4 | = render partial: "deposit", locals: {deposit: @deposit} 5 | -------------------------------------------------------------------------------- /config/daemons.yml: -------------------------------------------------------------------------------- 1 | dir_mode: script 2 | dir: ../../log 3 | multiple: false 4 | backtrace: true 5 | monitor: false 6 | ontop: false 7 | log_output: true 8 | -------------------------------------------------------------------------------- /spec/support/two_factor_helper.rb: -------------------------------------------------------------------------------- 1 | def two_factor_unlocked 2 | session[:two_factor_unlock] = true 3 | session[:two_factor_unlock_at] = Time.now 4 | end 5 | -------------------------------------------------------------------------------- /app/views/token_mailer/reset_password.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t(".follow_the_link") %> 3 |

4 | 5 |

6 | <%= link_to @token_url, @token_url%> 7 |

8 | -------------------------------------------------------------------------------- /config/initializers/carrierwave.rb: -------------------------------------------------------------------------------- 1 | CarrierWave.configure do |config| 2 | config.storage = :file 3 | config.cache_dir = "#{Rails.root}/tmp/uploads" 4 | end 5 | -------------------------------------------------------------------------------- /spec/models/partial_tree_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe PartialTree do 4 | pending "add some examples to (or delete) #{__FILE__}" 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/features/_id_document.css.scss: -------------------------------------------------------------------------------- 1 | #id_documents-edit { 2 | .form-control.date { 3 | display: inline; 4 | width: 30%; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /app/views/shared/admin/_member_accounts.html.slim: -------------------------------------------------------------------------------- 1 | - member.accounts.each do |account| 2 | = render partial: 'shared/admin/account', locals: {account: account} 3 | -------------------------------------------------------------------------------- /app/assets/javascripts/funds/filters/translate_filters.js.coffee: -------------------------------------------------------------------------------- 1 | angular.module('translateFilters', []).filter 't', -> 2 | (key, args={}) -> 3 | I18n.t(key, args) 4 | -------------------------------------------------------------------------------- /app/models/bank.rb: -------------------------------------------------------------------------------- 1 | class Bank < ActiveYamlBase 2 | include HashCurrencible 3 | 4 | def self.with_currency(c) 5 | find_all_by_currency c.to_s 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/comment_mailer/user_notification.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t('.notification_content')%> 3 |

4 | 5 |

6 | <%= link_to @ticket_url, @ticket_url %> 7 |

8 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /db/migrate/20130919091853_add_sn_to_orders.rb: -------------------------------------------------------------------------------- 1 | class AddSnToOrders < ActiveRecord::Migration 2 | def change 3 | add_column :orders, :sn, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/admin/statistic/base_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | module Statistic 3 | class BaseController < ::Admin::BaseController 4 | end 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/controllers/concerns/withdraws/ctrl_coinable.rb: -------------------------------------------------------------------------------- 1 | module Withdraws 2 | module CtrlCoinable 3 | extend ActiveSupport::Concern 4 | include Withdrawable 5 | end 6 | end -------------------------------------------------------------------------------- /app/views/shared/market/_chart.html.slim: -------------------------------------------------------------------------------- 1 | .panel.panel-default 2 | .panel-body.market-ticker 3 | = render partial: 'shared/market/ticker' 4 | .panel-body.market-chart 5 | -------------------------------------------------------------------------------- /app/views/ticket_mailer/author_notification.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t('.thanks_for_submit_ticket') %> 3 |

4 | 5 |

6 | <%= link_to @ticket_url, @ticket_url %> 7 |

8 | -------------------------------------------------------------------------------- /config/locales/client.cs.yml: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | # Never edit this file. It will be overwritten when translations are pulled from Transifex. 4 | # 5 | 6 | cs: {} 7 | -------------------------------------------------------------------------------- /config/locales/server.cs.yml: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | # Never edit this file. It will be overwritten when translations are pulled from Transifex. 4 | # 5 | 6 | cs: {} 7 | -------------------------------------------------------------------------------- /spec/factories/documents.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :document do 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /.travis.markets.yml: -------------------------------------------------------------------------------- 1 | - id: btccny 2 | code: 3 3 | base_unit: btc 4 | quote_unit: cny 5 | bid: {fee: 0, currency: cny, fixed: 2} 6 | ask: {fee: 0, currency: btc, fixed: 4} 7 | -------------------------------------------------------------------------------- /app/controllers/concerns/withdraws/ctrl_bankable.rb: -------------------------------------------------------------------------------- 1 | module Withdraws 2 | module CtrlBankable 3 | extend ActiveSupport::Concern 4 | include Withdrawable 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Peatio::Application 5 | -------------------------------------------------------------------------------- /db/migrate/20140328101707_add_type_to_deposits.rb: -------------------------------------------------------------------------------- 1 | class AddTypeToDeposits < ActiveRecord::Migration 2 | def change 3 | add_column :deposits, :type, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140416194209_remove_table_invitations.rb: -------------------------------------------------------------------------------- 1 | class RemoveTableInvitations < ActiveRecord::Migration 2 | def change 3 | drop_table :invitations 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140819085359_add_index_to_order_state.rb: -------------------------------------------------------------------------------- 1 | class AddIndexToOrderState < ActiveRecord::Migration 2 | def change 3 | add_index :orders, :state 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/javascripts/templates/hint_order_warning.jst.eco: -------------------------------------------------------------------------------- 1 | <%= @msg %> 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /db/migrate/20140416194300_remove_table_members_trades.rb: -------------------------------------------------------------------------------- 1 | class RemoveTableMembersTrades < ActiveRecord::Migration 2 | def change 3 | drop_table :members_trades 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/models/member_tag.rb: -------------------------------------------------------------------------------- 1 | class MemberTag < Settingslogic 2 | source "#{Rails.root}/config/member_tag.yml" 3 | namespace Rails.env 4 | suppress_errors Rails.env.production? 5 | end 6 | -------------------------------------------------------------------------------- /app/views/admin/documents/index.html.slim: -------------------------------------------------------------------------------- 1 | .row 2 | .col-xs-12 3 | = datagrid_table(@documents_grid, @assets) 4 | a.btn.btn-primary href='#{new_admin_document_path}' = t('.new') 5 | -------------------------------------------------------------------------------- /app/views/private/api_tokens/index.html.slim: -------------------------------------------------------------------------------- 1 | = content_for :frame do 2 | .container 3 | = render 'shared/flash' 4 | = render 'user_tokens' 5 | = render 'oauth_tokens' 6 | 7 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | Peatio::Application.initialize! 6 | -------------------------------------------------------------------------------- /db/migrate/20131224162832_add_sn_to_withdraws.rb: -------------------------------------------------------------------------------- 1 | class AddSnToWithdraws < ActiveRecord::Migration 2 | def change 3 | add_column :withdraws, :sn, :string, after: :id 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140404074816_add_currency_index_to_trades.rb: -------------------------------------------------------------------------------- 1 | class AddCurrencyIndexToTrades < ActiveRecord::Migration 2 | def change 3 | add_index :trades, :currency 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140421080408_add_type_to_two_factors.rb: -------------------------------------------------------------------------------- 1 | class AddTypeToTwoFactors < ActiveRecord::Migration 2 | def change 3 | add_column :two_factors, :type, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140507120249_add_addresses_to_proofs.rb: -------------------------------------------------------------------------------- 1 | class AddAddressesToProofs < ActiveRecord::Migration 2 | def change 3 | add_column :proofs, :addresses, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140806141419_add_index_to_trades.rb: -------------------------------------------------------------------------------- 1 | class AddIndexToTrades < ActiveRecord::Migration 2 | def change 3 | add_index :trades, :created_at, using: :btree 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140826083906_add_label_to_api_token.rb: -------------------------------------------------------------------------------- 1 | class AddLabelToAPIToken < ActiveRecord::Migration 2 | def change 3 | add_column :api_tokens, :label, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20141014085101_add_nickname_to_members.rb: -------------------------------------------------------------------------------- 1 | class AddNicknameToMembers < ActiveRecord::Migration 2 | def change 3 | add_column :members, :nickname, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/deposit/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Explain the generator 3 | 4 | Example: 5 | rails generate deposit Thing 6 | 7 | This will create: 8 | what/will/it/create 9 | -------------------------------------------------------------------------------- /script/pre-commit.sh: -------------------------------------------------------------------------------- 1 | git stash -q --keep-index 2 | echo 'running all tests...' 3 | rspec spec 4 | echo 'done' 5 | RESULT=$? 6 | git stash pop -q 7 | [ $RESULT -ne 0 ] && exit 1 8 | exit 0 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | * Add visible attribute to market and default visible is true 2 | * I18n translations for Email template 3 | * Put Our Mission and Features into README.md 4 | * Add CHANGELOG.md 5 | -------------------------------------------------------------------------------- /app/views/comment_mailer/admin_notification.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t('.notification_content', email: @author_email)%> 3 |

4 | 5 |

6 | <%= link_to @ticket_url, @ticket_url %> 7 |

8 | -------------------------------------------------------------------------------- /app/views/member_mailer/notify_signin.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t(".just_signed_in") %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /app/views/member_mailer/reset_password_done.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t(".successful") %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /app/views/reset_passwords/edit.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @token, url: reset_password_path(@token), as: :reset_password do |f| 2 | = f.input :password 3 | hr.split 4 | = f.button :wrapped 5 | -------------------------------------------------------------------------------- /app/views/ticket_mailer/admin_notification.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t('.admin_notification_content', email: @author_email)%> 3 |

4 | 5 |

6 | <%=link_to @ticket_url, @ticket_url %> 7 |

8 | -------------------------------------------------------------------------------- /db/migrate/20140303060739_add_activated_to_members.rb: -------------------------------------------------------------------------------- 1 | class AddActivatedToMembers < ActiveRecord::Migration 2 | def change 3 | add_column :members, :activated, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140702035833_add_balance_to_proofs.rb: -------------------------------------------------------------------------------- 1 | class AddBalanceToProofs < ActiveRecord::Migration 2 | def change 3 | add_column :proofs, :balance, :string, limit: 30 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/deposit/templates/model.rb.erb: -------------------------------------------------------------------------------- 1 | module Deposits 2 | class <%= class_name %> < ::Deposit 3 | include ::AasmAbsolutely 4 | include ::Deposits::Coinable 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/generators/withdraw/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Explain the generator 3 | 4 | Example: 5 | rails generate deposit Thing 6 | 7 | This will create: 8 | what/will/it/create 9 | -------------------------------------------------------------------------------- /app/models/withdraws/bank.rb: -------------------------------------------------------------------------------- 1 | module Withdraws 2 | class Bank < ::Withdraw 3 | include ::AasmAbsolutely 4 | include ::Withdraws::Bankable 5 | include ::FundSourceable 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/member_mailer/sms_auth_activated.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t(".sms_auth_activated") %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /app/views/private/markets/_chat.html.slim: -------------------------------------------------------------------------------- 1 | #chat.panel.panel-default 2 | .panel-heading 3 | span = t('.title') 4 | a.hand-point.pull-right: i.fa.fa-close 5 | .panel-body.panel-body-content 6 | -------------------------------------------------------------------------------- /app/views/shared/_meta.html.slim: -------------------------------------------------------------------------------- 1 | title = i18n_meta('page_title') 2 | 3 | meta name='description' content=i18n_meta('page_description') 4 | meta name='keywords' content=i18n_meta('page_keywords') 5 | -------------------------------------------------------------------------------- /db/migrate/20130915150504_add_payment_id_to_withdraws.rb: -------------------------------------------------------------------------------- 1 | class AddPaymentIdToWithdraws < ActiveRecord::Migration 2 | def change 3 | add_column :withdraws, :payment_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130918143551_add_ref_to_account_versions.rb: -------------------------------------------------------------------------------- 1 | class AddRefToAccountVersions < ActiveRecord::Migration 2 | def change 3 | add_column :account_versions, :ref, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140312061206_add_aasm_state_to_withdraws.rb: -------------------------------------------------------------------------------- 1 | class AddAasmStateToWithdraws < ActiveRecord::Migration 2 | def change 3 | add_column :withdraws, :aasm_state, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140416143352_add_phone_number_to_members.rb: -------------------------------------------------------------------------------- 1 | class AddPhoneNumberToMembers < ActiveRecord::Migration 2 | def change 3 | add_column :members, :phone_number, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140524014413_add_ord_type_to_orders.rb: -------------------------------------------------------------------------------- 1 | class AddOrdTypeToOrders < ActiveRecord::Migration 2 | def change 3 | add_column :orders, :ord_type, :string, limit: 10 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/withdraw/templates/model.rb.erb: -------------------------------------------------------------------------------- 1 | module Withdraws 2 | class <%= class_name %> < ::Withdraw 3 | include ::AasmAbsolutely 4 | include ::Withdraws::Coinable 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/controllers/admin/dashboard_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class DashboardController < BaseController 3 | skip_load_and_authorize_resource 4 | 5 | def index 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/mailers/deposit_mailer.rb: -------------------------------------------------------------------------------- 1 | class DepositMailer < BaseMailer 2 | 3 | def accepted(deposit_id) 4 | @deposit = Deposit.find deposit_id 5 | mail to: @deposit.member.email 6 | end 7 | 8 | end 9 | -------------------------------------------------------------------------------- /app/models/withdraws/satoshi.rb: -------------------------------------------------------------------------------- 1 | module Withdraws 2 | class Satoshi < ::Withdraw 3 | include ::AasmAbsolutely 4 | include ::Withdraws::Coinable 5 | include ::FundSourceable 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/member_mailer/sms_auth_deactivated.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t(".sms_auth_deactivated") %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /app/views/reset_passwords/new.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @token, url: reset_passwords_path, as: :reset_password do |f| 2 | = f.input :email 3 | hr.split 4 | = f.button :wrapped, cancel: signin_path 5 | -------------------------------------------------------------------------------- /db/migrate/20130904215802_add_is_active_to_two_factors.rb: -------------------------------------------------------------------------------- 1 | class AddIsActiveToTwoFactors < ActiveRecord::Migration 2 | def change 3 | add_column :two_factors, :is_active, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140102024125_add_fun_to_account_versions.rb: -------------------------------------------------------------------------------- 1 | class AddFunToAccountVersions < ActiveRecord::Migration 2 | def change 3 | add_column :account_versions, :fun, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140306021833_add_verified_to_id_documents.rb: -------------------------------------------------------------------------------- 1 | class AddVerifiedToIdDocuments < ActiveRecord::Migration 2 | def change 3 | add_column :id_documents, :verified, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140319022202_add_partial_tree_to_accounts.rb: -------------------------------------------------------------------------------- 1 | class AddPartialTreeToAccounts < ActiveRecord::Migration 2 | def change 3 | add_column :accounts, :partial_tree, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140327105217_remove_fund_sources_account_id.rb: -------------------------------------------------------------------------------- 1 | class RemoveFundSourcesAccountId < ActiveRecord::Migration 2 | def change 3 | remove_column :fund_sources, :account_id 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140416143239_add_country_code_to_members.rb: -------------------------------------------------------------------------------- 1 | class AddCountryCodeToMembers < ActiveRecord::Migration 2 | def change 3 | add_column :members, :country_code, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/api/api_v2/entities/order_book.rb: -------------------------------------------------------------------------------- 1 | module APIv2 2 | module Entities 3 | class OrderBook < Base 4 | expose :asks, using: Order 5 | expose :bids, using: Order 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/controllers/private/withdraws/banks_controller.rb: -------------------------------------------------------------------------------- 1 | module Private::Withdraws 2 | class BanksController < ::Private::Withdraws::BaseController 3 | include ::Withdraws::CtrlBankable 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/member_mailer/google_auth_activated.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t(".google_auth_activated") %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /app/views/member_mailer/google_auth_deactivated.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t(".google_auth_deactivated") %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /config/nginx_maintenance.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default; 3 | server_name _; 4 | 5 | root /home/deploy/peatio/current/public; 6 | 7 | location / { 8 | index 502.html; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /db/migrate/20130905025823_fix_account_id_by_reset_pin.rb: -------------------------------------------------------------------------------- 1 | class FixAccountIdByResetPin < ActiveRecord::Migration 2 | def change 3 | rename_column :reset_pins, :account_id, :member_id 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20131208012814_fix_payment_address_currecny.rb: -------------------------------------------------------------------------------- 1 | class FixPaymentAddressCurrecny < ActiveRecord::Migration 2 | def change 3 | add_column :payment_addresses, :currency, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140312071704_add_sum_to_withdraws.rb: -------------------------------------------------------------------------------- 1 | class AddSumToWithdraws < ActiveRecord::Migration 2 | def change 3 | add_column :withdraws, :sum, :decimal, precision: 32, scale: 16 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140712030803_add_disabled_to_members.rb: -------------------------------------------------------------------------------- 1 | class AddDisabledToMembers < ActiveRecord::Migration 2 | def change 3 | add_column :members, :disabled, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140715083857_add_aasm_state_to_id_document.rb: -------------------------------------------------------------------------------- 1 | class AddAasmStateToIdDocument < ActiveRecord::Migration 2 | def change 3 | add_column :id_documents, :aasm_state, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /public/templates/funds/_qrcode.html: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /app/controllers/private/withdraws/satoshis_controller.rb: -------------------------------------------------------------------------------- 1 | module Private::Withdraws 2 | class SatoshisController < ::Private::Withdraws::BaseController 3 | include ::Withdraws::CtrlCoinable 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/deposit_mailer/accepted.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t('.content', currency: @deposit.currency_text) %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /app/views/private/markets/_candlestick.html.slim: -------------------------------------------------------------------------------- 1 | #candlestick 2 | #candlestick_chart style='height: 100%;' 3 | .mask: table: tr: td.text-center 4 | i.fa.fa-refresh.fa-spin.fa-1x 5 | span Loading ... 6 | -------------------------------------------------------------------------------- /app/views/withdraw_mailer/done.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t('.content', currency: @withdraw.currency_text) %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | Peatio::Application.config.secret_key_base = '4adeecaaba6c4a5474d9c8d7893dd1f4243abdcd58187d8e628d3cf0be1855b5f0b780f63de790e8eb3fde4ba032b4d183ce623ed321c296382d7946826fcc5e' 2 | -------------------------------------------------------------------------------- /db/migrate/20140531054739_add_used_funds_to_trades.rb: -------------------------------------------------------------------------------- 1 | class AddUsedFundsToTrades < ActiveRecord::Migration 2 | def change 3 | add_column :trades, :funds, :decimal, precision: 32, scale: 16 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140618004355_add_displayname_to_members.rb: -------------------------------------------------------------------------------- 1 | class AddDisplaynameToMembers < ActiveRecord::Migration 2 | def change 3 | add_column :members, :display_name, :string, after: :name 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140803202610_remove_channel_id_from_fund_sources.rb: -------------------------------------------------------------------------------- 1 | class RemoveChannelIdFromFundSources < ActiveRecord::Migration 2 | def change 3 | remove_column :fund_sources, :channel_id 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140826093508_add_refreshed_at_to_two_factors.rb: -------------------------------------------------------------------------------- 1 | class AddRefreshedAtToTwoFactors < ActiveRecord::Migration 2 | def change 3 | add_column :two_factors, :refreshed_at, :timestamp 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20141015034040_add_nickname_to_authentications.rb: -------------------------------------------------------------------------------- 1 | class AddNicknameToAuthentications < ActiveRecord::Migration 2 | def change 3 | add_column :authentications, :nickname, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories/api_tokens.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :api_token do 5 | member 6 | scopes 'all' 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/assets/javascripts/component_mixin/notification.js.coffee: -------------------------------------------------------------------------------- 1 | @NotificationMixin = -> 2 | @notify = (body, title) -> 3 | title ||= gon.i18n.notification.title 4 | notification = notifier.notify(title, body) 5 | -------------------------------------------------------------------------------- /app/controllers/api/v1/base_controller.rb: -------------------------------------------------------------------------------- 1 | module API 2 | module V1 3 | class BaseController < ::ApplicationController 4 | skip_before_filter :set_language, :setting_default 5 | end 6 | end 7 | end 8 | 9 | -------------------------------------------------------------------------------- /app/views/private/history/_tabs.html.slim: -------------------------------------------------------------------------------- 1 | ul.nav.nav-pills role='tablist' 2 | - tabs.each do |name, args| 3 | - css_class = name == active ? 'active' : '' 4 | li class=css_class = link_to t(args[0]), args[1] 5 | -------------------------------------------------------------------------------- /app/views/withdraw_mailer/processing.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t('.content', currency: @withdraw.currency_text) %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /app/views/withdraw_mailer/submitted.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t('.content', currency: @withdraw.currency_text) %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /config/member_tag.yml: -------------------------------------------------------------------------------- 1 | defaults: &defaults 2 | tags: 3 | - vip 4 | - hero 5 | 6 | development: 7 | <<: *defaults 8 | 9 | test: 10 | <<: *defaults 11 | 12 | production: 13 | <<: *defaults 14 | -------------------------------------------------------------------------------- /db/migrate/20140418082715_add_sum_to_proofs.rb: -------------------------------------------------------------------------------- 1 | class AddSumToProofs < ActiveRecord::Migration 2 | def change 3 | add_column :proofs, :sum, :string 4 | add_column :partial_trees, :sum, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20140721125900_remove_column_verified_from_id_documents.rb: -------------------------------------------------------------------------------- 1 | class RemoveColumnVerifiedFromIdDocuments < ActiveRecord::Migration 2 | def change 3 | remove_column :id_documents, :verified 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140724033014_add_trusted_ip_list_to_api_tokens.rb: -------------------------------------------------------------------------------- 1 | class AddTrustedIpListToAPITokens < ActiveRecord::Migration 2 | def change 3 | add_column :api_tokens, :trusted_ip_list, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140804002557_add_api_disabled_to_members.rb: -------------------------------------------------------------------------------- 1 | class AddAPIDisabledToMembers < ActiveRecord::Migration 2 | def change 3 | add_column :members, :api_disabled, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140819090417_add_index_on_orders_member_id_and_state.rb: -------------------------------------------------------------------------------- 1 | class AddIndexOnOrdersMemberIdAndState < ActiveRecord::Migration 2 | def change 3 | add_index :orders, [:member_id, :state] 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories/proofs.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :proof do 5 | root "MyString" 6 | state "MyString" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/pusher.rb: -------------------------------------------------------------------------------- 1 | # stub pusher requests 2 | 3 | class Pusher::Client 4 | def trigger_async(*args) 5 | end 6 | end 7 | 8 | class Pusher::Channel 9 | def trigger_async(*args) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/models/deposits/satoshi.rb: -------------------------------------------------------------------------------- 1 | module Deposits 2 | class Satoshi < ::Deposit 3 | include ::AasmAbsolutely 4 | include ::Deposits::Coinable 5 | 6 | validates_uniqueness_of :txout, scope: :txid 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/views/withdraw_mailer/withdraw_state.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t(".your_state") %> 3 | <%= @withdraw.aasm_state %> 4 |

5 | 6 |

7 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 8 |

9 | -------------------------------------------------------------------------------- /config/initializers/activerecord.rb: -------------------------------------------------------------------------------- 1 | module ActiveModel 2 | module Translation 3 | alias :han :human_attribute_name 4 | end 5 | end 6 | 7 | ActiveRecord::Base.extend ActiveHash::Associations::ActiveRecordExtensions 8 | -------------------------------------------------------------------------------- /db/migrate/20130926170008_change_ref_to_text_in_account_versions.rb: -------------------------------------------------------------------------------- 1 | class ChangeRefToTextInAccountVersions < ActiveRecord::Migration 2 | def change 3 | change_column :account_versions, :ref, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130928122042_rename_account_logs_to_account_versions.rb: -------------------------------------------------------------------------------- 1 | class RenameAccountLogsToAccountVersions < ActiveRecord::Migration 2 | def change 3 | rename_table :account_logs, :account_versions 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140703065321_add_order_id_indices_to_trades.rb: -------------------------------------------------------------------------------- 1 | class AddOrderIdIndicesToTrades < ActiveRecord::Migration 2 | def change 3 | add_index :trades, :ask_id 4 | add_index :trades, :bid_id 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/controllers/admin/members_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Admin::MembersController do 4 | let(:member) { create(:admin_member) } 5 | before { session[:member_id] = member.id } 6 | 7 | end 8 | -------------------------------------------------------------------------------- /app/views/identities/edit.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @identity do |f| 2 | = f.input :old_password 3 | = f.input :password 4 | = f.input :password_confirmation 5 | hr.split 6 | = f.button :wrapped, cancel: settings_path 7 | -------------------------------------------------------------------------------- /app/views/member_mailer/phone_number_verified.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t(".verified", phone_number: @member.phone_number) %> 3 |

4 | 5 |

6 | <%= raw t("mailer.please_contact", contact_mail: ENV['SUPPORT_MAIL']) %> 7 |

8 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /db/migrate/20131001103847_add_deleted_at_to_withdraw_addresses.rb: -------------------------------------------------------------------------------- 1 | class AddDeletedAtToWithdrawAddresses < ActiveRecord::Migration 2 | def change 3 | add_column :withdraw_addresses, :deleted_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140416151403_add_phone_number_verified_to_members.rb: -------------------------------------------------------------------------------- 1 | class AddPhoneNumberVerifiedToMembers < ActiveRecord::Migration 2 | def change 3 | add_column :members, :phone_number_verified, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140421061712_add_index_on_accounts.rb: -------------------------------------------------------------------------------- 1 | class AddIndexOnAccounts < ActiveRecord::Migration 2 | def change 3 | add_index :accounts, [:member_id, :currency] 4 | add_index :accounts, :member_id 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20141003061259_add_txout_to_deposits.rb: -------------------------------------------------------------------------------- 1 | class AddTxoutToDeposits < ActiveRecord::Migration 2 | def change 3 | add_column :deposits, :txout, :integer 4 | add_index :deposits, [:txid, :txout] 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20141010083930_remove_phone_number_verified_from_members.rb: -------------------------------------------------------------------------------- 1 | class RemovePhoneNumberVerifiedFromMembers < ActiveRecord::Migration 2 | def change 3 | remove_column :members, :phone_number_verified 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/controllers/reset_password_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe ResetPasswordsController do 4 | before do 5 | get :new 6 | end 7 | 8 | it { expect(response).to be_ok } 9 | 10 | end 11 | -------------------------------------------------------------------------------- /spec/factories/id_document.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :id_document do 3 | name { Faker::Name.name } 4 | id_document_type :id_card 5 | id_document_number { Faker::Number.number(15).to_s } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/controllers/private/deposits/banks_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | module Deposits 3 | class BanksController < ::Private::Deposits::BaseController 4 | include ::Deposits::CtrlBankable 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/models/audit/audit_log.rb: -------------------------------------------------------------------------------- 1 | module Audit 2 | class AuditLog < ActiveRecord::Base 3 | belongs_to :operator, class_name: 'Member', foreign_key: 'operator_id' 4 | belongs_to :auditable, polymorphic: true 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/models/partial_tree.rb: -------------------------------------------------------------------------------- 1 | class PartialTree < ActiveRecord::Base 2 | 3 | belongs_to :account 4 | belongs_to :proof 5 | 6 | serialize :json, JSON 7 | validates_presence_of :proof_id, :account_id, :json 8 | 9 | end 10 | -------------------------------------------------------------------------------- /app/views/admin/members/toggle.js.erb: -------------------------------------------------------------------------------- 1 | $('#member-<%= @member.id %> a.toggle-web').text('<%= @member.disabled? ? 'Yes' : 'No' %>'); 2 | $('#member-<%= @member.id %> a.toggle-api').text('<%= @member.api_disabled? ? 'Yes' : 'No' %>'); 3 | -------------------------------------------------------------------------------- /db/migrate/20130912144526_add_receive_at_to_payment_transactions.rb: -------------------------------------------------------------------------------- 1 | class AddReceiveAtToPaymentTransactions < ActiveRecord::Migration 2 | def change 3 | add_column :payment_transactions, :receive_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20131110214254_add_currency_to_payment_transactions.rb: -------------------------------------------------------------------------------- 1 | class AddCurrencyToPaymentTransactions < ActiveRecord::Migration 2 | def change 3 | add_column :payment_transactions, :currency, :integer 4 | end 5 | end 6 | 7 | -------------------------------------------------------------------------------- /db/migrate/20140324060148_rename_withdraw_addresses_to_fund_sources.rb: -------------------------------------------------------------------------------- 1 | class RenameWithdrawAddressesToFundSources < ActiveRecord::Migration 2 | def change 3 | rename_table :withdraw_addresses, :fund_sources 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140329070543_remove_channel_id.rb: -------------------------------------------------------------------------------- 1 | class RemoveChannelId < ActiveRecord::Migration 2 | def change 3 | remove_column :deposits, :channel_id 4 | remove_column :payment_transactions, :channel_id 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20140331084541_fund_sources_is_locked_default_to_false.rb: -------------------------------------------------------------------------------- 1 | class FundSourcesIsLockedDefaultToFalse < ActiveRecord::Migration 2 | def change 3 | change_column_default :fund_sources, :is_locked, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140407011310_add_source_to_orders.rb: -------------------------------------------------------------------------------- 1 | class AddSourceToOrders < ActiveRecord::Migration 2 | def change 3 | add_column :orders, :source, :string, null: false 4 | Order.update_all(source: 'Web') 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20141003040822_add_payment_transaction_id_to_deposits.rb: -------------------------------------------------------------------------------- 1 | class AddPaymentTransactionIdToDeposits < ActiveRecord::Migration 2 | def change 3 | add_column :deposits, :payment_transaction_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20141012124243_set_token_is_used_to_false_as_default.rb: -------------------------------------------------------------------------------- 1 | class SetTokenIsUsedToFalseAsDefault < ActiveRecord::Migration 2 | def change 3 | change_column :tokens, :is_used, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/daemons/k_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | Daemons::Rails.run config[:script], config.to_hash 7 | -------------------------------------------------------------------------------- /spec/factories/tickets.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :ticket do 5 | sequence(:content) { |n| "Content #{n}" } 6 | author 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /.travis.database.yml: -------------------------------------------------------------------------------- 1 | test: 2 | adapter: mysql2 3 | database: peatio_test 4 | username: root 5 | encoding: utf8 6 | cucumber: 7 | adapter: mysql2 8 | database: peatio_test 9 | username: root 10 | encoding: utf8 11 | -------------------------------------------------------------------------------- /app/assets/javascripts/admin.js: -------------------------------------------------------------------------------- 1 | //= require jquery 2 | //= require jquery_ujs 3 | //= require bootstrap 4 | //= require bootstrap-wysihtml5/b3 5 | //= require bootstrap-datetimepicker 6 | //= require ZeroClipboard 7 | //= require admin/app 8 | -------------------------------------------------------------------------------- /app/controllers/private/deposits/satoshis_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | module Deposits 3 | class SatoshisController < ::Private::Deposits::BaseController 4 | include ::Deposits::CtrlCoinable 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20140327065708_rename_fund_sources_category_to_channel_id.rb: -------------------------------------------------------------------------------- 1 | class RenameFundSourcesCategoryToChannelId < ActiveRecord::Migration 2 | def change 3 | rename_column :fund_sources, :category, :channel_id 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/daemons/stats_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | Daemons::Rails.run config[:script], config.to_hash 7 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /app/api/api_v2/entities/base.rb: -------------------------------------------------------------------------------- 1 | module APIv2 2 | module Entities 3 | class Base < Grape::Entity 4 | format_with(:iso8601) {|t| t.iso8601 if t } 5 | format_with(:decimal) {|d| d.to_s('F') if d } 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/controllers/api/v1/tickers_controller.rb: -------------------------------------------------------------------------------- 1 | module API 2 | module V1 3 | class TickersController < BaseController 4 | def show 5 | @ticker = Global[params[:id]].ticker 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/models/concerns/hash_currencible.rb: -------------------------------------------------------------------------------- 1 | module HashCurrencible 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | def currency_obj 6 | Currency.find_by_code(attributes[:currency]) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130928194048_add_alipay_address_to_members.rb: -------------------------------------------------------------------------------- 1 | class AddAlipayAddressToMembers < ActiveRecord::Migration 2 | def change 3 | add_column :members, :alipay, :string 4 | add_column :members, :state, :integer 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20140101175408_add_fee_to_account_versions.rb: -------------------------------------------------------------------------------- 1 | class AddFeeToAccountVersions < ActiveRecord::Migration 2 | def change 3 | add_column :account_versions, :fee, :decimal, precision: 32, scale: 16, after: :locked 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20140703070953_add_funds_received_to_orders.rb: -------------------------------------------------------------------------------- 1 | class AddFundsReceivedToOrders < ActiveRecord::Migration 2 | def change 3 | add_column :orders, :funds_received, :decimal, precision: 32, scale: 16, default: 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/daemons/hot_wallets_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | Daemons::Rails.run config[:script], config.to_hash 7 | -------------------------------------------------------------------------------- /lib/daemons/websocket_api_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | Daemons::Rails.run config[:script], config.to_hash -------------------------------------------------------------------------------- /app/assets/stylesheets/features/_history.css.scss: -------------------------------------------------------------------------------- 1 | #history-transactions { 2 | #transactions { 3 | th { 4 | text-transform: capitalize; 5 | } 6 | 7 | th, a { 8 | cursor: pointer; 9 | } 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /app/views/shared/_document.html.slim: -------------------------------------------------------------------------------- 1 | #document_modal.modal.hide.fade tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" 2 | .modal-body 3 | .modal-footer: a.close data-dismiss='modal' aria-hidden='true' = t('.close') 4 | -------------------------------------------------------------------------------- /db/migrate/20140303080054_rename_is_active_to_activated.rb: -------------------------------------------------------------------------------- 1 | class RenameIsActiveToActivated < ActiveRecord::Migration 2 | def change 3 | change_table :two_factors do |t| 4 | t.rename :is_active, :activated 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20140806141035_add_index_to_orders.rb: -------------------------------------------------------------------------------- 1 | class AddIndexToOrders < ActiveRecord::Migration 2 | def change 3 | add_index :orders, :member_id, using: :btree 4 | add_index :orders, [:currency, :state], using: :btree 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/daemons/global_state_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | Daemons::Rails.run config[:script], config.to_hash 7 | -------------------------------------------------------------------------------- /lib/daemons/withdraw_audit_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | Daemons::Rails.run config[:script], config.to_hash 7 | -------------------------------------------------------------------------------- /app/api/api_v2/markets.rb: -------------------------------------------------------------------------------- 1 | module APIv2 2 | class Markets < Grape::API 3 | 4 | desc 'Get all available markets.' 5 | get "/markets" do 6 | present Market.all, with: APIv2::Entities::Market 7 | end 8 | 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/models/concerns/aasm_absolutely.rb: -------------------------------------------------------------------------------- 1 | module AasmAbsolutely 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | enumerize :aasm_state, in: self.superclass::STATES, scope: true, i18n_scope: "#{name.underscore}.aasm_state" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/two_factors/index.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @two_factor, url: two_factor_path(@two_factor.class.to_s.demodulize.downcase) do |f| 2 | 3 | = two_factor_tag(current_user) 4 | 5 | = f.button :wrapped, t('.verify'), cancel: settings_path 6 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /db/migrate/20140405053744_remove_withdraws_state_and_channel_id.rb: -------------------------------------------------------------------------------- 1 | class RemoveWithdrawsStateAndChannelId < ActiveRecord::Migration 2 | def change 3 | remove_column :withdraws, :channel_id 4 | remove_column :withdraws, :state 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20140804151249_change_default_of_withdrao_fee.rb: -------------------------------------------------------------------------------- 1 | class ChangeDefaultOfWithdraoFee < ActiveRecord::Migration 2 | def change 3 | change_column :withdraws, :sum, :decimal, precision: 32, scale: 16, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/daemons/payment_transaction_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | Daemons::Rails.run config[:script], config.to_hash 7 | -------------------------------------------------------------------------------- /spec/factories/partial_trees.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :partial_tree do 5 | json "MyText" 6 | proof_id 1 7 | account_id 1 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/assets/javascripts/lib/pusher_connection.js.coffee: -------------------------------------------------------------------------------- 1 | pusher = new Pusher gon.pusher.key, 2 | encrypted: gon.pusher.encrypted 3 | wsHost: gon.pusher.wsHost 4 | wsPort: gon.pusher.wsPort 5 | wssPort: gon.pusher.wssPort 6 | 7 | window.pusher = pusher 8 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password, :pin] 5 | -------------------------------------------------------------------------------- /config/slack.yml.example: -------------------------------------------------------------------------------- 1 | staging: &defaults 2 | payload: 3 | channel: '#peatio' 4 | username: minabot 5 | token: ~ 6 | hook_url: https://peatio.slack.com/services/hooks/incoming-webhook?token= 7 | 8 | production: 9 | <<: *defaults 10 | -------------------------------------------------------------------------------- /lib/daemons/daemons: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | results = [] 3 | Dir[File.dirname(__FILE__) + "/*_ctl"].each {|f| results << `ruby #{f} #{ARGV.first}`} 4 | results.delete_if { |result| result.nil? || result.empty? } 5 | puts results.join unless results.empty? 6 | -------------------------------------------------------------------------------- /lib/generators/deposit/templates/controller.rb.erb: -------------------------------------------------------------------------------- 1 | module Private 2 | module Deposits 3 | class <%= name.camelize.pluralize %>Controller < ::Private::Deposits::BaseController 4 | include ::Deposits::CtrlCoinable 5 | end 6 | end 7 | end 8 | 9 | -------------------------------------------------------------------------------- /lib/generators/withdraw/templates/controller.rb.erb: -------------------------------------------------------------------------------- 1 | module Private 2 | module Withdraws 3 | class <%= name.camelize.pluralize %>Controller < ::Private::Withdraws::BaseController 4 | include ::Withdraws::CtrlCoinable 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /public/templates/funds/_flash.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /spec/factories/token.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :token do 3 | member 4 | end 5 | 6 | factory :activation, class: Token::Activation, parent: :token 7 | factory :reset_password, class: Token::ResetPassword, parent: :token 8 | end 9 | -------------------------------------------------------------------------------- /app/api/api_v2/entities/account.rb: -------------------------------------------------------------------------------- 1 | module APIv2 2 | module Entities 3 | class Account < Base 4 | expose :currency 5 | expose :balance, format_with: :decimal 6 | expose :locked, format_with: :decimal 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/views/token_mailer/activation.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= t(".click_to_verify") %> 3 |

4 | 5 |

6 | <%= link_to @token_url, @token_url %> 7 |

8 | 9 |

10 | <%= t(".unable_to_click") %> 11 |
12 | <%= t(".link_expire") %> 13 |

14 | -------------------------------------------------------------------------------- /db/migrate/20140718141345_rename_id_documents_column_from_sn_to_id_document_number.rb: -------------------------------------------------------------------------------- 1 | class RenameIdDocumentsColumnFromSnToIdDocumentNumber < ActiveRecord::Migration 2 | def change 3 | rename_column :id_documents, :sn, :id_document_number 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /config/locales/server.de.yml: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | # Never edit this file. It will be overwritten when translations are pulled from Transifex. 4 | # 5 | 6 | de: 7 | view_on_github: View on Github 8 | tags: 9 | vip: VIP 10 | admin: Admin 11 | -------------------------------------------------------------------------------- /db/migrate/20140718134132_rename_id_documents_column_category_to_id_document_type.rb: -------------------------------------------------------------------------------- 1 | class RenameIdDocumentsColumnCategoryToIdDocumentType < ActiveRecord::Migration 2 | def change 3 | rename_column :id_documents, :category, :id_document_type 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /public/templates/funds/deposit_btc.html: -------------------------------------------------------------------------------- 1 |

{{"funds.deposit_btc.title" | t}}

2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /public/templates/funds/withdraw_btc.html: -------------------------------------------------------------------------------- 1 |

{{"funds.withdraw_btc.title" | t}}

2 |

3 | {{"funds.withdraw_coin.intro" | t}} 4 |

5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /spec/factories/account.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :account do 3 | locked { "0.0".to_d } 4 | balance { "100.0".to_d } 5 | currency :cny 6 | 7 | factory :account_btc do 8 | currency :btc 9 | end 10 | end 11 | end 12 | 13 | -------------------------------------------------------------------------------- /spec/factories/comments.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :comment do 5 | sequence(:content) { |n| "Content #{n}" } 6 | ticket 7 | author 8 | end 9 | 10 | end 11 | -------------------------------------------------------------------------------- /spec/factories/payment_transactions.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :payment_transaction do 3 | txid { Faker::Lorem.characters(16) } 4 | txout 0 5 | currency { 'btc' } 6 | amount { 10.to_d } 7 | payment_address 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/models/payment_transaction/normal.rb: -------------------------------------------------------------------------------- 1 | class PaymentTransaction::Normal < PaymentTransaction 2 | # Default payment transaction captures all bitcoin-like transactions. 3 | 4 | validates_presence_of :txout 5 | validates_uniqueness_of :txout, scope: :txid 6 | 7 | end 8 | -------------------------------------------------------------------------------- /app/views/private/history/_transaction.html.slim: -------------------------------------------------------------------------------- 1 | tr 2 | td = transaction_type transaction 3 | td = transaction.created_at 4 | td = transaction.currency_obj.code_text 5 | td = transaction.amount 6 | td = transaction.fee 7 | td = transaction_txid_link transaction 8 | -------------------------------------------------------------------------------- /app/views/shared/market/_market_sel.html.slim: -------------------------------------------------------------------------------- 1 | - if Market.all.size > 1 2 | .market-selector 3 | - Market.all.each do |market| 4 | = link_to market.name, market_path(market.id), class: (current_market.name == market.name) ? 'btn btn-primary' : 'btn btn-default' 5 | -------------------------------------------------------------------------------- /spec/routing/two_factors_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'two_factors' do 4 | it { expect(get('/two_factors/sms')).to be_routable } 5 | it { expect(get('/two_factors')).to be_routable } 6 | it { expect(put('/two_factors/sms')).to be_routable } 7 | end 8 | -------------------------------------------------------------------------------- /app/controllers/admin/two_factors_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class TwoFactorsController < BaseController 3 | load_and_authorize_resource 4 | 5 | def destroy 6 | @two_factor.deactive! 7 | 8 | redirect_to :back 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/controllers/private/settings_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | class SettingsController < BaseController 3 | def index 4 | unless current_user.activated? 5 | flash.now[:info] = t('.activated') 6 | end 7 | end 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /app/views/private/history/_trade.html.slim: -------------------------------------------------------------------------------- 1 | tr 2 | td = t(".#{trade_side trade}") 3 | td = trade.created_at 4 | td = trade.market.base_unit.upcase 5 | td = trade.volume 6 | td = trade.market.quote_unit.upcase 7 | td = trade.volume*trade.price 8 | td = trade.price 9 | -------------------------------------------------------------------------------- /db/migrate/20130928113620_delete_table_account_versions.rb: -------------------------------------------------------------------------------- 1 | class DeleteTableAccountVersions < ActiveRecord::Migration 2 | def up 3 | drop_table :account_versions 4 | end 5 | 6 | def down 7 | raise ActiveRecord::IrreversibleMigration 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20141002075102_add_tx_out_to_payment_transactions.rb: -------------------------------------------------------------------------------- 1 | class AddTxOutToPaymentTransactions < ActiveRecord::Migration 2 | def change 3 | add_column :payment_transactions, :txout, :integer 4 | add_index :payment_transactions, [:txid, :txout] 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/validators/ticket_validator.rb: -------------------------------------------------------------------------------- 1 | class TicketValidator < ActiveModel::Validator 2 | def validate(record) 3 | if record.title.blank? && record.content.blank? 4 | record.errors[:title] << I18n.t('private.tickets.title_content_both_blank') 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/private/tickets/new.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @ticket do |f| 2 | .form-group 3 | .col-xs-20.col-xs-offset-4 4 | = t('.intro') 5 | = f.input :title 6 | = f.input :content, input_html: {rows: 10} 7 | hr.split 8 | = f.button :wrapped, cancel: tickets_path 9 | -------------------------------------------------------------------------------- /config/initializers/pusher.rb: -------------------------------------------------------------------------------- 1 | Pusher.app_id = ENV['PUSHER_APP'] 2 | Pusher.key = ENV['PUSHER_KEY'] 3 | Pusher.secret = ENV['PUSHER_SECRET'] 4 | Pusher.host = ENV['PUSHER_HOST'] || 'api.pusherapp.com' 5 | Pusher.port = ENV['PUSHER_PORT'].present? ? ENV['PUSHER_PORT'].to_i : 80 6 | -------------------------------------------------------------------------------- /db/migrate/20140715040545_remove_name_field_from_members_table.rb: -------------------------------------------------------------------------------- 1 | class RemoveNameFieldFromMembersTable < ActiveRecord::Migration 2 | def up 3 | remove_column :members, :name 4 | end 5 | 6 | def down 7 | add_column :members, :name, :string 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/controllers/api/v1/deeps_controller.rb: -------------------------------------------------------------------------------- 1 | module API 2 | module V1 3 | class DeepsController < BaseController 4 | def show 5 | @asks = Global[params[:id]].asks 6 | @bids = Global[params[:id]].bids 7 | end 8 | end 9 | end 10 | end 11 | 12 | -------------------------------------------------------------------------------- /app/mailers/base_mailer.rb: -------------------------------------------------------------------------------- 1 | class BaseMailer < ActionMailer::Base 2 | include AMQPQueue::Mailer 3 | 4 | layout 'mailers/application' 5 | add_template_helper MailerHelper 6 | 7 | default from: ENV['SYSTEM_MAIL_FROM'], 8 | reply_to: ENV['SUPPORT_MAIL'] 9 | end 10 | -------------------------------------------------------------------------------- /app/views/api/v1/tickers/show.jbuilder: -------------------------------------------------------------------------------- 1 | json.ticker do 2 | json.buy @ticker[:buy] 3 | json.sell @ticker[:sell] 4 | json.low @ticker[:low] 5 | json.high @ticker[:high] 6 | json.last @ticker[:last] 7 | json.vol @ticker[:volume] 8 | end 9 | 10 | json.at @ticker[:at] 11 | -------------------------------------------------------------------------------- /config/locales/client.de.yml: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | # Never edit this file. It will be overwritten when translations are pulled from Transifex. 4 | # 5 | 6 | de: 7 | js: 8 | brand: Peatio 9 | funds: 10 | deposit: Einzahlen 11 | withdraw: Auszahlen 12 | -------------------------------------------------------------------------------- /app/models/concerns/deposits/bankable.rb: -------------------------------------------------------------------------------- 1 | module Deposits 2 | module Bankable 3 | extend ActiveSupport::Concern 4 | 5 | included do 6 | validates :fund_extra, :fund_uid, :amount, presence: true 7 | delegate :accounts, to: :channel 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/observers/transfer_observer.rb: -------------------------------------------------------------------------------- 1 | class TransferObserver < AuditObserver 2 | observe :deposit, :withdraw 3 | 4 | def after_update(record) 5 | if record.aasm_state_changed? 6 | Audit::TransferAuditLog.audit!(record, current_user) 7 | end 8 | end 9 | 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20131022035138_add_in_out_to_accounts.rb: -------------------------------------------------------------------------------- 1 | class AddInOutToAccounts < ActiveRecord::Migration 2 | def change 3 | add_column :accounts, :in, :decimal, :precision => 32, :scale => 16 4 | add_column :accounts, :out, :decimal, :precision => 32, :scale => 16 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20140530133210_add_locked_to_orders.rb: -------------------------------------------------------------------------------- 1 | class AddLockedToOrders < ActiveRecord::Migration 2 | def change 3 | add_column :orders, :locked, :decimal, precision: 32, scale: 16 4 | add_column :orders, :origin_locked, :decimal, precision: 32, scale: 16 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /public/templates/funds/deposit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/api/api_v2/entities/member.rb: -------------------------------------------------------------------------------- 1 | module APIv2 2 | module Entities 3 | class Member < Base 4 | expose :sn 5 | expose :name 6 | expose :email 7 | expose :activated 8 | expose :accounts, using: ::APIv2::Entities::Account 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/views/admin/deposits/banks/index.html.slim: -------------------------------------------------------------------------------- 1 | .panel.panel-primary 2 | .panel-heading = t('.oneday') 3 | = render partial: 'table', locals: {banks: @oneday_banks} 4 | .panel.panel-success 5 | .panel-heading = t('.available') 6 | = render partial: 'table', locals: {banks: @available_banks} 7 | -------------------------------------------------------------------------------- /app/views/private/markets/_ticker.html.slim: -------------------------------------------------------------------------------- 1 | #ticker.panel.panel-default 2 | .panel-body 3 | table.table 4 | thead: tr 5 | th.col-xs-8.text-center #{t('.bid')} 6 | th.col-xs-8.text-center #{t('.last')} 7 | th.col-xs-8.text-center #{t('.ask')} 8 | tbody: tr 9 | -------------------------------------------------------------------------------- /db/migrate/20130925171856_change_to_enumerize_in_accounts.rb: -------------------------------------------------------------------------------- 1 | class ChangeToEnumerizeInAccounts < ActiveRecord::Migration 2 | def up 3 | change_column :accounts, :currency, :integer 4 | end 5 | 6 | def down 7 | change_column :accounts, :currency, :string 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20131130190923_remove_pin_digest_from_identities.rb: -------------------------------------------------------------------------------- 1 | class RemovePinDigestFromIdentities < ActiveRecord::Migration 2 | def up 3 | remove_column :identities, :pin_digest 4 | end 5 | 6 | def down 7 | add_column :identities, :pin_digest, :string 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20141107031140_add_deleted_at_to_api_tokens_and_oauth_tokens.rb: -------------------------------------------------------------------------------- 1 | class AddDeletedAtToAPITokensAndOauthTokens < ActiveRecord::Migration 2 | def change 3 | add_column :api_tokens, :deleted_at, :datetime 4 | add_column :oauth_access_tokens, :deleted_at, :datetime 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/whitelist_constraint.rb: -------------------------------------------------------------------------------- 1 | class WhitelistConstraint 2 | def initialize(list) 3 | @list = list 4 | end 5 | 6 | def matches?(request) 7 | if @list.empty? || @list.include?(request.remote_ip) 8 | true 9 | else 10 | false 11 | end 12 | end 13 | end 14 | 15 | -------------------------------------------------------------------------------- /public/templates/funds/withdraw.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Peatio::Application.load_tasks 8 | -------------------------------------------------------------------------------- /app/controllers/private/withdraws_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | class WithdrawsController < BaseController 3 | before_action :auth_activated! 4 | before_action :auth_verified! 5 | 6 | def index 7 | @channels = WithdrawChannel.all 8 | end 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/models/token/activation.rb: -------------------------------------------------------------------------------- 1 | class Token::Activation < ::Token 2 | after_create :send_token 3 | 4 | def confirm! 5 | super 6 | member.active! 7 | end 8 | 9 | private 10 | 11 | def send_token 12 | TokenMailer.activation(member.email, token).deliver 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/views/private/markets/_balance.html.slim: -------------------------------------------------------------------------------- 1 | .row.row-tips 2 | .col-xs-24.text-right 3 | span.label.label-info.status-info 4 | span.label.label-success.status-success 5 | span.label.label-danger.status-danger 6 | span.number-label = t('.balance') 7 | span.current-balance.number 8 | -------------------------------------------------------------------------------- /db/migrate/20130906073020_create_payment_addresses.rb: -------------------------------------------------------------------------------- 1 | class CreatePaymentAddresses < ActiveRecord::Migration 2 | def change 3 | create_table :payment_addresses do |t| 4 | t.integer :account_id 5 | t.string :address 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20140709085158_create_comments.rb: -------------------------------------------------------------------------------- 1 | class CreateComments < ActiveRecord::Migration 2 | def change 3 | create_table :comments do |t| 4 | t.text :content 5 | t.integer :author_id 6 | t.integer :ticket_id 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20130929012418_create_invitations.rb: -------------------------------------------------------------------------------- 1 | class CreateInvitations < ActiveRecord::Migration 2 | def change 3 | create_table :invitations do |t| 4 | t.boolean :is_used 5 | t.string :token 6 | t.string :email 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20140319022302_create_proofs.rb: -------------------------------------------------------------------------------- 1 | class CreateProofs < ActiveRecord::Migration 2 | def change 3 | create_table :proofs do |t| 4 | t.string :root 5 | t.integer :currency 6 | t.boolean :ready, default: false 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/models/worker/pusher_market.rb: -------------------------------------------------------------------------------- 1 | module Worker 2 | class PusherMarket 3 | 4 | def process(payload, metadata, delivery_info) 5 | trade = Trade.new payload 6 | trade.trigger_notify 7 | Global[trade.market].trigger_trades [trade.for_global] 8 | end 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /config/locales/server.zh-TW.yml: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | # Never edit this file. It will be overwritten when translations are pulled from Transifex. 4 | # 5 | 6 | zh-TW: 7 | view_on_github: 到 Github 上查看 8 | slogan: 首家开源数字加密货币交易所 9 | tags: 10 | vip: VIP 11 | admin: 管理员 12 | all: 全部 13 | -------------------------------------------------------------------------------- /db/migrate/20130928190156_rename_member_id_to_identity_id.rb: -------------------------------------------------------------------------------- 1 | class RenameMemberIdToIdentityId < ActiveRecord::Migration 2 | def up 3 | rename_column :reset_pins, :member_id, :identity_id 4 | end 5 | 6 | def down 7 | rename_column :reset_pins, :identity_id, :member_id 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20130930183833_migrate_withdraw_addresses.rb: -------------------------------------------------------------------------------- 1 | class MigrateWithdrawAddresses < ActiveRecord::Migration 2 | def up 3 | change_table :members do |t| 4 | t.remove :alipay 5 | end 6 | end 7 | 8 | def down 9 | raise ActiveRecord::IrreversibleMigration 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20140717033231_add_assets_table.rb: -------------------------------------------------------------------------------- 1 | class AddAssetsTable < ActiveRecord::Migration 2 | def change 3 | create_table :assets do |t| 4 | t.string :type 5 | t.integer :attachable_id 6 | t.string :attachable_type 7 | t.string :file 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/views/verify/google_auths/edit.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @google_auth, as: 'google_auth', url: verify_google_auth_path, method: :delete do |f| 2 | = f.input :otp 3 | hr.split 4 | = f.button :wrapped, t('.submit'), cancel: settings_path 5 | 6 | = content_for :guide do 7 | p.text-warning = t('.warning') 8 | -------------------------------------------------------------------------------- /db/migrate/20131009132505_create_documents.rb: -------------------------------------------------------------------------------- 1 | class CreateDocuments < ActiveRecord::Migration 2 | def change 3 | create_table :documents do |t| 4 | t.string :key 5 | t.string :title 6 | t.text :body 7 | t.boolean :is_auth 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/datagrid/naming.rb: -------------------------------------------------------------------------------- 1 | module Datagrid 2 | module Naming 3 | extend ActiveSupport::Concern 4 | extend ::ActiveModel::Naming 5 | 6 | module ClassMethods 7 | def grid_name 8 | I18n.t("activerecord.models.#{model_name.i18n_key}") 9 | end 10 | end 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /spec/factories/authentications.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :authentication do 5 | provider "MyString" 6 | uid "MyString" 7 | token "MyString" 8 | secret "MyString" 9 | member_id 1 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/controllers/private/trade_states_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | class TradeStatesController < BaseController 3 | def show 4 | @member = current_user 5 | @ask_account = @member.get_account params[:ask] 6 | @bid_account = @member.get_account params[:bid] 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/views/admin/proofs/edit.html.slim: -------------------------------------------------------------------------------- 1 | .row 2 | .col-xs-12 3 | = simple_vertical_form_for [:admin, @proof] do |f| 4 | = f.input :id, readonly: true 5 | = f.input :created_at, as: :string, readonly: true 6 | = f.input :currency, readonly: true 7 | = f.input :balance 8 | = f.button :submit 9 | -------------------------------------------------------------------------------- /db/migrate/20141105090746_add_oauth_columns_to_api_tokens.rb: -------------------------------------------------------------------------------- 1 | class AddOauthColumnsToAPITokens < ActiveRecord::Migration 2 | def change 3 | add_column :api_tokens, :oauth_access_token_id, :integer 4 | add_column :api_tokens, :expire_at, :datetime 5 | add_column :api_tokens, :scopes, :string 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/factories/identity.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :identity do 3 | email { Faker::Internet.email } 4 | password { 'Password123' } 5 | password_confirmation { 'Password123' } 6 | is_active true 7 | 8 | trait :deactive do 9 | is_active false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/admin/members/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.base do 2 | json.id @member.id 3 | json.sn @member.sn 4 | json.email @member.email 5 | end 6 | 7 | json.accounts @accounts do |a| 8 | json.currency a.currency 9 | json.balance a.balance 10 | json.locked a.locked 11 | json.sum a.locked + a.balance 12 | end 13 | -------------------------------------------------------------------------------- /app/views/datagrid/_head.html.erb: -------------------------------------------------------------------------------- 1 | 2 | <% grid.html_columns(*options[:columns]).each do |column| %> 3 | 4 | <%= datagrid_order_for(grid, column) if column.order && options[:order]%> 5 | <%= column.header %> 6 | 7 | <% end %> 8 | 9 | -------------------------------------------------------------------------------- /app/views/private/history/_order.html.slim: -------------------------------------------------------------------------------- 1 | tr 2 | td = order.id 3 | td = t ".#{order.kind}" 4 | td = t ".#{order.state}" 5 | td = order.currency.upcase 6 | td = order.price 7 | td = order.origin_volume 8 | td = order.avg_price 9 | td = order.origin_volume - order.volume 10 | td = order.created_at 11 | -------------------------------------------------------------------------------- /db/migrate/20140709084906_create_tickets.rb: -------------------------------------------------------------------------------- 1 | class CreateTickets < ActiveRecord::Migration 2 | def change 3 | create_table :tickets do |t| 4 | t.string :title 5 | t.text :content 6 | t.string :aasm_state 7 | t.integer :author_id 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/fixtures/banks.yml: -------------------------------------------------------------------------------- 1 | - id: 1 2 | code: bank_code_1 3 | currency: cny 4 | deposit: true 5 | withdraw: true 6 | - id: 2 7 | code: bank_code_2 8 | currency: cny 9 | deposit: true 10 | withdraw: true 11 | - id: 3 12 | code: bank_code_3 13 | currency: cny 14 | deposit: true 15 | withdraw: true 16 | -------------------------------------------------------------------------------- /app/mailers/token_mailer.rb: -------------------------------------------------------------------------------- 1 | class TokenMailer < BaseMailer 2 | 3 | def reset_password(email, token) 4 | @token_url = edit_reset_password_url(token) 5 | mail to: email 6 | end 7 | 8 | def activation(email, token) 9 | @token_url = edit_activation_url token 10 | mail to: email 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /app/models/concerns/channelable.rb: -------------------------------------------------------------------------------- 1 | module Channelable 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | def self.category 6 | to_s.underscore.split('_').first.pluralize 7 | end 8 | end 9 | 10 | def kls 11 | "#{self.class.category}/#{key}".camelize.constantize 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /app/views/authentications/identities/new.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @identity, url: authentications_identities_path do |f| 2 | = f.input :email, disabled: true 3 | = f.input :password, label: t('.password') 4 | = f.input :password_confirmation 5 | hr.split 6 | = f.button :wrapped, value: t('.save') ,cancel: settings_path 7 | -------------------------------------------------------------------------------- /app/views/datagrid/_row.html.erb: -------------------------------------------------------------------------------- 1 | 2 | <% grid.html_columns(*options[:columns]).each do |column| %> 3 | <%= datagrid_format_value(grid, column, asset) %> 4 | <% end %> 5 | 6 | -------------------------------------------------------------------------------- /app/views/shared/_header_lang_sel.html.slim: -------------------------------------------------------------------------------- 1 | li.dropdown 2 | a.dropdown-toggle href="#" data-toggle="dropdown" 3 | img src='#{language_path}' 4 | b.caret 5 | ul#languages.dropdown-menu 6 | - I18n.available_locales.each do |lang| 7 | li: a href="?lang=#{lang}": img src="/languages/#{lang || I18n.locale}.png" 8 | 9 | -------------------------------------------------------------------------------- /db/migrate/20130905132250_add_balance_to_account_versions.rb: -------------------------------------------------------------------------------- 1 | class AddBalanceToAccountVersions < ActiveRecord::Migration 2 | def change 3 | add_column :account_versions, :balance, :decimal, :precision => 32, :scale => 16 4 | add_column :account_versions, :amount, :decimal, :precision => 32, :scale => 16 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/models/concerns/withdraws/bankable.rb: -------------------------------------------------------------------------------- 1 | module Withdraws 2 | module Bankable 3 | extend ActiveSupport::Concern 4 | 5 | included do 6 | validates_presence_of :fund_extra 7 | 8 | delegate :name, to: :member, prefix: true 9 | 10 | alias_attribute :remark, :id 11 | end 12 | 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/views/private/api_tokens/new.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @token do |f| 2 | = f.input :label, hint: t('.label_hint') 3 | = two_factor_tag(current_user) 4 | hr.split 5 | = f.button :wrapped, t('actions.confirm') do 6 | = link_to t('actions.cancel'), api_tokens_path, role: 'button', class: 'btn btn-danger btn-lg pull-right' 7 | -------------------------------------------------------------------------------- /app/views/private/markets/_range_switch.html.slim: -------------------------------------------------------------------------------- 1 | ul#range_switch.list-inline.switch data-x='60' 2 | - %w(1 5 15 30 | 60 120 240 360 720 | 1440 4320 | 10080).each do |x| 3 | li.text-center 4 | - if x == '|' 5 | span | 6 | - else 7 | a.hand-point.chart-switch href='#' data-x='#{x}' = t(".switch_#{x}") 8 | -------------------------------------------------------------------------------- /config/initializers/kaminari_config.rb: -------------------------------------------------------------------------------- 1 | Kaminari.configure do |config| 2 | config.default_per_page = 10 3 | # config.max_per_page = nil 4 | # config.window = 4 5 | # config.outer_window = 0 6 | # config.left = 0 7 | # config.right = 0 8 | # config.page_method_name = :page 9 | # config.param_name = :page 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20130926011813_change_to_enumerize_in_payment_transactions.rb: -------------------------------------------------------------------------------- 1 | class ChangeToEnumerizeInPaymentTransactions < ActiveRecord::Migration 2 | def up 3 | change_column :payment_transactions, :state, :integer 4 | end 5 | 6 | def down 7 | change_column :payment_transactions, :state, :string 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20140306020939_create_id_documents.rb: -------------------------------------------------------------------------------- 1 | class CreateIdDocuments < ActiveRecord::Migration 2 | def change 3 | create_table :id_documents do |t| 4 | t.integer :category 5 | t.string :name 6 | t.string :sn 7 | t.integer :member_id 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20140326191837_add_deposit_id_to_payment_transactions.rb: -------------------------------------------------------------------------------- 1 | class AddDepositIdToPaymentTransactions < ActiveRecord::Migration 2 | def change 3 | add_column :payment_transactions, :aasm_state, :string, :after => :state 4 | add_column :payment_transactions, :channel_id, :integer, :after => :aasm_state 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /config/locales/client.zh-TW.yml: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | # Never edit this file. It will be overwritten when translations are pulled from Transifex. 4 | # 5 | 6 | zh-TW: 7 | js: 8 | brand: 貔貅 9 | submit: 提交 10 | funds: 11 | deposit: 充值 12 | withdraw: 提现 13 | deposit_cny: 14 | title: 人民币充值 15 | -------------------------------------------------------------------------------- /app/validators/withdraw_blacklist_validator.rb: -------------------------------------------------------------------------------- 1 | class WithdrawBlacklistValidator < ActiveModel::Validator 2 | 3 | def validate(record) 4 | if record.channel.blacklist && record.channel.blacklist.include?(record.fund_uid) 5 | record.errors[:fund_uid] << I18n.t('withdraws.invalid_address') 6 | end 7 | end 8 | 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20131003003357_add_address_to_deposits.rb: -------------------------------------------------------------------------------- 1 | class AddAddressToDeposits < ActiveRecord::Migration 2 | def change 3 | change_table :deposits do |t| 4 | t.string :address, :after => :amount 5 | t.string :address_label, :after => :address 6 | t.rename :category, :address_type 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20140105034746_drop_reset_passwords.rb: -------------------------------------------------------------------------------- 1 | class DropResetPasswords < ActiveRecord::Migration 2 | def up 3 | if ActiveRecord::Base.connection.table_exists? :reset_passwords 4 | drop_table :reset_passwords 5 | end 6 | end 7 | 8 | def down 9 | raise ActiveRecord::IrreversibleMigration 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20140327062025_add_memo_and_remove_fund_source_to_deposits.rb: -------------------------------------------------------------------------------- 1 | class AddMemoAndRemoveFundSourceToDeposits < ActiveRecord::Migration 2 | def change 3 | add_column :deposits, :memo, :string 4 | rename_column :deposits, :fund_source_uid, :fund_uid 5 | rename_column :deposits, :fund_source_extra, :fund_extra 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/models/bank_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Bank do 4 | context '#with_currency' do 5 | it { expect(Bank.with_currency(:cny)).not_to be_empty } 6 | end 7 | 8 | context '#currency_obj' do 9 | subject { Bank.with_currency(:cny).first } 10 | its(:currency_obj) { should be_present } 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/models/audit/transfer_audit_log.rb: -------------------------------------------------------------------------------- 1 | module Audit 2 | class TransferAuditLog < AuditLog 3 | 4 | def self.audit!(transfer, operator = nil) 5 | create(operator_id: operator.try(:id), auditable: transfer, 6 | source_state: transfer.aasm_state_was, target_state: transfer.aasm_state) 7 | end 8 | 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/models/worker/pusher_member.rb: -------------------------------------------------------------------------------- 1 | module Worker 2 | class PusherMember 3 | 4 | def process(payload, metadata, delivery_info) 5 | member = Member.find payload['member_id'] 6 | event = payload['event'] 7 | data = JSON.parse payload['data'] 8 | member.notify event, data 9 | end 10 | 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/views/admin/statistic/orders/show.html.slim: -------------------------------------------------------------------------------- 1 | .row: .col-xs-12.alert 2 | #filter-accordion.panel-group 3 | = render "admin/statistic/shared/filter", form_target: @orders_grid, url: admin_statistic_orders_path 4 | = render "admin/statistic/shared/summary", groups: @groups 5 | .row: .col-xs-12 6 | = datagrid_table(@orders_grid, @assets) 7 | -------------------------------------------------------------------------------- /app/views/admin/statistic/trades/show.html.slim: -------------------------------------------------------------------------------- 1 | .row: .col-xs-12.alert 2 | #filter-accordion.panel-group 3 | = render "admin/statistic/shared/filter", form_target: @trades_grid, url: admin_statistic_trades_path 4 | = render "admin/statistic/shared/summary", groups: @groups 5 | .row: .col-xs-12 6 | = datagrid_table(@trades_grid, @assets) 7 | -------------------------------------------------------------------------------- /db/migrate/20131204020953_add_currency_to_account_versions.rb: -------------------------------------------------------------------------------- 1 | class AddCurrencyToAccountVersions < ActiveRecord::Migration 2 | def up 3 | add_column :account_versions, :currency, :integer 4 | remove_column :account_versions, :detail 5 | end 6 | 7 | def down 8 | raise ActiveRecord::IrreversibleMigration 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/benchmark/amqp_mock.rb: -------------------------------------------------------------------------------- 1 | class AMQPQueue 2 | class < 2 | window.sfx('warning') 3 | 4 | window.sfx_success = -> 5 | window.sfx('success') 6 | 7 | window.sfx = (kind) -> 8 | s = $("##{kind}-fx")[0] 9 | return if Cookies.get('sound') == 'false' 10 | return unless s.play 11 | s.pause() 12 | s.currentTime = 0 13 | s.play() 14 | -------------------------------------------------------------------------------- /app/views/admin/statistic/deposits/show.html.slim: -------------------------------------------------------------------------------- 1 | .row: .col-xs-12.alert 2 | #filter-accordion.panel-group 3 | = render "admin/statistic/shared/filter", form_target: @deposits_grid, url: admin_statistic_deposits_path 4 | = render "admin/statistic/shared/summary", groups: @groups 5 | .row: .col-xs-12 6 | = datagrid_table(@deposits_grid, @assets) 7 | -------------------------------------------------------------------------------- /config/database.yml.example: -------------------------------------------------------------------------------- 1 | development: &defaults 2 | adapter: mysql2 3 | encoding: utf8 4 | database: peatio_development 5 | username: root 6 | password: 7 | pool: 10 8 | reconnect: true 9 | 10 | test: 11 | <<: *defaults 12 | database: peatio_test 13 | 14 | production: 15 | <<: *defaults 16 | database: peatio_production 17 | -------------------------------------------------------------------------------- /lib/templates/slim/scaffold/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for(@<%= singular_table_name %>) do |f| 2 | = f.error_notification 3 | 4 | .form-inputs 5 | <%- attributes.each do |attribute| -%> 6 | = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> 7 | <%- end -%> 8 | 9 | .form-actions 10 | = f.button :submit 11 | -------------------------------------------------------------------------------- /app/assets/javascripts/component_ui/key_bind.js.coffee: -------------------------------------------------------------------------------- 1 | ESC = 27 2 | @KeyBindUI = flight.component -> 3 | @after 'initialize', -> 4 | entry = '#ask_entry' 5 | @$node.on 'keyup', (e) -> 6 | if e.keyCode == ESC 7 | if entry == '#bid_entry' then entry = '#ask_entry' else entry = '#bid_entry' 8 | $(entry).trigger 'place_order::clear' 9 | -------------------------------------------------------------------------------- /app/assets/javascripts/component_ui/market_ticker.js.coffee: -------------------------------------------------------------------------------- 1 | window.MarketTickerUI = flight.component -> 2 | @attributes 3 | ticker: 'tbody > tr' 4 | 5 | @refresh = (event, ticker) -> 6 | @select('ticker').empty().prepend(JST['templates/ticker'](ticker)) 7 | 8 | @after 'initialize', -> 9 | @on document, 'market::ticker', @refresh 10 | -------------------------------------------------------------------------------- /app/models/asset.rb: -------------------------------------------------------------------------------- 1 | class Asset < ActiveRecord::Base 2 | belongs_to :attachable, polymorphic: true 3 | 4 | mount_uploader :file, FileUploader 5 | 6 | def image? 7 | file.content_type.start_with?('image') if file? 8 | end 9 | end 10 | 11 | class Asset::IdDocumentFile < Asset 12 | end 13 | 14 | class Asset::IdBillFile < Asset 15 | end 16 | -------------------------------------------------------------------------------- /app/models/withdraw_channel.rb: -------------------------------------------------------------------------------- 1 | class WithdrawChannel < ActiveYamlBase 2 | include Channelable 3 | include HashCurrencible 4 | include International 5 | 6 | def blacklist 7 | self[:blacklist] 8 | end 9 | 10 | def as_json(options = {}) 11 | super(options)['attributes'].merge({resource_name: key.pluralize}) 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /app/views/admin/statistic/withdraws/show.html.slim: -------------------------------------------------------------------------------- 1 | .row: .col-xs-12.alert 2 | #filter-accordion.panel-group 3 | = render "admin/statistic/shared/filter", form_target: @withdraws_grid, url: admin_statistic_withdraws_path 4 | = render "admin/statistic/shared/summary", groups: @groups 5 | .row: .col-xs-12 6 | = datagrid_table(@withdraws_grid, @assets) 7 | -------------------------------------------------------------------------------- /db/migrate/20140302094520_rename_identity_id_to_member_id.rb: -------------------------------------------------------------------------------- 1 | class RenameIdentityIdToMemberId < ActiveRecord::Migration 2 | def change 3 | change_table :tokens do |t| 4 | t.rename :identity_id, :member_id 5 | end 6 | 7 | change_table :two_factors do |t| 8 | t.rename :identity_id, :member_id 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/factories/trade.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :trade do 3 | price "10.0" 4 | volume 1 5 | funds {price.to_d * volume.to_d} 6 | currency :btccny 7 | association :ask, factory: :order_ask 8 | association :bid, factory: :order_bid 9 | ask_member { ask.member } 10 | bid_member { bid.member } 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/controllers/admin/deposits/base_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | module Deposits 3 | class BaseController < ::Admin::BaseController 4 | def channel 5 | @channel ||= DepositChannel.find_by_key(self.controller_name.singularize) 6 | end 7 | 8 | def kls 9 | channel.kls 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /config/markets.yml.example: -------------------------------------------------------------------------------- 1 | - id: btccny 2 | code: 3 3 | #name: BTC/CNY # default name 4 | base_unit: btc 5 | quote_unit: cny 6 | #price_group_fixed: 1 # aggregate price levels in orderbook 7 | bid: {fee: 0, currency: cny, fixed: 2} 8 | ask: {fee: 0, currency: btc, fixed: 4} 9 | sort_order: 1 10 | #visible: false # default to true 11 | -------------------------------------------------------------------------------- /db/migrate/20130928165236_add_alipay_to_members.rb: -------------------------------------------------------------------------------- 1 | class AddAlipayToMembers < ActiveRecord::Migration 2 | def up 3 | add_column :identities, :pin_digest, :string 4 | remove_column :members, :pin_digest 5 | end 6 | 7 | def down 8 | remove_column :identities, :pin_digest 9 | add_column :members, :pin_digest, :string 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/api/api_v2/markets_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe APIv2::Markets do 4 | 5 | describe "GET /api/v2/markets" do 6 | it "should all available markets" do 7 | get '/api/v2/markets' 8 | response.should be_success 9 | response.body.should == '[{"id":"btccny","name":"BTC/CNY"}]' 10 | end 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20140327044440_change_withdraws.rb: -------------------------------------------------------------------------------- 1 | class ChangeWithdraws < ActiveRecord::Migration 2 | def change 3 | rename_column :withdraws, :withdraw_channel_id, :channel_id 4 | rename_column :withdraws, :tx_id, :txid 5 | rename_column :withdraws, :fund_source_uid, :fund_uid 6 | rename_column :withdraws, :fund_source_extra, :fund_extra 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/tasks/deploy.rake: -------------------------------------------------------------------------------- 1 | namespace :deploy do 2 | desc 'touching client side i8n assets' 3 | task touch_client_i18n_assets: :environment do 4 | Dir[Rails.root.join('app', 'assets', 'javascripts','locales', '*.js.erb')].each do |path| 5 | File.open(path, 'a') do |f| 6 | f << "\n//#{Time.now.to_s}" 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/features/tag_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'member tags' do 4 | let!(:identity) { create :identity } 5 | let!(:member) { create :member, email: identity.email, tag_list: 'hero' } 6 | 7 | it 'user can view self tags in settings index' do 8 | signin identity 9 | expect(page).to have_content 'Hero Member' 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/assets/javascripts/funds/models/currency.js.coffee: -------------------------------------------------------------------------------- 1 | class Currency extends PeatioModel.Model 2 | @configure 'Currency', 'key', 'code', 'coin', 'blockchain' 3 | 4 | @initData: (records) -> 5 | PeatioModel.Ajax.disable -> 6 | $.each records, (idx, record) -> 7 | currency = Currency.create(record.attributes) 8 | 9 | window.Currency = Currency 10 | -------------------------------------------------------------------------------- /app/validators/email_validator.rb: -------------------------------------------------------------------------------- 1 | class EmailValidator < ActiveModel::EachValidator 2 | def validate_each(record, attribute, value) 3 | return if value.nil? 4 | unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i 5 | record.errors[attribute] << (options[:message] || I18n.t("activerecord.errors.messages.invalid_email")) 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20131002012809_add_fee_to_withdraws.rb: -------------------------------------------------------------------------------- 1 | class AddFeeToWithdraws < ActiveRecord::Migration 2 | def change 3 | add_column :withdraws, :member_id, :integer, :after => :account_id 4 | add_column :withdraws, :currency, :integer, :after => :member_id 5 | add_column :withdraws, :fee, :decimal, :precision => 32, :scale => 16, :after => :amount 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/models/deposit_channel.rb: -------------------------------------------------------------------------------- 1 | class DepositChannel < ActiveYamlBase 2 | include Channelable 3 | include HashCurrencible 4 | include International 5 | 6 | def accounts 7 | bank_accounts.map {|i| OpenStruct.new(i) } 8 | end 9 | 10 | def as_json(options = {}) 11 | super(options)['attributes'].merge({resource_name: key.pluralize}) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/views/forum/index.html.slim: -------------------------------------------------------------------------------- 1 | a#muut href="https://muut.com/i/peatio" Peatio Forum 2 | 3 | = javascript_include_tag "//cdn.muut.com/1/moot.#{I18n.locale.to_s.slice(0,2)}.min.js" 4 | = stylesheet_link_tag '//cdn.muut.com/1/moot.css' 5 | javascript: 6 | $(function(){ 7 | $("#muut").muut({ 8 | api: #{muut_api_options.to_json.html_safe} 9 | }) 10 | }); 11 | -------------------------------------------------------------------------------- /app/views/private/assets/_liability_proof.html.slim: -------------------------------------------------------------------------------- 1 | .panel.panel-default 2 | .panel-body 3 | .row 4 | #guide.col-xs-8 5 | h3 = t('.title') 6 | p.text-ignore = t('.intro') 7 | p 8 | = link_to t('.how-to-verify'), t('.how-to-verify-uri'), :target => '_blank' 9 | #content.col-xs-16 10 | = render 'liability_tabs' 11 | -------------------------------------------------------------------------------- /db/migrate/20140404101823_add_ask_member_id_and_bid_member_id_to_trades.rb: -------------------------------------------------------------------------------- 1 | class AddAskMemberIdAndBidMemberIdToTrades < ActiveRecord::Migration 2 | def change 3 | add_column :trades, :ask_member_id, :integer 4 | add_column :trades, :bid_member_id, :integer 5 | 6 | add_index :trades, :ask_member_id 7 | add_index :trades, :bid_member_id 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20140428203350_add_desc_and_keyword_to_documents.rb: -------------------------------------------------------------------------------- 1 | class AddDescAndKeywordToDocuments < ActiveRecord::Migration 2 | def change 3 | add_column :documents, :desc, :text 4 | add_column :documents, :keywords, :text 5 | 6 | add_column :document_translations, :desc, :text 7 | add_column :document_translations, :keywords, :text 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/fixtures/markets.yml: -------------------------------------------------------------------------------- 1 | - id: btccny 2 | code: 3 3 | base_unit: btc 4 | quote_unit: cny 5 | bid: {fee: 0, currency: cny, fixed: 2} 6 | ask: {fee: 0, currency: btc, fixed: 4} 7 | - id: ptsbtc 8 | code: 6 9 | base_unit: pts 10 | quote_unit: btc 11 | bid: {fee: 0, currency: btc, fixed: 4} 12 | ask: {fee: 0, currency: pts, fixed: 4} 13 | visible: false 14 | -------------------------------------------------------------------------------- /app/models/active_yaml_base.rb: -------------------------------------------------------------------------------- 1 | class ActiveYamlBase < ActiveYaml::Base 2 | field :sort_order, default: 9999 3 | 4 | if Rails.env == 'test' 5 | set_root_path "#{Rails.root}/spec/fixtures" 6 | else 7 | set_root_path "#{Rails.root}/config" 8 | end 9 | 10 | private 11 | 12 | def <=>(other) 13 | self.sort_order <=> other.sort_order 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /config/initializers/datagrid/filters/date_time_filter.rb: -------------------------------------------------------------------------------- 1 | class Datagrid::Filters::DateTimeFilter < Datagrid::Filters::BaseFilter 2 | def parse(value) 3 | if value.respond_to?(:utc) 4 | value = value.utc 5 | end 6 | 7 | if value.is_a?(String) 8 | return value 9 | else 10 | return value.to_s(:db) 11 | end 12 | end 13 | end 14 | 15 | 16 | -------------------------------------------------------------------------------- /config/withdraw_channels.yml: -------------------------------------------------------------------------------- 1 | - id: 200 2 | key: satoshi 3 | currency: btc 4 | fixed: 8 5 | fee: 0.0005 6 | inuse: true 7 | type: WithdrawChannelSatoshi 8 | - id: 400 9 | key: bank 10 | currency: cny 11 | fixed: 2 12 | fee_max: 0 13 | min: 100 14 | max: 50000 15 | fee: 0.003 16 | proportion: true 17 | inuse: true 18 | type: WithdrawChannelBank 19 | -------------------------------------------------------------------------------- /db/migrate/20130925165804_change_to_enumerize_in_trades.rb: -------------------------------------------------------------------------------- 1 | class ChangeToEnumerizeInTrades < ActiveRecord::Migration 2 | def up 3 | change_column :trades, :trend, :integer 4 | change_column :trades, :currency, :integer 5 | end 6 | 7 | def down 8 | change_column :trades, :currency, :string 9 | change_column :trades, :trend, :boolean 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20131003021225_rename_txid_to_payment_transactions.rb: -------------------------------------------------------------------------------- 1 | class RenameTxidToPaymentTransactions < ActiveRecord::Migration 2 | def up 3 | change_table :payment_transactions do |t| 4 | t.datetime :dont_at 5 | end 6 | end 7 | 8 | def down 9 | change_table :payment_transactions do |t| 10 | t.remove :dont_at 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/controllers/forum_controller.rb: -------------------------------------------------------------------------------- 1 | class ForumController < ApplicationController 2 | layout 'landing' 3 | 4 | def index 5 | render text: 'Please provide muut key and secret' and return unless muut_enabled? 6 | if current_user.try(:display_name).blank? 7 | redirect_to edit_member_path, notice: t('.notice.display_name') and return 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/models/concerns/currencible.rb: -------------------------------------------------------------------------------- 1 | module Currencible 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | extend Enumerize 6 | enumerize :currency, in: Currency.enumerize, scope: true 7 | belongs_to_active_hash :currency_obj, class_name: 'Currency', foreign_key: 'currency_value' 8 | delegate :key_text, to: :currency_obj, prefix: true 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/models/matching/constants.rb: -------------------------------------------------------------------------------- 1 | module Matching 2 | 3 | ZERO = 0.to_d unless defined?(ZERO) 4 | 5 | class DoubleSubmitError < StandardError; end 6 | class InvalidOrderError < StandardError; end 7 | class NotEnoughVolume < StandardError; end 8 | class ExceedSumLimit < StandardError; end 9 | class TradeExecutionError < StandardError; end 10 | 11 | end 12 | -------------------------------------------------------------------------------- /app/views/documents/show.html.slim: -------------------------------------------------------------------------------- 1 | = content_for :page_title do 2 | title = @doc.title 3 | 4 | = content_for :description do 5 | meta name='description' content= @doc.desc 6 | 7 | = content_for :keywords do 8 | meta name='keywords' content= @doc.keywords 9 | 10 | = content_for :frame do 11 | .container 12 | .panel.panel-default 13 | .panel-body == @doc.body 14 | -------------------------------------------------------------------------------- /bin/init_config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'fileutils' 4 | 5 | Dir.glob("config/*.yml.example").each do |example_file| 6 | target_file = example_file[0..-9] 7 | 8 | if File.exist? target_file 9 | puts "Ignore the #{target_file}" 10 | else 11 | FileUtils.cp example_file, target_file 12 | puts "cp #{example_file} #{target_file}" 13 | end 14 | end 15 | 16 | -------------------------------------------------------------------------------- /db/migrate/20140304015055_create_documents_translations.rb: -------------------------------------------------------------------------------- 1 | class CreateDocumentsTranslations < ActiveRecord::Migration 2 | def up 3 | Document.create_translation_table!( 4 | { :title => :string, :body => :text }, 5 | { :migrate_data => true } 6 | ) 7 | end 8 | 9 | def down 10 | Document.drop_translation_table! :migrate_data => true 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/fixtures/withdraw_channels.yml: -------------------------------------------------------------------------------- 1 | - id: 200 2 | key: satoshi 3 | currency: btc 4 | fixed: 8 5 | fee: 0.0005 6 | inuse: true 7 | type: WithdrawChannelSatoshi 8 | - id: 400 9 | key: bank 10 | currency: cny 11 | fixed: 2 12 | fee_max: 0 13 | min: 100 14 | max: 50000 15 | fee: 0.003 16 | proportion: true 17 | inuse: true 18 | type: WithdrawChannelBank 19 | -------------------------------------------------------------------------------- /spec/models/identity_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Identity do 4 | it { should allow_value("pas1Word").for(:password) } 5 | it { should allow_value("pas1Wo@d").for(:password) } 6 | it { should allow_value("pas1Wo_d").for(:password) } 7 | it { should allow_value("123456").for(:password) } 8 | it { should_not allow_value("pwd").for(:password) } 9 | end 10 | -------------------------------------------------------------------------------- /app/api/api_v2/entities/market.rb: -------------------------------------------------------------------------------- 1 | module APIv2 2 | module Entities 3 | class Market < Base 4 | expose :id, documentation: "Unique market id. It's always in the form of xxxyyy, where xxx is the base currency code, yyy is the quote currency code, e.g. 'btccny'. All available markets can be found at /api/v2/markets." 5 | 6 | expose :name 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/controllers/api/v1/trades_controller.rb: -------------------------------------------------------------------------------- 1 | module API 2 | module V1 3 | class TradesController < BaseController 4 | def show 5 | if params[:since] 6 | @trades = Global[params[:id]].since_trades(params[:since]) 7 | else 8 | @trades = Global[params[:id]].trades.reverse 9 | end 10 | end 11 | end 12 | end 13 | end 14 | 15 | -------------------------------------------------------------------------------- /app/views/activations/new.html.slim: -------------------------------------------------------------------------------- 1 | #tips-wrapper 2 | #tips 3 | p 4 | span == t('.tip', email: current_user.email) 5 | p: span #{t(".spam")} 6 | .resend-button 7 | = link_to activation_path(@activation), :method => :put, :class => 'btn btn-primary first' do 8 | span.fui-mail 9 | span #{t('helpers.submit.activation.update')} 10 | -------------------------------------------------------------------------------- /app/views/datagrid/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= form_for grid, options do |f| -%> 2 | <% grid.filters.each do |filter| %> 3 |
4 | <%= f.datagrid_label filter %> 5 | <%= f.datagrid_filter filter %> 6 |
7 | <% end %> 8 | <%= f.submit I18n.t("datagrid.form.submit", :default => "Search").html_safe, :class => 'btn btn-success' %> 9 | <% end -%> 10 | -------------------------------------------------------------------------------- /db/migrate/20130907124647_create_deposits.rb: -------------------------------------------------------------------------------- 1 | class CreateDeposits < ActiveRecord::Migration 2 | def change 3 | create_table :deposits do |t| 4 | t.integer :account_id 5 | t.decimal :amount, :precision => 32, :scale => 16 6 | t.string :payment_way 7 | t.string :payment_id 8 | t.string :state 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/kline_db.rb: -------------------------------------------------------------------------------- 1 | module KlineDB 2 | class << self 3 | 4 | def redis 5 | @redis ||= Redis.new url: ENV["REDIS_URL"], db: 1 6 | end 7 | 8 | def kline(market, period) 9 | key = "peatio:#{market}:k:#{period}" 10 | length = redis.llen(key) 11 | data = redis.lrange(key, length - 5000, -1).map{|str| JSON.parse(str)} 12 | end 13 | 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/controllers/private/settings_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Private::SettingsController do 4 | let(:member) { create :member } 5 | before { session[:member_id] = member.id } 6 | 7 | describe 'GET /index' do 8 | before { get :index } 9 | 10 | it { should respond_with :ok } 11 | it { should render_template(:index) } 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/factories/two_factor.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :two_factor do 3 | member 4 | 5 | trait :activated do 6 | activated true 7 | end 8 | end 9 | 10 | factory :two_factor_app, class: TwoFactor::App, parent: :two_factor, traits: [:activated] 11 | factory :two_factor_sms, class: TwoFactor::Sms, parent: :two_factor, traits: [:activated] 12 | end 13 | 14 | -------------------------------------------------------------------------------- /app/api/api_v2/members.rb: -------------------------------------------------------------------------------- 1 | module APIv2 2 | class Members < Grape::API 3 | helpers ::APIv2::NamedParams 4 | 5 | desc 'Get your profile and accounts info.', scopes: %w(profile) 6 | params do 7 | use :auth 8 | end 9 | get "/members/me" do 10 | authenticate! 11 | present current_user, with: APIv2::Entities::Member 12 | end 13 | 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/assets/javascripts/component_ui/push_button.js.coffee: -------------------------------------------------------------------------------- 1 | @PushButton = flight.component -> 2 | @attributes 3 | buttons: '.type-toggle button' 4 | 5 | @setActiveButton = (event) -> 6 | @select('buttons').removeClass('active') 7 | $(event.target).closest('button').addClass('active') 8 | 9 | @after 'initialize', -> 10 | @on @select('buttons'), 'click', @setActiveButton 11 | -------------------------------------------------------------------------------- /app/models/worker/trade_executor.rb: -------------------------------------------------------------------------------- 1 | module Worker 2 | class TradeExecutor 3 | 4 | def process(payload, metadata, delivery_info) 5 | payload.symbolize_keys! 6 | ::Matching::Executor.new(payload).execute! 7 | rescue 8 | SystemMailer.trade_execute_error(payload, $!.message, $!.backtrace.join("\n")).deliver 9 | raise $! 10 | end 11 | 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20130907110146_create_withdraws.rb: -------------------------------------------------------------------------------- 1 | class CreateWithdraws < ActiveRecord::Migration 2 | def change 3 | create_table :withdraws do |t| 4 | t.integer :account_id 5 | t.decimal :amount, :precision => 32, :scale => 16 6 | t.string :payment_way 7 | t.string :payment_to 8 | t.string :state 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20130925175113_change_to_enumerize_in_deposits.rb: -------------------------------------------------------------------------------- 1 | class ChangeToEnumerizeInDeposits < ActiveRecord::Migration 2 | def up 3 | change_column :deposits, :payment_way, :integer 4 | change_column :deposits, :state, :integer 5 | end 6 | 7 | def down 8 | change_column :deposits, :payment_way, :string 9 | change_column :deposits, :state, :string 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/security_middleware.rb: -------------------------------------------------------------------------------- 1 | class SecurityMiddleware 2 | 3 | def initialize(app) 4 | @app = app 5 | end 6 | 7 | def call(env) 8 | env['HTTP_HOST'] = host 9 | env['HTTP_X_FORWARDED_HOST'] = host 10 | @app.call(env) 11 | end 12 | 13 | def host 14 | @host ||= ENV['URL_PORT'] ? "#{ENV['URL_HOST']}:#{ENV['URL_PORT']}" : ENV['URL_HOST'] 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /spec/factories/deposits.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :deposit do 3 | member { create(:member) } 4 | account { member.get_account(currency) } 5 | currency { 'btc' } 6 | fund_uid { Faker::Lorem.characters } 7 | fund_extra { Faker::Lorem.characters } 8 | amount { (100..10000).to_a.sample.to_d } 9 | txid { Faker::Lorem.characters(16) } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/models/deposits/bank.rb: -------------------------------------------------------------------------------- 1 | module Deposits 2 | class Bank < ::Deposit 3 | include ::AasmAbsolutely 4 | include ::Deposits::Bankable 5 | include ::FundSourceable 6 | 7 | def charge!(txid) 8 | with_lock do 9 | submit! 10 | accept! 11 | touch(:done_at) 12 | update_attribute(:txid, txid) 13 | end 14 | end 15 | 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/kaminari/_gap.html.slim: -------------------------------------------------------------------------------- 1 | / Non-link tag that stands for skipped pages... 2 | - available local variables 3 | current_page : a page object for the currently displayed page 4 | total_pages : total number of pages 5 | per_page : number of items to fetch per page 6 | remote : data-remote 7 | li.page.gap 8 | a 9 | == raw(t 'views.pagination.truncate') 10 | ' 11 | -------------------------------------------------------------------------------- /config/deposit_channels.yml: -------------------------------------------------------------------------------- 1 | - id: 200 2 | key: satoshi 3 | currency: btc 4 | sort_order: 1 5 | min_confirm: 1 6 | max_confirm: 3 7 | - id: 400 8 | key: bank 9 | currency: cny 10 | sort_order: 2 11 | bank_accounts: 12 | - 13 | bank: 'Your Bank Name' 14 | branch: 'Your Bank Branch' 15 | holder: 'Your Account Holder' 16 | account: 'Your Account Number' 17 | -------------------------------------------------------------------------------- /db/migrate/20130926014845_change_to_enumerize_in_withdraws.rb: -------------------------------------------------------------------------------- 1 | class ChangeToEnumerizeInWithdraws < ActiveRecord::Migration 2 | def up 3 | change_column :withdraws, :payment_way, :integer 4 | change_column :withdraws, :state, :integer 5 | end 6 | 7 | def down 8 | change_column :withdraws, :payment_way, :string 9 | change_column :withdraws, :state, :string 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20131002190141_rebuild_deposits.rb: -------------------------------------------------------------------------------- 1 | class RebuildDeposits < ActiveRecord::Migration 2 | def change 3 | change_table :deposits do |t| 4 | t.integer :member_id, :after => :account_id 5 | t.integer :currency, :after => :member_id 6 | t.datetime :done_at 7 | t.rename :payment_way, :category 8 | t.rename :payment_id, :tx_id 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/routing/admin/two_factors_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe '/admin/members/1/two_factors' do 4 | let(:url) { '/admin/members/1/two_factors/1' } 5 | it { expect(delete: url).to be_routable } 6 | it { expect(delete: url).to route_to \ 7 | controller: 'admin/two_factors', 8 | action: 'destroy', 9 | member_id: '1', 10 | id: '1' 11 | } 12 | end 13 | -------------------------------------------------------------------------------- /app/grids/documents_grid.rb: -------------------------------------------------------------------------------- 1 | class DocumentsGrid 2 | include Datagrid 3 | include Datagrid::Naming 4 | include Datagrid::ColumnI18n 5 | 6 | scope do |m| 7 | Document 8 | end 9 | 10 | column :key 11 | column :title 12 | column :is_auth 13 | column :actions, html: true, header: '' do |o| 14 | link_to I18n.t('actions.edit'), edit_admin_document_path(o.key) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/views/private/account_versions/index.html.slim: -------------------------------------------------------------------------------- 1 | .content.row 2 | .profile 3 | .picture 4 | i.fa.fa-list 5 | .summary 6 | p = t('.description') 7 | = datagrid_form_for @account_versions_grid, url: account_versions_path 8 | .versions 9 | = datagrid_table(@account_versions_grid, @assets, html: {:class => 'datagrid table-striped table-hover account_versions_grid'}) 10 | -------------------------------------------------------------------------------- /spec/api/api_v2/entities/account_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe APIv2::Entities::Account do 4 | 5 | let(:account) { create(:account_btc) } 6 | 7 | subject { OpenStruct.new APIv2::Entities::Account.represent(account).serializable_hash } 8 | 9 | its(:currency) { should == 'btc' } 10 | its(:balance) { should == '100.0'} 11 | its(:locked) { should == '0.0' } 12 | 13 | end 14 | -------------------------------------------------------------------------------- /spec/fixtures/deposit_channels.yml: -------------------------------------------------------------------------------- 1 | - id: 200 2 | key: satoshi 3 | currency: btc 4 | sort_order: 1 5 | min_confirm: 1 6 | max_confirm: 3 7 | - id: 400 8 | key: bank 9 | currency: cny 10 | sort_order: 2 11 | bank_accounts: 12 | - 13 | bank: 'Your Bank Name' 14 | branch: 'Your Bank Branch' 15 | holder: 'Your Account Holder' 16 | account: 'Your Account Number' 17 | -------------------------------------------------------------------------------- /app/helpers/private/assets_helper.rb: -------------------------------------------------------------------------------- 1 | module Private::AssetsHelper 2 | 3 | def verify_link(proof, partial_tree) 4 | hashtag = "verify?partial_tree=#{partial_tree.json.to_json}&expected_root=#{proof.root.to_json}" 5 | uri = "http://syskall.com/proof-of-liabilities/##{URI.encode hashtag}" 6 | link_to t('.go-verify'), uri, :class => 'btn btn-default', :target => '_blank' 7 | end 8 | 9 | end 10 | -------------------------------------------------------------------------------- /app/api/api_v2/entities/deposit.rb: -------------------------------------------------------------------------------- 1 | module APIv2 2 | module Entities 3 | class Deposit < Base 4 | expose :currency 5 | expose :amount, format_with: :decimal 6 | expose :fee 7 | expose :txid 8 | expose :created_at, format_with: :iso8601 9 | expose :memo 10 | expose :done_at, format_with: :iso8601 11 | expose :aasm_state, as: :state 12 | end 13 | end 14 | end -------------------------------------------------------------------------------- /app/controllers/concerns/token_management.rb: -------------------------------------------------------------------------------- 1 | module Concerns 2 | module TokenManagement 3 | extend ActiveSupport::Concern 4 | 5 | def token_required 6 | if not @token = Token.available.with_token(params[:token] || params[:id]).first 7 | redirect_to root_path, :alert => t('.alert') 8 | end 9 | end 10 | 11 | alias :'token_required!' :'token_required' 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/views/private/assets/partial_tree.js.erb: -------------------------------------------------------------------------------- 1 | var scope = '#<%= params[:id] %>-proof .partial-tree'; 2 | $(scope + ' pre').text('<%= @json %>').show(); 3 | 4 | copy_link = $(scope + ' a.copy'); 5 | copy_link.removeClass('disabled'); 6 | 7 | get_link = $(scope + ' a.get-partial-tree'); 8 | get_link.addClass('disabled'); 9 | 10 | $(scope + ' .message').text('<%= t('.success', timestamp: @timestamp.to_s) %>') 11 | -------------------------------------------------------------------------------- /config/maintenance.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$1" == "off" ]; then 4 | echo "switch off maintenance mode" 5 | ln -sf /home/deploy/peatio/shared/config/nginx.conf /etc/nginx/conf.d/peatio.conf 6 | service nginx reload 7 | else 8 | echo "switch on maintenance mode" 9 | ln -sf /home/deploy/peatio/shared/config/nginx_maintenance.conf /etc/nginx/conf.d/peatio.conf 10 | service nginx reload 11 | fi 12 | -------------------------------------------------------------------------------- /app/assets/javascripts/swagger-ui/lib/jquery.slideto.min.js: -------------------------------------------------------------------------------- 1 | (function(b){b.fn.slideto=function(a){a=b.extend({slide_duration:"slow",highlight_duration:3E3,highlight:true,highlight_color:"#FFFF99"},a);return this.each(function(){obj=b(this);b("body").animate({scrollTop:obj.offset().top},a.slide_duration,function(){a.highlight&&b.ui.version&&obj.effect("highlight",{color:a.highlight_color},a.highlight_duration)})})}})(jQuery); 2 | -------------------------------------------------------------------------------- /db/migrate/20130906073931_create_payment_transactions.rb: -------------------------------------------------------------------------------- 1 | class CreatePaymentTransactions < ActiveRecord::Migration 2 | def change 3 | create_table :payment_transactions do |t| 4 | t.string :txid 5 | t.decimal :amount, :precision => 32, :scale => 16 6 | t.integer :confirmations 7 | t.string :address 8 | t.string :state 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20131201011127_drop_reset_pins.rb: -------------------------------------------------------------------------------- 1 | class DropResetPins < ActiveRecord::Migration 2 | def up 3 | drop_table :reset_pins 4 | end 5 | 6 | def down 7 | create_table :reset_pins do |t| 8 | t.string :email 9 | t.string :token 10 | t.datetime :expire_at 11 | t.integer :identity_id 12 | t.boolean :is_used 13 | 14 | t.timestamps 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/api/api_v2/entities/trade.rb: -------------------------------------------------------------------------------- 1 | module APIv2 2 | module Entities 3 | class Trade < Base 4 | expose :id 5 | expose :price 6 | expose :volume 7 | expose :funds 8 | expose :currency, as: :market 9 | expose :created_at, format_with: :iso8601 10 | 11 | expose :side do |trade, options| 12 | options[:side] || trade.side 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/controllers/private/account_versions_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | class AccountVersionsController < BaseController 3 | def index 4 | @account_versions_grid = AccountVersionsGrid.new(params[:account_versions_grid]) do |scope| 5 | scope.where(:member_id => current_user.id) 6 | end 7 | @assets = @account_versions_grid.assets.page(params[:page]).per(20) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/daemons/matching_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | 7 | config[:app_name] = 'peatio:amqp:matching' 8 | config[:script] = "#{File.expand_path('../amqp_daemon.rb', __FILE__)}" 9 | config[:ARGV] = ARGV + %w(-- matching) 10 | 11 | Daemons::Rails.run config[:script], config.to_hash 12 | -------------------------------------------------------------------------------- /app/validators/strength_validator.rb: -------------------------------------------------------------------------------- 1 | class StrengthValidator < ActiveModel::EachValidator 2 | def validate_each(record, attribute, value) 3 | min = options[:min] 4 | min ||= 6 5 | unless value =~ /(?=^.{#{min},}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*\z/ 6 | record.errors[attribute] << (options[:message] || I18n.t("activemodel.errors.messages.strength")) 7 | end 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /app/views/private/shared/_balances.html.slim: -------------------------------------------------------------------------------- 1 | .row 2 | - member.accounts.each do |account| 3 | .col-xs-6 4 | .row class='account-#{account.currency}' 5 | .col-xs-4: h5.amount data-title='#{account.currency_text}' = account.amount 6 | .col-xs-3: h5.locked.text-right data-title='#{t('.locked')}' = account.locked 7 | .col-xs-3: h5.available.text-right data-title='#{t('.available')}' = account.balance 8 | -------------------------------------------------------------------------------- /db/migrate/20140402043033_create_partial_trees.rb: -------------------------------------------------------------------------------- 1 | class CreatePartialTrees < ActiveRecord::Migration 2 | def up 3 | create_table :partial_trees do |t| 4 | t.integer :proof_id, null: false 5 | t.integer :account_id, null: false 6 | t.text :json, null: false 7 | 8 | t.timestamps 9 | end 10 | 11 | remove_column :accounts, :partial_tree 12 | 13 | Proof.delete_all 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/models/running_account.rb: -------------------------------------------------------------------------------- 1 | class RunningAccount < ActiveRecord::Base 2 | include Currencible 3 | 4 | CATEGORY = { 5 | withdraw_fee: 0, 6 | trading_fee: 1, 7 | register_reward: 2, 8 | referral_code_reward: 3, 9 | deposit_reward: 4 10 | } 11 | 12 | enumerize :category, in: CATEGORY 13 | 14 | belongs_to :member 15 | belongs_to :source, polymorphic: true 16 | 17 | end 18 | -------------------------------------------------------------------------------- /spec/models/deposit_channel_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe DepositChannel do 4 | 5 | context "#sort" do 6 | let(:dc1) { DepositChannel.new } 7 | let(:dc2) { DepositChannel.new } 8 | 9 | it "sort DepositChannel" do 10 | dc1.stubs(:sort_order).returns 1 11 | dc2.stubs(:sort_order).returns 2 12 | expect([dc2, dc1].sort.first.sort_order).to eq(1) 13 | end 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /app/assets/javascripts/component_ui/market_trades.js.coffee: -------------------------------------------------------------------------------- 1 | window.MarketTradesUI = flight.component -> 2 | @attributes 3 | wrap: '.wrap' 4 | table: 'tbody' 5 | defaultHeight: 156 6 | 7 | @refresh = (event, data) -> 8 | $table = @select('table') 9 | $table.prepend(JST['templates/market_trade'](trade)) for trade in data.trades 10 | 11 | @after 'initialize', -> 12 | @on document, 'market::trades', @refresh 13 | -------------------------------------------------------------------------------- /app/assets/javascripts/funds/models/member.js.coffee: -------------------------------------------------------------------------------- 1 | class Member extends PeatioModel.Model 2 | @configure 'Member', 'sn', 'display_name', 'created_at', 'updated_at', 'state', 3 | 'country_code', 'phone_number', 'name', 'app_activated', 'sms_activated' 4 | 5 | @initData: (records) -> 6 | PeatioModel.Ajax.disable -> 7 | $.each records, (idx, record) -> 8 | Member.create(record) 9 | 10 | window.Member = Member 11 | -------------------------------------------------------------------------------- /lib/daemons/withdraw_coin_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | 7 | config[:app_name] = 'peatio:amqp:withdraw_coin' 8 | config[:script] = "#{File.expand_path('../amqp_daemon.rb', __FILE__)}" 9 | config[:ARGV] = ARGV + %w(-- withdraw_coin) 10 | 11 | Daemons::Rails.run config[:script], config.to_hash 12 | -------------------------------------------------------------------------------- /app/assets/javascripts/funds/models/fund_source.js.coffee: -------------------------------------------------------------------------------- 1 | class FundSource extends PeatioModel.Model 2 | @configure 'FundSource', 'aasm_state', 'member_id', 'currency', 'extra', 'uid', 'is_locked', 'label' 3 | 4 | constructor: -> 5 | super 6 | 7 | @initData: (records) -> 8 | PeatioModel.Ajax.disable -> 9 | $.each records, (idx, record) -> 10 | FundSource.create(record) 11 | 12 | window.FundSource = FundSource 13 | -------------------------------------------------------------------------------- /app/controllers/admin/statistic/members_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | module Statistic 3 | class MembersController < BaseController 4 | def show 5 | @members_count = Member.count 6 | @register_group = Member.where('created_at > ?', 30.days.ago).select('date(created_at) as date, count(id) as total, sum(activated IS TRUE) as total_activated').group('date(created_at)') 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/views/private/markets/_market_switch.html.slim: -------------------------------------------------------------------------------- 1 | li#market_switch.dropdown 2 | a.dropdown-toggle href="#" data-toggle="dropdown" 3 | span = t('.title') 4 | .dropdown-menu 5 | table.table.table-hover 6 | thead: tr 7 | th.name.col-xs-6.text-left #{t('.name')} 8 | th.bid.col-xs-8.text-right #{t('.bid')} 9 | th.ask.col-xs-8.text-right #{t('.ask')} 10 | th.col-xs-2.text-center 11 | tbody 12 | -------------------------------------------------------------------------------- /db/migrate/20140403070840_add_type_to_withdraws.rb: -------------------------------------------------------------------------------- 1 | class AddTypeToWithdraws < ActiveRecord::Migration 2 | def up 3 | add_column :withdraws, :type, :string 4 | 5 | Withdraw.all.each do |withdraw| 6 | type = withdraw.currency == 'btc' ? 'Withdraws::Satoshi' : 'Withdraws::Bank' 7 | withdraw.update_column :type, type 8 | end 9 | end 10 | 11 | def down 12 | remove_column :withdraws, :type 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/controllers/private/payment_addresses_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | class PaymentAddressesController < BaseController 3 | def update 4 | account = current_user.get_account(params[:currency]) 5 | payment_address = account.payment_addresses.using 6 | unless payment_address.transactions.empty? 7 | account.gen_payment_address 8 | end 9 | redirect_to funds_path 10 | end 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /app/helpers/private/history_helper.rb: -------------------------------------------------------------------------------- 1 | module Private::HistoryHelper 2 | 3 | def trade_side(trade) 4 | trade.ask_member == current_user ? 'sell' : 'buy' 5 | end 6 | 7 | def transaction_type(t) 8 | t(".#{t.class.superclass.name}") 9 | end 10 | 11 | def transaction_txid_link(t) 12 | return t.txid unless t.currency_obj.coin? 13 | 14 | txid = t.txid || '' 15 | link_to txid, t.blockchain_url 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /bin/rspec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'rspec' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require 'pathname' 10 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require 'rubygems' 14 | require 'bundler/setup' 15 | 16 | load Gem.bin_path('rspec-core', 'rspec') 17 | -------------------------------------------------------------------------------- /config/initializers/dirty_ext.rb: -------------------------------------------------------------------------------- 1 | module ActiveModel 2 | module Dirty 3 | def changes_attributes 4 | HashWithIndifferentAccess[changed.map { |attr| [attr, __send__(attr)] }] 5 | end 6 | 7 | def changes_attributes_as_json 8 | ca, json = changes_attributes, self.as_json 9 | json.each do |key, value| 10 | ca[key.to_s] = value if ca.key?(key) 11 | end 12 | ca 13 | end 14 | end 15 | end 16 | 17 | -------------------------------------------------------------------------------- /lib/daemons/market_data_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | 7 | config[:app_name] = 'peatio:amqp:market_data' 8 | config[:script] = "#{File.expand_path('../amqp_daemon.rb', __FILE__)}" 9 | config[:ARGV] = ARGV + %w(-- slave_book market_ticker) 10 | 11 | Daemons::Rails.run config[:script], config.to_hash 12 | -------------------------------------------------------------------------------- /spec/controllers/admin/id_documents_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Admin::IdDocumentsController do 4 | let(:member) { create(:admin_member) } 5 | before { 6 | session[:member_id] = member.id 7 | two_factor_unlocked 8 | } 9 | 10 | describe 'GET index' do 11 | before { get :index } 12 | 13 | it { should respond_with :ok } 14 | it { should render_template(:index) } 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /app/views/authentications/emails/new.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for :email, url: authentications_emails_path, method: :post do |f| 2 | = f.input :address, label: t('.email_address') 3 | = f.button :submit, t('.save'), class: "btn btn-default btn-lg pull-right btn" 4 | 5 | = content_for :guide_title do 6 | h3 7 | i.fa.fa-envelope.fa-2x 8 | span = t('.title') 9 | 10 | = content_for :guide do 11 | p.text-warning 12 | = t('.warning') 13 | -------------------------------------------------------------------------------- /lib/market_constraint.rb: -------------------------------------------------------------------------------- 1 | class MarketConstraint 2 | def self.matches?(request) 3 | id = request.path_parameters[:market_id] || request.path_parameters[:id] 4 | market = Market.find_by_id(id) 5 | if market 6 | request.path_parameters[:market] = id 7 | request.path_parameters[:ask] = market.base_unit 8 | request.path_parameters[:bid] = market.quote_unit 9 | else 10 | false 11 | end 12 | end 13 | end 14 | 15 | -------------------------------------------------------------------------------- /db/migrate/20140902112641_create_simple_captcha_data.rb: -------------------------------------------------------------------------------- 1 | class CreateSimpleCaptchaData < ActiveRecord::Migration 2 | def self.up 3 | create_table :simple_captcha_data do |t| 4 | t.string :key, :limit => 40 5 | t.string :value, :limit => 6 6 | t.timestamps 7 | end 8 | 9 | add_index :simple_captcha_data, :key, :name => "idx_key" 10 | end 11 | 12 | def self.down 13 | drop_table :simple_captcha_data 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/daemons/deposit_coin_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | 7 | config[:app_name] = 'peatio:amqp:deposit_coin' 8 | config[:script] = "#{File.expand_path('../amqp_daemon.rb', __FILE__)}" 9 | config[:ARGV] = ARGV + %w(-- deposit_coin deposit_coin_address) 10 | 11 | Daemons::Rails.run config[:script], config.to_hash 12 | -------------------------------------------------------------------------------- /lib/daemons/notification_ctl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'daemons/rails/config' 4 | 5 | config = Daemons::Rails::Config.for_controller(File.expand_path(__FILE__)) 6 | 7 | config[:app_name] = 'peatio:amqp:notification' 8 | config[:script] = "#{File.expand_path('../amqp_daemon.rb', __FILE__)}" 9 | config[:ARGV] = ARGV + %w(-- sms_notification email_notification) 10 | 11 | Daemons::Rails.run config[:script], config.to_hash 12 | -------------------------------------------------------------------------------- /spec/models/matching/order_book_manager_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Matching::OrderBookManager do 4 | 5 | context ".build_order" do 6 | it "should build limit order" do 7 | order = ::Matching::OrderBookManager.build_order id: 1, market: 'btccny', ord_type: 'limit', type: 'ask', price: '1.0', volume: '1.0', timestamp: 12345 8 | order.should be_instance_of(::Matching::LimitOrder) 9 | end 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /app/assets/javascripts/funds/models/withdraw_channel.js.coffee: -------------------------------------------------------------------------------- 1 | class WithdrawChannel extends PeatioModel.Model 2 | @configure 'WithdrawChannel', 'key', 'currency', 'resource_name' 3 | 4 | @initData: (records) -> 5 | PeatioModel.Ajax.disable -> 6 | $.each records, (idx, record) -> 7 | WithdrawChannel.create(record) 8 | 9 | account: -> 10 | Account.findBy('currency', @currency) 11 | 12 | window.WithdrawChannel = WithdrawChannel 13 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /spec/controllers/application_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe ApplicationController do 4 | describe "CoinRPC::ConnectionRefusedError handling" do 5 | controller do 6 | def index 7 | raise CoinRPC::ConnectionRefusedError 8 | end 9 | end 10 | 11 | it 'renders errors/connection' do 12 | get :index 13 | expect(response).to render_template 'errors/connection' 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/factories/fund_source.rb: -------------------------------------------------------------------------------- 1 | FactoryGirl.define do 2 | factory :fund_source do 3 | extra 'bitcoin' 4 | uid { Faker::Bitcoin.address } 5 | is_locked false 6 | currency 'btc' 7 | 8 | member { create(:member) } 9 | 10 | trait :cny do 11 | extra 'bc' 12 | uid '123412341234' 13 | currency 'cny' 14 | end 15 | 16 | factory :cny_fund_source, traits: [:cny] 17 | factory :btc_fund_source 18 | end 19 | end 20 | 21 | -------------------------------------------------------------------------------- /spec/routing/api_v1_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe "routes for api v1" do 4 | 5 | it "routes tickers api" do 6 | Market.expects(:find_by_id).with('xxxyyy').returns(Market.new(id: 'xxxyyy', base_unit: 'xxx', quote_unit: 'yyy')) 7 | { get: '/api/tickers/xxxyyy' }.should be_routable 8 | 9 | Market.expects(:find_by_id).with('yyyxxx').returns(nil) 10 | { get: '/api/tickers/yyyxxx' }.should_not be_routable 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /app/models/concerns/international.rb: -------------------------------------------------------------------------------- 1 | module International 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | def method_missing(name, *args) 6 | if name =~ /(.*)_text$/ 7 | attr = $1 8 | I18n.t(i18n_text_key(attr), attr) 9 | else 10 | super(name, *args) 11 | end 12 | end 13 | 14 | def i18n_text_key(key) 15 | "#{self.class.model_name.i18n_key}.#{self.key}.#{key}" 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/views/admin/withdraws/banks/index.html.slim: -------------------------------------------------------------------------------- 1 | - unless @one_banks.empty? 2 | .panel.panel-primary 3 | .panel-heading: span = t('.one') 4 | = render partial: 'table', locals: {banks: @one_banks} 5 | 6 | - unless @all_banks.empty? 7 | .panel.panel-success 8 | .panel-heading: span = t('.all') 9 | = render partial: 'table', locals: {banks: @all_banks} 10 | 11 | - if @all_banks.empty? and @one_banks.empty? 12 | h3.text-info.text-center = t('.empty') 13 | -------------------------------------------------------------------------------- /app/views/shared/admin/_account.html.slim: -------------------------------------------------------------------------------- 1 | .panel.panel-info 2 | .panel-heading 3 | span = t('.account_info') 4 | span = " : " 5 | span = account.currency_text 6 | .panel-body 7 | dl.dl-horizontal 8 | = item_for account, :amount 9 | = item_for account, :locked 10 | = item_for account, :balance 11 | - if account.currency_obj.coin? 12 | = item_for t('.payment_address') do 13 | = account.payment_address.address 14 | -------------------------------------------------------------------------------- /db/migrate/20140320142701_create_versions.rb: -------------------------------------------------------------------------------- 1 | class CreateVersions < ActiveRecord::Migration 2 | def change 3 | create_table :versions do |t| 4 | t.string :item_type, :null => false 5 | t.integer :item_id, :null => false 6 | t.string :event, :null => false 7 | t.string :whodunnit 8 | t.text :object 9 | t.datetime :created_at 10 | end 11 | add_index :versions, [:item_type, :item_id] 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/mailers/deposit_mailer_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe DepositMailer do 4 | 5 | describe "accepted" do 6 | let(:deposit) { create :deposit } 7 | let(:mail) { 8 | deposit.submit! 9 | deposit.accept! 10 | DepositMailer.accepted(deposit.id) 11 | } 12 | 13 | it { expect(mail).not_to be_nil } 14 | it { expect(mail.subject).to match "Your deposit has been credited into your account" } 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /spec/support/rspec_matchers.rb: -------------------------------------------------------------------------------- 1 | RSpec::Matchers.define :be_d do |expected| 2 | match do |actual| 3 | if expected.kind_of? BigDecimal 4 | actual.to_d == expected 5 | elsif expected.kind_of? String 6 | actual.to_d == expected.to_d 7 | else 8 | raise "not support type #{expected.class}" 9 | end 10 | end 11 | 12 | failure_message_for_should do |actual| 13 | "expected #{actual.to_s} would be of #{expected.to_s}" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20131006183340_create_tokens.rb: -------------------------------------------------------------------------------- 1 | class CreateTokens < ActiveRecord::Migration 2 | def up 3 | create_table :tokens do |t| 4 | t.string :token 5 | t.datetime :expire_at 6 | t.integer :identity_id 7 | t.boolean :is_used 8 | t.string :type 9 | 10 | t.timestamps 11 | end 12 | 13 | add_index :tokens, [:type, :token, :expire_at, :is_used] 14 | end 15 | 16 | def down 17 | drop_table :tokens 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /db/migrate/20140302161905_create_authentications.rb: -------------------------------------------------------------------------------- 1 | class CreateAuthentications < ActiveRecord::Migration 2 | def change 3 | create_table :authentications do |t| 4 | t.string :provider 5 | t.string :uid 6 | t.string :token 7 | t.string :secret 8 | t.integer :member_id 9 | 10 | t.timestamps 11 | end 12 | 13 | add_index :authentications, :member_id 14 | add_index :authentications, [:provider, :uid] 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /db/migrate/20140920062130_add_type_to_payment_transactions.rb: -------------------------------------------------------------------------------- 1 | class AddTypeToPaymentTransactions < ActiveRecord::Migration 2 | def up 3 | add_column :payment_transactions, :type, :string, limit: 60 4 | PaymentTransaction.update_all type: 'PaymentTransaction::Default' 5 | add_index :payment_transactions, :type 6 | end 7 | 8 | def down 9 | remove_index :payment_transactions, :type 10 | remove_column :payment_transactions, :type 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20140715002401_add_more_fields_to_id_documents_table.rb: -------------------------------------------------------------------------------- 1 | class AddMoreFieldsToIdDocumentsTable < ActiveRecord::Migration 2 | def change 3 | add_column :id_documents, :birth_date, :date 4 | add_column :id_documents, :address, :text 5 | add_column :id_documents, :city, :string 6 | add_column :id_documents, :country, :string 7 | add_column :id_documents, :zipcode, :string 8 | add_column :id_documents, :id_bill_type, :integer 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/mailers/ticket_mailer.rb: -------------------------------------------------------------------------------- 1 | class TicketMailer < BaseMailer 2 | 3 | def author_notification(ticket_id) 4 | ticket = Ticket.find ticket_id 5 | @ticket_url = ticket_url(ticket) 6 | 7 | mail to: ticket.author.email 8 | end 9 | 10 | def admin_notification(ticket_id) 11 | ticket = Ticket.find ticket_id 12 | @author_email = ticket.author.email 13 | @ticket_url = admin_ticket_url(ticket) 14 | 15 | mail to: ENV['SUPPORT_MAIL'] 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /app/views/kaminari/_last_page.html.slim: -------------------------------------------------------------------------------- 1 | / Link to the "Last" page 2 | - available local variables 3 | url : url to the last page 4 | current_page : a page object for the currently displayed page 5 | total_pages : total number of pages 6 | per_page : number of items to fetch per page 7 | remote : data-remote 8 | li.next class="#{'disabled' if current_page.first?}" 9 | == link_to raw(t 'views.pagination.last'), url, {:remote => remote} 10 | ' 11 | -------------------------------------------------------------------------------- /config/logrotate.conf: -------------------------------------------------------------------------------- 1 | /home/deploy/peatio/shared/log/*.log { 2 | su deploy deploy 3 | daily 4 | missingok 5 | rotate 30 6 | compress 7 | delaycompress 8 | copytruncate 9 | create 0644 deploy deploy 10 | 11 | } 12 | 13 | /home/deploy/peatio/shared/log/*.output { 14 | su deploy deploy 15 | daily 16 | missingok 17 | rotate 30 18 | compress 19 | delaycompress 20 | copytruncate 21 | create 0644 deploy deploy 22 | 23 | } 24 | -------------------------------------------------------------------------------- /db/migrate/20131027012836_change_in_out_to_accounts.rb: -------------------------------------------------------------------------------- 1 | class ChangeInOutToAccounts < ActiveRecord::Migration 2 | def up 3 | change_column :accounts, :in, :decimal, :precision => 32, :scale => 16 4 | change_column :accounts, :out, :decimal, :precision => 32, :scale => 16 5 | end 6 | 7 | def down 8 | change_column :accounts, :in, :decimal, :precision => 32, :scale => 16 9 | change_column :accounts, :out, :decimal, :precision => 32, :scale => 16 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20140403031847_create_api_tokens.rb: -------------------------------------------------------------------------------- 1 | class CreateAPITokens < ActiveRecord::Migration 2 | def change 3 | create_table :api_tokens do |t| 4 | t.integer :member_id, null: false 5 | t.string :access_key, null: false, limit: 50 6 | t.string :secret_key, null: false, limit: 50 7 | 8 | t.timestamps 9 | end 10 | 11 | add_index :api_tokens, :access_key, unique: true 12 | add_index :api_tokens, :secret_key, unique: true 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/views/kaminari/_first_page.html.slim: -------------------------------------------------------------------------------- 1 | / Link to the "First" page 2 | - available local variables 3 | url : url to the first page 4 | current_page : a page object for the currently displayed page 5 | total_pages : total number of pages 6 | per_page : number of items to fetch per page 7 | remote : data-remote 8 | li.previous class="#{'disabled' if current_page.first?}" 9 | == link_to raw(t 'views.pagination.first'), url, :remote => remote 10 | ' 11 | -------------------------------------------------------------------------------- /spec/routing/trade_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe "routes for trade" do 4 | 5 | it "routes /markets/xxxyyy to the trade controller" do 6 | Market.expects(:find_by_id).with('xxxyyy').returns(Market.new(id: 'xxxyyy', base_unit: 'xxx', quote_unit: 'yyy')) 7 | { :get => "/markets/xxxyyy" }.should be_routable 8 | 9 | Market.expects(:find_by_id).with('yyyxxx').returns(nil) 10 | { :get => "/markets/yyyxxx" }.should_not be_routable 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /spec/services/coin_rpc_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CoinRPC do 4 | describe '#http_post_request' do 5 | it 'raises custom error on connection refused' do 6 | Net::HTTP.any_instance.stubs(:request).raises(Errno::ECONNREFUSED) 7 | 8 | rpc_client = CoinRPC::BTC.new('http://127.0.0.1:18332') 9 | 10 | expect { 11 | rpc_client.http_post_request '' 12 | }.to raise_error(CoinRPC::ConnectionRefusedError) 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/controllers/private/order_asks_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | class OrderAsksController < BaseController 3 | include Concerns::OrderCreation 4 | 5 | def create 6 | @order = OrderAsk.new(order_params(:order_ask)) 7 | order_submit 8 | end 9 | 10 | def clear 11 | @orders = OrderAsk.where(member_id: current_user.id).with_state(:wait) 12 | Ordering.new(@orders).cancel 13 | render status: 200, nothing: true 14 | end 15 | 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/controllers/private/order_bids_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | class OrderBidsController < BaseController 3 | include Concerns::OrderCreation 4 | 5 | def create 6 | @order = OrderBid.new(order_params(:order_bid)) 7 | order_submit 8 | end 9 | 10 | def clear 11 | @orders = OrderBid.where(member_id: current_user.id).with_state(:wait) 12 | Ordering.new(@orders).cancel 13 | render status: 200, nothing: true 14 | end 15 | 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/models/concerns/fund_sourceable.rb: -------------------------------------------------------------------------------- 1 | module FundSourceable 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | attr_accessor :fund_source 6 | before_validation :set_fund_source_attributes, on: :create 7 | validates :fund_source, presence: true, on: :create 8 | end 9 | 10 | def set_fund_source_attributes 11 | if fs = FundSource.find_by_id(fund_source) 12 | self.fund_extra = fs.extra 13 | self.fund_uid = fs.uid.strip 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/views/admin/withdraws/satoshis/index.html.slim: -------------------------------------------------------------------------------- 1 | - unless @one_satoshis.empty? 2 | .panel.panel-primary 3 | .panel-heading: span = t('.one') 4 | = render partial: 'table', locals: {satoshis: @one_satoshis} 5 | - unless @all_satoshis.empty? 6 | .panel.panel-success 7 | .panel-heading: span = t('.all') 8 | = render partial: 'table', locals: {satoshis: @all_satoshis} 9 | 10 | - if @all_satoshis.empty? and @one_satoshis.empty? 11 | h3.text-info.text-center = t('.empty') 12 | -------------------------------------------------------------------------------- /spec/fixtures/currencies.yml: -------------------------------------------------------------------------------- 1 | - id: 1 2 | key: dollar 3 | code: cny 4 | coin: false 5 | quick_withdraw_max: 10 6 | - id: 2 7 | key: satoshi 8 | code: btc 9 | coin: true 10 | rpc: http://bitcoinrpc:5gKAgrJv8CQr2CGUhjVbBFLSj29HnE6YGXvfykHJzS3k@127.0.0.1:18332 11 | blockchain: http://testnet.btclook.com/txn/#{txid} 12 | address_url: https://blockchain.info/address/#{address} 13 | quick_withdraw_max: 0.1 14 | - id: 4 15 | key: protoshare 16 | code: pts 17 | coin: true 18 | -------------------------------------------------------------------------------- /app/assets/javascripts/templates/ticker.jst.eco: -------------------------------------------------------------------------------- 1 | 2 | <%= @buy %> 3 | <%- formatter.trend_icon @buy_trend %> 4 | 5 | 6 | <%= @last %> 7 | <%- formatter.trend_icon @last_trend %> 8 | 9 | 10 | <%= @sell %> 11 | <%- formatter.trend_icon @sell_trend %> 12 | 13 | -------------------------------------------------------------------------------- /app/views/kaminari/_next_page.html.slim: -------------------------------------------------------------------------------- 1 | / Link to the "Next" page 2 | - available local variables 3 | url : url to the next page 4 | current_page : a page object for the currently displayed page 5 | total_pages : total number of pages 6 | per_page : number of items to fetch per page 7 | remote : data-remote 8 | li.next class="#{'disabled' if current_page.last?}" 9 | == link_to raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote 10 | ' 11 | -------------------------------------------------------------------------------- /spec/routing/verify/sms_auths_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe "sms_auths" do 4 | describe "GET /verify/sms_auth" do 5 | it { expect(get("/verify/sms_auth")).to route_to \ 6 | controller: 'verify/sms_auths', 7 | action: 'show' 8 | } 9 | end 10 | 11 | describe "PUT /verify/sms_auth" do 12 | it { expect(put("/verify/sms_auth")).to route_to \ 13 | controller: 'verify/sms_auths', 14 | action: 'update' 15 | } 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/assets/javascripts/funds/models/deposit_channel.js.coffee: -------------------------------------------------------------------------------- 1 | class DepositChannel extends PeatioModel.Model 2 | @configure 'DepositChannel', 'key', 'currency', 'min_confirm', 'max_confirm', 'bank_accounts', 'resource_name' 3 | 4 | @initData: (records) -> 5 | PeatioModel.Ajax.disable -> 6 | $.each records, (idx, record) -> 7 | DepositChannel.create(record) 8 | 9 | account: -> 10 | Account.findBy('currency', @currency) 11 | 12 | window.DepositChannel = DepositChannel 13 | 14 | -------------------------------------------------------------------------------- /app/assets/javascripts/templates/order_book_bid.jst.eco: -------------------------------------------------------------------------------- 1 | 2 |
3 | <%- formatter.amount @volume, @price %> 4 |
5 |
6 | <%- formatter.mask_fixed_volume @volume %> 7 |
8 |
9 | <%- formatter.mask_fixed_price @price %> 10 |
11 | 12 | -------------------------------------------------------------------------------- /app/assets/javascripts/templates/order_book_ask.jst.eco: -------------------------------------------------------------------------------- 1 | 2 |
3 | <%- formatter.mask_fixed_price @price %> 4 |
5 |
6 | <%- formatter.mask_fixed_volume @volume %> 7 |
8 |
9 | <%- formatter.amount @volume, @price %> 10 |
11 | 12 | -------------------------------------------------------------------------------- /app/views/kaminari/_prev_page.html.slim: -------------------------------------------------------------------------------- 1 | / Link to the "Previous" page 2 | - available local variables 3 | url : url to the previous page 4 | current_page : a page object for the currently displayed page 5 | total_pages : total number of pages 6 | per_page : number of items to fetch per page 7 | remote : data-remote 8 | li.previous class="#{'disabled' if current_page.first?}" 9 | == link_to raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote 10 | ' 11 | -------------------------------------------------------------------------------- /app/mailers/comment_mailer.rb: -------------------------------------------------------------------------------- 1 | class CommentMailer < BaseMailer 2 | 3 | def user_notification(comment_id) 4 | comment = Comment.find comment_id 5 | @ticket_url = ticket_url(comment.ticket) 6 | 7 | mail to: comment.ticket.author.email 8 | end 9 | 10 | def admin_notification(comment_id) 11 | comment = Comment.find comment_id 12 | @ticket_url = admin_ticket_url(comment.ticket) 13 | @author_email = comment.author.email 14 | 15 | mail to: ENV['SUPPORT_MAIL'] 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /app/views/private/markets/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.asks @asks 2 | json.bids @bids 3 | json.trades @trades 4 | json.market_orders @markets_orders 5 | 6 | if @member 7 | json.orders do 8 | json.wait *([@orders_wait] + Order::ATTRIBUTES) 9 | json.done @trades_done.map {|t| 10 | if t.self_trade? 11 | [t.for_notify('ask'), t.for_notify('bid')] 12 | else 13 | t.for_notify 14 | end 15 | }.flatten 16 | json.cancel *([@orders_cancel] + Order::ATTRIBUTES) 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/controllers/admin/statistic/withdraws_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | module Statistic 3 | class WithdrawsController < BaseController 4 | def show 5 | @withdraws_grid = ::Statistic::WithdrawsGrid.new(params[:statistic_withdraws_grid]) 6 | @assets = @withdraws_grid.assets 7 | 8 | @groups = { 9 | :count => @assets.all.size, 10 | :amount => @assets.sum(:amount), 11 | :fee => @assets.sum(:fee) 12 | } 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/models/fund_source.rb: -------------------------------------------------------------------------------- 1 | class FundSource < ActiveRecord::Base 2 | include Currencible 3 | 4 | attr_accessor :name 5 | 6 | paranoid 7 | 8 | belongs_to :member 9 | 10 | validates_presence_of :uid, :extra, :member 11 | 12 | def label 13 | if currency_obj.try :coin? 14 | "#{uid} (#{extra})" 15 | else 16 | [I18n.t("banks.#{extra}"), "****#{uid[-4..-1]}"].join('#') 17 | end 18 | end 19 | 20 | def as_json(options = {}) 21 | super(options).merge({label: label}) 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /app/views/identities/new.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @identity, :url => '/auth/identity/register' do |f| 2 | = f.input :email, :input_html => {:name => 'email', :autofocus => 'true'} 3 | = f.input :password, :input_html => {:name => 'password'} 4 | = f.input :password_confirmation, :input_html => {:name => 'password_confirmation'} 5 | hr.split 6 | = f.button :wrapped, t('header.signup'), cancel: root_path 7 | 8 | = content_for :guide do 9 | ul.list-unstyled 10 | li: a href='#{signin_path}'= t('.signin') 11 | -------------------------------------------------------------------------------- /db/migrate/20140326170234_change_deposits.rb: -------------------------------------------------------------------------------- 1 | class ChangeDeposits < ActiveRecord::Migration 2 | def change 3 | rename_column :deposits, :address, :fund_source_uid 4 | rename_column :deposits, :address_label, :fund_source_extra 5 | rename_column :deposits, :address_type, :channel_id 6 | rename_column :deposits, :tx_id, :txid 7 | add_column :deposits, :fee, :decimal, :precision => 32, :scale => 16, :after => :amount 8 | add_column :deposits, :aasm_state, :string, :after => :state 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /.travis.currencies.yml: -------------------------------------------------------------------------------- 1 | - id: 1 2 | key: renminbi 3 | code: cny 4 | coin: false 5 | assets: 6 | balance: 92343242.56 7 | accounts: 8 | - 9 | bank: '招商银行' 10 | address: '6225 0885 6022 3501' 11 | password: '111111' 12 | tel: '95555' 13 | - id: 2 14 | key: satoshi 15 | code: btc 16 | coin: true 17 | rpc: http://username:password@127.0.0.1:18332 18 | assets: 19 | balance: 333333 20 | accounts: 21 | - 22 | address: 1dice8EMZmqKvrGE4Qc9bUFf9PX3xaYDp 23 | -------------------------------------------------------------------------------- /app/assets/stylesheets/vars/_basic.css.scss: -------------------------------------------------------------------------------- 1 | /* peatio exchange site vars 2 | -------------------------------------------------------------- */ 3 | 4 | $brand-width: 140px; 5 | $funds-panel-height: 750px; 6 | 7 | $footer-bg: $body-bg; 8 | $footer-height: 120px; 9 | $footer-color: $gray-light; 10 | $footer-border: #ddd; 11 | 12 | $content-split: #ddd; 13 | 14 | $btn-gutter-width: 20px; 15 | $text-gutter-width: 5px; 16 | $icon-gutter-width: 5px; 17 | 18 | $up-bg: rgba(89, 132, 50, 1.0); 19 | $down-bg: rgba(159, 49, 27, 1.0); 20 | -------------------------------------------------------------------------------- /app/helpers/private/tickets_helper.rb: -------------------------------------------------------------------------------- 1 | module Private::TicketsHelper 2 | def member_tittle(author) 3 | if current_user == author 4 | I18n.t('private.tickets.me') 5 | else 6 | I18n.t('private.tickets.supporter') 7 | end 8 | end 9 | 10 | def close_open_toggle_link 11 | if params[:closed] 12 | link_to t('private.tickets.view_open_tickets'), tickets_path 13 | else 14 | link_to t('private.tickets.view_closed_tickets'), tickets_path(closed: true) 15 | end 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /config/initializers/check_env.rb: -------------------------------------------------------------------------------- 1 | environments = %w( 2 | PUSHER_APP 3 | PUSHER_KEY 4 | PUSHER_SECRET 5 | ) 6 | 7 | environments.select! do |key| 8 | ENV[key] =~ /^YOUR/ 9 | end 10 | 11 | unless environments.empty? 12 | puts "====================== WARNING ======================" 13 | puts " please check below config in config/application.yml" 14 | puts "" 15 | environments.each do |key| puts " #{key}" end 16 | puts "=====================================================" 17 | raise "config missing" 18 | end 19 | -------------------------------------------------------------------------------- /app/grids/proofs_grid.rb: -------------------------------------------------------------------------------- 1 | class ProofsGrid 2 | 3 | include Datagrid 4 | 5 | scope do 6 | Proof.order('id desc') 7 | end 8 | 9 | filter(:id, :integer) 10 | filter(:created_at, :date, :range => true) 11 | 12 | column(:id) 13 | column(:currency) 14 | column(:balance) 15 | column(:sum) 16 | column(:created_at) do |model| 17 | model.created_at.to_date 18 | end 19 | column :actions, html: true, header: '' do |proof| 20 | link_to I18n.t('actions.edit'), edit_admin_proof_path(proof) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /app/controllers/admin/id_documents_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class IdDocumentsController < BaseController 3 | load_and_authorize_resource 4 | 5 | def index 6 | @id_documents = @id_documents.order(:updated_at).reverse_order.page params[:page] 7 | end 8 | 9 | def show 10 | end 11 | 12 | def update 13 | @id_document.approve! if params[:approve] 14 | @id_document.reject! if params[:reject] 15 | 16 | redirect_to admin_id_document_path(@id_document) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/api/api_v2/auth/utils_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe APIv2::Auth::Utils do 4 | Utils = APIv2::Auth::Utils 5 | 6 | context '.generate_access_key' do 7 | it "should be a string longer than 40 characters" do 8 | Utils.generate_access_key.should match(/^[a-zA-Z0-9]{40}$/) 9 | end 10 | end 11 | 12 | context '.generate_secret_key' do 13 | it "should be a string longer than 40 characters" do 14 | Utils.generate_secret_key.should match(/^[a-zA-Z0-9]{40}$/) 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/factories/payment_addresses.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryGirl.define do 4 | factory :payment_address do 5 | address "MyString" 6 | account { create(:member).get_account(:cny) } 7 | 8 | trait :btc_address do 9 | address { Faker::Bitcoin.address } 10 | account { create(:member).get_account(:btc) } 11 | currency Currency.find_by_code('btc').id 12 | end 13 | 14 | factory :btc_payment_address, traits: [:btc_address] 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/helpers/private/assets_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | # Specs in this file have access to a helper object that includes 4 | # the Private::AssetsHelper. For example: 5 | # 6 | # describe Private::AssetsHelper do 7 | # describe "string concat" do 8 | # it "concats two strings with spaces" do 9 | # expect(helper.concat_strings("this","that")).to eq("this that") 10 | # end 11 | # end 12 | # end 13 | describe Private::AssetsHelper do 14 | pending "add some examples to (or delete) #{__FILE__}" 15 | end 16 | -------------------------------------------------------------------------------- /spec/models/payment_address_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe PaymentAddress do 4 | 5 | context ".create" do 6 | before do 7 | PaymentAddress.any_instance.stubs(:id).returns(1) 8 | end 9 | 10 | it "generate address after commit" do 11 | AMQPQueue.expects(:enqueue) 12 | .with(:deposit_coin_address, 13 | {payment_address_id: 1, currency: 'btc'}, 14 | {persistent: true}) 15 | 16 | PaymentAddress.create currency: :btc 17 | end 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /spec/models/proof_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Proof do 4 | describe '#asset_sum' do 5 | it 'aggregates address balances' do 6 | proof = Proof.new(addresses: [ 7 | {"address"=>"1HjfnJpQmANtuW7yr1ggeDfyfe1kDK7rxx", "balance"=>1}, 8 | {"address"=>"1HjfnJpQmANtuW7yr1ggeDfyfe1kDK7rm3", "balance"=>2.00005}, 9 | {"address"=>"1dice97ECuByXAvqXpaYzSaQuPVvrtmz6", "balance"=>5.84489237} 10 | ]) 11 | 12 | expect(proof.asset_sum).to eq(8.84494237) 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/controllers/members_controller.rb: -------------------------------------------------------------------------------- 1 | class MembersController < ApplicationController 2 | before_filter :auth_member! 3 | before_filter :auth_no_initial! 4 | 5 | def edit 6 | @member = current_user 7 | end 8 | 9 | def update 10 | @member = current_user 11 | 12 | if @member.update_attributes(member_params) 13 | redirect_to forum_path 14 | else 15 | render :edit 16 | end 17 | end 18 | 19 | private 20 | def member_params 21 | params.required(:member).permit(:display_name) 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /app/views/private/markets/_settings.html.slim: -------------------------------------------------------------------------------- 1 | li#settings.dropdown 2 | a.dropdown-toggle href="#" data-toggle="dropdown" 3 | i.fa.fa-gears 4 | span = t('.title') 5 | .dropdown-menu 6 | table.table: tbody 7 | tr 8 | td: span = t('.sound') 9 | td: span: input type="checkbox" name="sound-checkbox" data-size='mini' data-on-color='success' 10 | tr 11 | td: span = t('.notification') 12 | td: span: input type="checkbox" name="notification-checkbox" data-size='mini' data-on-color='success' 13 | -------------------------------------------------------------------------------- /app/views/datagrid/_order_for.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= link_to( 3 | I18n.t("datagrid.table.order.asc", :default => "↑".html_safe).html_safe, 4 | url_for(grid.param_name => grid.as_query.merge(:order => column.name, :descending => false)), 5 | :class => "asc") %> 6 | <%= link_to( 7 | I18n.t("datagrid.table.order.desc", :default => "↓".html_safe).html_safe, 8 | url_for(grid.param_name => grid.as_query.merge(:order => column.name, :descending => true )), 9 | :class => "desc") %> 10 |
11 | -------------------------------------------------------------------------------- /app/api/api_v2/tickers.rb: -------------------------------------------------------------------------------- 1 | module APIv2 2 | class Tickers < Grape::API 3 | helpers ::APIv2::NamedParams 4 | 5 | desc 'Get ticker of all markets.' 6 | get "/tickers" do 7 | Market.all.inject({}) do |h, m| 8 | h[m.id] = format_ticker Global[m.id].ticker 9 | h 10 | end 11 | end 12 | 13 | desc 'Get ticker of specific market.' 14 | params do 15 | use :market 16 | end 17 | get "/tickers/:market" do 18 | format_ticker Global[params[:market]].ticker 19 | end 20 | 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /app/assets/javascripts/lib/tiny-pubsub.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Tiny Pub/Sub 3 | * https://github.com/cowboy/jquery-tiny-pubsub 4 | * 5 | * Copyright (c) 2013 "Cowboy" Ben Alman 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | (function($) { 10 | 11 | var o = $({}); 12 | 13 | $.subscribe = function() { 14 | o.on.apply(o, arguments); 15 | }; 16 | 17 | $.unsubscribe = function() { 18 | o.off.apply(o, arguments); 19 | }; 20 | 21 | $.publish = function() { 22 | o.trigger.apply(o, arguments); 23 | }; 24 | 25 | }(jQuery)); 26 | -------------------------------------------------------------------------------- /app/controllers/private/pusher_controller.rb: -------------------------------------------------------------------------------- 1 | require "openssl" 2 | 3 | module Private 4 | class PusherController < BaseController 5 | protect_from_forgery :except => :auth 6 | 7 | def auth 8 | sn = params[:channel_name].split('-', 2).last 9 | if current_user && current_user.sn == sn 10 | response = Pusher[params[:channel_name]].authenticate(params[:socket_id]) 11 | render :json => response 12 | else 13 | render :text => "Forbidden", :status => '403' 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/mailers/withdraw_mailer.rb: -------------------------------------------------------------------------------- 1 | class WithdrawMailer < BaseMailer 2 | 3 | def submitted(withdraw_id) 4 | set_mail(withdraw_id) 5 | end 6 | 7 | def processing(withdraw_id) 8 | set_mail(withdraw_id) 9 | end 10 | 11 | def done(withdraw_id) 12 | set_mail(withdraw_id) 13 | end 14 | 15 | def withdraw_state(withdraw_id) 16 | set_mail(withdraw_id) 17 | end 18 | 19 | private 20 | 21 | def set_mail(withdraw_id) 22 | @withdraw = Withdraw.find withdraw_id 23 | mail to: @withdraw.member.email 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /app/views/kaminari/_page.html.slim: -------------------------------------------------------------------------------- 1 | / Link showing page number 2 | - available local variables 3 | page : a page object for "this" page 4 | url : url to this page 5 | current_page : a page object for the currently displayed page 6 | total_pages : total number of pages 7 | per_page : number of items to fetch per page 8 | remote : data-remote 9 | li class="page#{' active' if page.current?}" 10 | == link_to page, url, {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil} 11 | ' 12 | -------------------------------------------------------------------------------- /spec/models/fund_source_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe FundSource do 4 | 5 | context '#label' do 6 | context 'for btc' do 7 | let(:fund_source) { build(:btc_fund_source) } 8 | subject { fund_source } 9 | 10 | its(:label) { should eq("#{fund_source.uid} (bitcoin)") } 11 | end 12 | 13 | context 'bank' do 14 | let(:fund_source) { build(:cny_fund_source) } 15 | subject { fund_source } 16 | 17 | its(:label) { should eq('Bank of China#****1234') } 18 | end 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /app/views/private/assets/index.html.slim: -------------------------------------------------------------------------------- 1 | = content_for :frame do 2 | .container 3 | ul.nav.nav-justified.assets-nav 4 | li.active data-scroll-nav='0' 5 | a = t('.liability-proof') 6 | li data-scroll-nav='1' 7 | a = t('.btc-assets') 8 | li data-scroll-nav='2' 9 | a = t('.cny-assets') 10 | 11 | - if current_user 12 | div data-scroll-index=0 = render 'liability_proof' 13 | 14 | div data-scroll-index=1 = render 'btc_assets' 15 | div data-scroll-index=2 = render 'cny_assets' 16 | 17 | -------------------------------------------------------------------------------- /db/migrate/20140714143823_unread_migration.rb: -------------------------------------------------------------------------------- 1 | class UnreadMigration < ActiveRecord::Migration 2 | def self.up 3 | create_table :read_marks, :force => true do |t| 4 | t.integer :readable_id 5 | t.integer :member_id, :null => false 6 | t.string :readable_type, :null => false, :limit => 20 7 | t.datetime :timestamp 8 | end 9 | 10 | add_index :read_marks, [:member_id] 11 | add_index :read_marks, [:readable_type, :readable_id] 12 | 13 | end 14 | 15 | def self.down 16 | drop_table :read_marks 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/assets/javascripts/component_ui/order_total.js.coffee: -------------------------------------------------------------------------------- 1 | @OrderTotalUI = flight.component -> 2 | flight.compose.mixin @, [OrderInputMixin] 3 | 4 | @attributes 5 | precision: gon.market.bid.fixed 6 | variables: 7 | input: 'total' 8 | known: 'price' 9 | output: 'volume' 10 | 11 | @onOutput = (event, order) -> 12 | total = order.price.times order.volume 13 | 14 | @changeOrder @value unless @validateRange(total) 15 | @setInputValue @value 16 | 17 | order.total = @value 18 | @trigger 'place_order::order::updated', order 19 | -------------------------------------------------------------------------------- /app/controllers/private/deposits/base_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | module Deposits 3 | class BaseController < ::Private::BaseController 4 | layout 'app' 5 | before_action :channel 6 | before_action :auth_activated! 7 | before_action :auth_verified! 8 | 9 | def channel 10 | @channel ||= DepositChannel.find_by_key(self.controller_name.singularize) 11 | end 12 | 13 | def model_kls 14 | "deposits/#{self.controller_name.singularize}".camelize.constantize 15 | end 16 | end 17 | end 18 | end 19 | 20 | -------------------------------------------------------------------------------- /db/migrate/20130901010953_create_orders.rb: -------------------------------------------------------------------------------- 1 | class CreateOrders < ActiveRecord::Migration 2 | def change 3 | create_table :orders do |t| 4 | t.string :bid 5 | t.string :ask 6 | t.string :currency 7 | t.decimal :price, :precision => 32, :scale => 16 8 | t.decimal :volume, :precision => 32, :scale => 16 9 | t.decimal :origin_volume, :precision => 32, :scale => 16 10 | t.string :state 11 | t.datetime :done_at 12 | t.string :type 13 | t.integer :member_id 14 | t.timestamps 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/support/deposit_helper.rb: -------------------------------------------------------------------------------- 1 | def deposit admin_identity, member, amount 2 | login admin_identity 3 | click_on 'admin' 4 | 5 | # this part is handled by a google extension 6 | query = {deposit: { txid: "deposit_#{Time.now.to_i}", 7 | sn: member.sn, 8 | fund_uid: identity.email, 9 | fund_extra: member.name, 10 | amount: amount }} 11 | 12 | visit(new_admin_currency_deposit_path(query)) 13 | 14 | within 'form' do 15 | click_on I18n.t('helpers.submit.deposit.create') 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/controllers/authentications/weibo_accounts_controller.rb: -------------------------------------------------------------------------------- 1 | module Authentications 2 | class WeiboAccountsController < ApplicationController 3 | before_action :auth_member! 4 | 5 | def destroy 6 | if current_user.authentications.count <= 1 7 | flash[:alert] = t("authentications.weibo.destroy.last_auth_alert") 8 | else 9 | if current_user.remove_auth('weibo') 10 | flash[:notice] = t("authentications.weibo.destroy.unbind_success") 11 | end 12 | end 13 | redirect_to settings_path 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/views/layouts/landing.html.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | html lang="en" 3 | head 4 | link rel="shortcut icon" href="/favicon.ico" 5 | = include_gon 6 | = stylesheet_link_tag "application", :media => "all" 7 | = javascript_include_tag "application" 8 | = javascript_include_tag "locales/#{I18n.locale}" 9 | = render 'shared/html5' 10 | = render 'shared/meta' 11 | = csrf_meta_tags 12 | body id='#{body_id}' data-lang="#{locale_name}" 13 | #wrap 14 | = render 'shared/alert' 15 | = yield 16 | #push 17 | = render 'shared/footer' 18 | -------------------------------------------------------------------------------- /spec/models/token/activation_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Token::Activation do 4 | let(:member) { create :member } 5 | let(:activation) { create :activation, member: member } 6 | 7 | describe '#confirm!' do 8 | before { activation.confirm! } 9 | 10 | it { expect(member).to be_activated } 11 | end 12 | 13 | describe 'send_token after creation' do 14 | let(:mail) { ActionMailer::Base.deliveries.last } 15 | 16 | before { activation } 17 | 18 | it { expect(mail.subject).to match('Account Activation') } 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /app/controllers/admin/statistic/deposits_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | module Statistic 3 | class DepositsController < BaseController 4 | prepend_before_filter :load_grid 5 | 6 | def show 7 | @groups = { 8 | :count => @assets.all.size, 9 | :amount => @assets.sum(:amount) 10 | } 11 | end 12 | 13 | private 14 | def load_grid 15 | @deposits_grid = ::Statistic::DepositsGrid.new(params[:statistic_deposits_grid]) 16 | @assets = @deposits_grid.assets 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /db/migrate/20141119155043_create_running_accounts.rb: -------------------------------------------------------------------------------- 1 | class CreateRunningAccounts < ActiveRecord::Migration 2 | def change 3 | create_table :running_accounts do |t| 4 | t.integer :category 5 | t.decimal :income, precision: 32, scale: 16, null: false, default: 0 6 | t.decimal :expenses, precision: 32, scale: 16, null: false, default: 0 7 | t.integer :currency 8 | t.references :member, index: true 9 | t.references :source, polymorphic: true, index: true 10 | t.string :note 11 | 12 | t.timestamps 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/daemons/hot_wallets.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # You might want to change this 4 | ENV["RAILS_ENV"] ||= "development" 5 | 6 | root = File.expand_path(File.dirname(__FILE__)) 7 | root = File.dirname(root) until File.exists?(File.join(root, 'config')) 8 | Dir.chdir(root) 9 | 10 | require File.join(root, "config", "environment") 11 | 12 | $running = true 13 | Signal.trap("TERM") do 14 | $running = false 15 | end 16 | 17 | while($running) do 18 | Currency.all.each do |currency| 19 | currency.refresh_balance if currency.coin? 20 | end 21 | 22 | sleep 5 23 | end 24 | -------------------------------------------------------------------------------- /spec/mailers/member_mailer_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe MemberMailer do 4 | describe "notify_signin" do 5 | let(:member) { create :member } 6 | let(:mail) { MemberMailer.notify_signin(member.id) } 7 | 8 | it "renders the headers" do 9 | mail.subject.should eq("[PEATIO] You have just signed in") 10 | mail.to.should eq([member.email]) 11 | mail.from.should eq([ENV['SYSTEM_MAIL_FROM']]) 12 | end 13 | 14 | it "renders the body" do 15 | mail.body.encoded.should match("signed in") 16 | end 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /app/uploaders/file_uploader.rb: -------------------------------------------------------------------------------- 1 | class FileUploader < CarrierWave::Uploader::Base 2 | def store_dir 3 | "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" 4 | end 5 | 6 | def filename 7 | "#{secure_token}.#{file.extension}" if original_filename.present? 8 | end 9 | 10 | def extension_white_list 11 | %w(jpg jpeg gif png pdf) 12 | end 13 | 14 | protected 15 | 16 | def secure_token 17 | var = :"@#{mounted_as}_secure_token" 18 | model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/views/private/assets/_cny_assets.html.slim: -------------------------------------------------------------------------------- 1 | .panel.panel-default 2 | .panel-body 3 | .row 4 | #guide.col-xs-8 5 | h3 = t('.title') 6 | p.text-ignore = t('.intro') 7 | #content.col-xs-16 8 | .jumbotron 9 | .row 10 | .col-xs-offset-4.col-xs-16 11 | span.pull-left = t('.total') 12 | span.pull-right 13 | == t("currency.icon.cny") 14 | = @cny_proof.balance 15 | .clearfix 16 | 17 | == t('.description', @cny_assets['accounts'].first.symbolize_keys) 18 | -------------------------------------------------------------------------------- /db/migrate/20140707115022_create_audit_logs.rb: -------------------------------------------------------------------------------- 1 | class CreateAuditLogs < ActiveRecord::Migration 2 | def change 3 | create_table :audit_logs do |t| 4 | # Common Properties 5 | t.string :type 6 | t.integer :operator_id 7 | t.timestamps 8 | t.integer :auditable_id 9 | t.string :auditable_type 10 | 11 | # For Deposit and Withdraw 12 | t.string :source_state 13 | t.string :target_state 14 | end 15 | 16 | add_index :audit_logs, :operator_id 17 | add_index :audit_logs, [:auditable_id, :auditable_type] 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [peatio.serverenyml] 5 | file_filter = config/locales/server..yml 6 | source_file = config/locales/server.en.yml 7 | source_lang = en 8 | trans.zh_CN = config/locales/server.zh-CN.yml 9 | trans.zh_TW = config/locales/server.zh-TW.yml 10 | type = YML 11 | 12 | [peatio.clientenyml] 13 | file_filter = config/locales/client..yml 14 | source_file = config/locales/client.en.yml 15 | source_lang = en 16 | trans.zh_CN = config/locales/client.zh-CN.yml 17 | trans.zh_TW = config/locales/client.zh-TW.yml 18 | type = YML 19 | 20 | -------------------------------------------------------------------------------- /app/controllers/concerns/deposits/ctrl_coinable.rb: -------------------------------------------------------------------------------- 1 | module Deposits 2 | module CtrlCoinable 3 | extend ActiveSupport::Concern 4 | 5 | def gen_address 6 | account = current_user.get_account(channel.currency) 7 | if !account.payment_address.transactions.empty? 8 | @address = account.payment_addresses.create currency: account.currency 9 | @address.gen_address if @address.address.blank? 10 | render nothing: true 11 | else 12 | render text: t('.require_transaction'), status: 403 13 | end 14 | 15 | end 16 | 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/observers/transfer_observer_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe TransferObserver do 4 | describe "#after_update" do 5 | let!(:member) { create(:member) } 6 | let!(:deposit) { create(:deposit, aasm_state: 'submitted')} 7 | before do 8 | TransferObserver.any_instance.stubs(:current_user).returns(member) 9 | end 10 | 11 | subject { deposit.update_attributes(aasm_state: 'accepted')} 12 | 13 | it "should create the audit log" do 14 | expect { subject }.to change{ Audit::TransferAuditLog.count }.by(1) 15 | 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/assets/javascripts/templates/market_trade.jst.eco: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%- formatter.trade_time @date %> 4 | 5 | 6 | <%- formatter.short_trade @type %> 7 | 8 | 9 | <%= formatter.fix_bid @price %> 10 | 11 | 12 | <%= formatter.fix_ask @amount %> 13 | 14 | 15 | <%- formatter.amount @amount, @price %> 16 | 17 | 18 | -------------------------------------------------------------------------------- /db/migrate/20130629015414_create_identities.rb: -------------------------------------------------------------------------------- 1 | class CreateIdentities < ActiveRecord::Migration 2 | def change 3 | create_table :identities do |t| 4 | t.string :email 5 | t.string :password_digest 6 | t.boolean :is_active 7 | t.integer :retry_count 8 | t.boolean :is_locked 9 | t.datetime :locked_at 10 | t.datetime :last_verify_at 11 | t.timestamps 12 | end 13 | 14 | create_table :two_factors do |t| 15 | t.integer :identity_id 16 | t.string :otp_secret 17 | t.datetime :last_verify_at 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/controllers/private/withdraws/base_controller.rb: -------------------------------------------------------------------------------- 1 | module Private 2 | module Withdraws 3 | class BaseController < ::Private::BaseController 4 | before_action :channel 5 | before_action :auth_activated! 6 | before_action :auth_verified! 7 | before_action :two_factor_activated! 8 | 9 | def channel 10 | @channel ||= WithdrawChannel.find_by_key(self.controller_name.singularize) 11 | end 12 | 13 | def model_kls 14 | "withdraws/#{self.controller_name.singularize}".camelize.constantize 15 | end 16 | 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/models/matching/price_level.rb: -------------------------------------------------------------------------------- 1 | module Matching 2 | class PriceLevel 3 | 4 | attr :price, :orders 5 | 6 | def initialize(price) 7 | @price = price 8 | @orders = [] 9 | end 10 | 11 | def top 12 | @orders.first 13 | end 14 | 15 | def empty? 16 | @orders.empty? 17 | end 18 | 19 | def add(order) 20 | @orders << order 21 | end 22 | 23 | def remove(order) 24 | @orders.delete_if {|o| o.id == order.id } 25 | end 26 | 27 | def find(id) 28 | @orders.find {|o| o.id == id } 29 | end 30 | 31 | end 32 | end 33 | --------------------------------------------------------------------------------