From fb6565993143a122f990efd16392c72a6a414d7b Mon Sep 17 00:00:00 2001 From: Rabbit Date: Mon, 13 Jan 2025 13:40:50 +0800 Subject: [PATCH] Feat/rgbpp top holders (#2384) feat: add rgbpp top holders --- ...rb => rgb_assets_statistics_controller.rb} | 2 +- .../api/v2/rgb_top_holders_controller.rb | 45 +++++++++++++++++++ config/routes/v2.rb | 3 +- 3 files changed, 48 insertions(+), 2 deletions(-) rename app/controllers/api/v2/{rgbpp_assets_statistics_controller.rb => rgb_assets_statistics_controller.rb} (93%) create mode 100644 app/controllers/api/v2/rgb_top_holders_controller.rb diff --git a/app/controllers/api/v2/rgbpp_assets_statistics_controller.rb b/app/controllers/api/v2/rgb_assets_statistics_controller.rb similarity index 93% rename from app/controllers/api/v2/rgbpp_assets_statistics_controller.rb rename to app/controllers/api/v2/rgb_assets_statistics_controller.rb index ac8303481..c93d9cd6b 100644 --- a/app/controllers/api/v2/rgbpp_assets_statistics_controller.rb +++ b/app/controllers/api/v2/rgb_assets_statistics_controller.rb @@ -1,6 +1,6 @@ module Api module V2 - class RgbppAssetsStatisticsController < BaseController + class RgbAssetsStatisticsController < BaseController def index expires_in 15.minutes, public: true, stale_while_revalidate: 5.minutes, stale_if_error: 5.minutes diff --git a/app/controllers/api/v2/rgb_top_holders_controller.rb b/app/controllers/api/v2/rgb_top_holders_controller.rb new file mode 100644 index 000000000..fd8f2e1c5 --- /dev/null +++ b/app/controllers/api/v2/rgb_top_holders_controller.rb @@ -0,0 +1,45 @@ +module Api + module V2 + class RgbTopHoldersController < BaseController + def show + expires_in 15.minutes, public: true, stale_while_revalidate: 5.minutes, stale_if_error: 5.minutes + + udt = Udt.find_by(udt_type: %i[xudt xudt_compatible], type_hash: params[:id]) + return head :not_found unless udt + + merged_array = btc_top_holders(udt) + ckb_top_holders(udt) + top10 = merged_array.sort_by { |item| -item[:amount].to_f }.take(10) + + render json: { data: top10 } + end + + private + + def btc_top_holders(udt) + result = BitcoinAddressMapping. + joins("LEFT OUTER JOIN udt_accounts ON udt_accounts.address_id = bitcoin_address_mappings.ckb_address_id"). + where(udt_accounts: { udt_id: udt.id }).where("udt_accounts.amount > 0"). + group("bitcoin_address_mappings.bitcoin_address_id"). + select("bitcoin_address_mappings.bitcoin_address_id, SUM(udt_accounts.amount) AS total_amount"). + order("total_amount DESC").limit(10) + + result.map do |record| + address_hash = BitcoinAddress.find_by(id: record.bitcoin_address_id).address_hash + position_ratio = udt.total_amount.zero? ? 0 : format("%.5f", record.total_amount.to_f / udt.total_amount) + { address_hash:, amount: record.total_amount.to_s, position_ratio: position_ratio.to_s, network: "btc" } + end + end + + def ckb_top_holders(udt) + UdtAccount.joins("LEFT OUTER JOIN bitcoin_address_mappings ON udt_accounts.address_id = bitcoin_address_mappings.ckb_address_id"). + where(udt_accounts: { udt_id: udt.id}, bitcoin_address_mappings: { bitcoin_address_id: nil }). + where("udt_accounts.amount > 0"). + order("udt_accounts.amount desc").limit(10).map do |udt_account| + address_hash = udt_account.address.address_hash + position_ratio = udt.total_amount.zero? ? 0 : format("%.5f", udt_account.amount.to_f / udt.total_amount) + { address_hash:, amount: udt_account.amount.to_s, position_ratio: position_ratio.to_s, network: "ckb" } + end + end + end + end +end diff --git a/config/routes/v2.rb b/config/routes/v2.rb index a72b59b95..250a23fd7 100644 --- a/config/routes/v2.rb +++ b/config/routes/v2.rb @@ -107,6 +107,7 @@ resources :graph_channels, only: :index end resources :udt_hourly_statistics, only: :show - resources :rgbpp_assets_statistics, only: :index + resources :rgb_assets_statistics, only: :index + resources :rgb_top_holders, only: :show end end