Skip to content

Commit

Permalink
optimize: market. (#267)
Browse files Browse the repository at this point in the history
  • Loading branch information
blowcowbeer authored Jun 26, 2024
1 parent 8dbfffa commit 4ff47cd
Show file tree
Hide file tree
Showing 12 changed files with 545 additions and 347 deletions.
129 changes: 129 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
## Chain
* [3.1 统计交易量](#3.1)
* [3.2 地址总量](#3.2)

## Asset
* [4.1 获取资产信息](#4.1)

## 其他
* [5.1 获取FRA市场信息](#5.1)

<h3 id="1.1">1.1 根据交易哈希获取交易</h3>

* `GET /api/tx`
Expand Down Expand Up @@ -522,3 +526,128 @@
}]
}
```

<h3 id="5.1">5.1 获取FRA市场信息</h3>

* `GET /api/coins/:id/market_chart`


| 参数 | 类型 | 必传 | 说明 |
|-------------|--------|----|--------------------|
| id | string | Y | 币种 |
| vs_currency | string | N | 计价货币,缺省值为"usd" |
| interval | string | N | 时间间隔,缺省为"daily" |
| days | number | N | 天数,缺省值为7,即列表中有7条数据 |

* Request: `/api/coins/findora/market_chart?vs_currency=usd&days=7&interval=daily`
* Response:
```json
{
"code":200,
"message":"",
"data":{
"market_caps":[
[
1718841600000,
12076960.654386723
],
[
1718928000000,
12502620.19204148
],
[
1719014400000,
12518619.67665847
],
[
1719100800000,
12756431.19328877
],
[
1719187200000,
12478551.446567249
],
[
1719273600000,
10902644.116966683
],
[
1719360000000,
10841063.701286633
],
[
1719415382000,
10689314.764516797
]
],
"prices":[
[
1718841600000,
0.0010421953662283902
],
[
1718928000000,
0.0010786349850002864
],
[
1719014400000,
0.001075916897093825
],
[
1719100800000,
0.0011022425089767258
],
[
1719187200000,
0.0010769704462329777
],
[
1719273600000,
0.0009381464216474152
],
[
1719360000000,
0.0009336248576932378
],
[
1719415382000,
0.0009218445536291912
]
],
"total_volumes":[
[
1718841600000,
255031.1386785886
],
[
1718928000000,
77237.26698759367
],
[
1719014400000,
353159.57762952574
],
[
1719100800000,
439593.60549064353
],
[
1719187200000,
430793.7394006403
],
[
1719273600000,
357770.9091104639
],
[
1719360000000,
466249.0112276624
],
[
1719415382000,
480190.8136610133
]
]
}
}
```
3 changes: 2 additions & 1 deletion explorer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::service::v2::block::{
};
use crate::service::v2::claim::{get_claim_by_tx_hash, get_claims};
use crate::service::v2::delegation::{get_delegation_by_tx_hash, get_delegations};
use crate::service::v2::other::{get_address_count, get_statistics, get_tx_distribute};
use crate::service::v2::other::{get_address_count, get_market, get_statistics, get_tx_distribute};
use crate::service::v2::prism_evm_to_native::{get_e2n_by_tx_hash, get_e2n_txs};
use crate::service::v2::prism_native_to_evm::{get_n2e_by_tx_hash, get_n2e_txs};
use crate::service::v2::transaction::{get_tx_by_hash, get_txs};
Expand Down Expand Up @@ -83,6 +83,7 @@ async fn main() -> Result<()> {
.route("/api/e2ns", get(get_e2n_txs))
// asset
.route("/api/assets", get(get_assets))
.route("/api/coins/:id/market_chart", get(get_market))
.layer(cors)
.with_state(app_state);
let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
Expand Down
84 changes: 75 additions & 9 deletions explorer/src/service/error.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,81 @@
use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};

pub type Result<T> = core::result::Result<T, (StatusCode, String)>;
#[derive(Debug)]
pub enum ExplorerError {
Custom(String),
DBError(sqlx::Error),
IOError(std::io::Error),
TomlDeError(toml::de::Error),
HexError(rustc_hex::FromHexError),
ParseUrlError(url::ParseError),
SerdeJsonError(serde_json::Error),
ReqwestError(reqwest::Error),
}

impl From<reqwest::Error> for ExplorerError {
fn from(e: reqwest::Error) -> Self {
ExplorerError::ReqwestError(e)
}
}

impl From<serde_json::Error> for ExplorerError {
fn from(e: serde_json::Error) -> Self {
ExplorerError::SerdeJsonError(e)
}
}

impl From<String> for ExplorerError {
fn from(e: String) -> Self {
ExplorerError::Custom(e)
}
}

impl From<url::ParseError> for ExplorerError {
fn from(e: url::ParseError) -> Self {
ExplorerError::ParseUrlError(e)
}
}

pub fn internal_error<E>(err: E) -> (StatusCode, String)
where
E: std::error::Error,
{
let err_msg = err.to_string();
if err_msg.contains("no rows") {
return (StatusCode::NOT_FOUND, "not found".to_string());
impl From<rustc_hex::FromHexError> for ExplorerError {
fn from(e: rustc_hex::FromHexError) -> Self {
ExplorerError::HexError(e)
}
}

impl From<std::io::Error> for ExplorerError {
fn from(e: std::io::Error) -> Self {
ExplorerError::IOError(e)
}
}

impl From<toml::de::Error> for ExplorerError {
fn from(e: toml::de::Error) -> Self {
ExplorerError::TomlDeError(e)
}
}

(StatusCode::INTERNAL_SERVER_ERROR, err_msg)
impl From<sqlx::Error> for ExplorerError {
fn from(e: sqlx::Error) -> Self {
ExplorerError::DBError(e)
}
}

pub type Result<T> = core::result::Result<T, ExplorerError>;

impl IntoResponse for ExplorerError {
fn into_response(self) -> Response {
let err_msg = match self {
ExplorerError::Custom(e) => e,
ExplorerError::DBError(e) => e.to_string(),
ExplorerError::IOError(e) => e.to_string(),
ExplorerError::TomlDeError(e) => e.to_string(),
ExplorerError::HexError(e) => e.to_string(),
ExplorerError::ParseUrlError(e) => e.to_string(),
ExplorerError::SerdeJsonError(e) => e.to_string(),
ExplorerError::ReqwestError(e) => e.to_string(),
};

(StatusCode::INTERNAL_SERVER_ERROR, err_msg).into_response()
}
}
30 changes: 13 additions & 17 deletions explorer/src/service/v2/asset.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::service::error::{internal_error, Result};
use crate::service::error::Result;
use crate::service::QueryResult;
use crate::AppState;
use axum::extract::{Query, State};
Expand Down Expand Up @@ -32,7 +32,7 @@ pub async fn get_assets(
State(state): State<Arc<AppState>>,
Query(params): Query<GetAssetsParams>,
) -> Result<Json<QueryResult<Vec<AssetResponse>>>> {
let mut conn = state.pool.acquire().await.map_err(internal_error)?;
let mut conn = state.pool.acquire().await?;
let page = params.page.unwrap_or(1);
let page_size = params.page_size.unwrap_or(10);

Expand Down Expand Up @@ -60,27 +60,23 @@ pub async fn get_assets(
.as_str(),
);

let row = sqlx::query(&sql_total)
.fetch_one(&mut *conn)
.await
.map_err(internal_error)?;
let total: i64 = row.try_get("count").map_err(internal_error)?;
let row = sqlx::query(&sql_total).fetch_one(&mut *conn).await?;
let total: i64 = row.try_get("count")?;

let rows = sqlx::query(sql_query.as_str())
.fetch_all(&mut *conn)
.await
.map_err(internal_error)?;
.await?;

let mut assets: Vec<AssetResponse> = vec![];
for row in rows {
let asset: String = row.try_get("asset").map_err(internal_error)?;
let tx: String = row.try_get("tx").map_err(internal_error)?;
let block: String = row.try_get("block").map_err(internal_error)?;
let issuer: String = row.try_get("issuer").map_err(internal_error)?;
let height: i64 = row.try_get("height").map_err(internal_error)?;
let timestamp: i64 = row.try_get("timestamp").map_err(internal_error)?;
let ty: i32 = row.try_get("ty").map_err(internal_error)?;
let value: Value = row.try_get("content").map_err(internal_error)?;
let asset: String = row.try_get("asset")?;
let tx: String = row.try_get("tx")?;
let block: String = row.try_get("block")?;
let issuer: String = row.try_get("issuer")?;
let height: i64 = row.try_get("height")?;
let timestamp: i64 = row.try_get("timestamp")?;
let ty: i32 = row.try_get("ty")?;
let value: Value = row.try_get("content")?;
assets.push(AssetResponse {
asset,
tx,
Expand Down
Loading

0 comments on commit 4ff47cd

Please sign in to comment.