Allow multiple idos per category, parse data, and add tests
This commit is contained in:
parent
b97ec39fdb
commit
8e76a62d78
2 changed files with 980 additions and 141 deletions
File diff suppressed because it is too large
Load diff
127
src/rpc/ido.rs
127
src/rpc/ido.rs
|
|
@ -4,67 +4,55 @@
|
|||
// A copy of the license can be found in the LICENSE file or at https://www.gnu.org/licenses/agpl-3.0.html
|
||||
|
||||
use crate::{
|
||||
db::{cauldron::ido, DB},
|
||||
db::{cauldron::ido::{self, deserialize_ido_params}, DB},
|
||||
rpc::{
|
||||
err::{bad_request, db_error, not_found, ApiErrorCode, CachedApiResult},
|
||||
response::{cached_ok, CACHE_NONE},
|
||||
},
|
||||
};
|
||||
use bitcoin_hashes::hex::FromHex;
|
||||
use bitcoincash::TokenID;
|
||||
use bitcoincash::{TokenID, Txid};
|
||||
use rocket::{get, State};
|
||||
use serde_json::{json, Value};
|
||||
|
||||
/// List all discovered IDOs.
|
||||
///
|
||||
/// **Response Example:**
|
||||
/// ```json
|
||||
/// {
|
||||
/// "idos": [
|
||||
/// {
|
||||
/// "creation_txid": "abc123...",
|
||||
/// "category": "def456...",
|
||||
/// "params_raw": "...",
|
||||
/// "discovered_at_mtp": 1700000000,
|
||||
/// "phase": "fundraising"
|
||||
/// }
|
||||
/// ]
|
||||
/// }
|
||||
/// ```
|
||||
fn format_ido(
|
||||
creation_txid: String,
|
||||
offered_token_category: String,
|
||||
offering_category: Option<String>,
|
||||
params_raw: Vec<u8>,
|
||||
mtp: i64,
|
||||
phase: String,
|
||||
) -> Value {
|
||||
let params = deserialize_ido_params(¶ms_raw);
|
||||
json!({
|
||||
"creation_txid": creation_txid,
|
||||
"offered_token_category": offered_token_category,
|
||||
"offering_category": offering_category,
|
||||
"params_raw": hex::encode(¶ms_raw),
|
||||
"params": params,
|
||||
"discovered_at_mtp": mtp,
|
||||
"phase": phase,
|
||||
})
|
||||
}
|
||||
|
||||
/// List all discovered IDOs with parsed parameters.
|
||||
#[get("/ido")]
|
||||
pub async fn list_idos(conn: &State<DB>) -> CachedApiResult<Value> {
|
||||
let idos = ido::list_idos(&conn.cauldron_r).await.map_err(db_error)?;
|
||||
|
||||
let idos_json: Vec<Value> = idos
|
||||
.into_iter()
|
||||
.map(|(txid, category, params_raw, mtp, phase)| {
|
||||
json!({
|
||||
"creation_txid": txid,
|
||||
"category": category,
|
||||
"params_raw": hex::encode(params_raw),
|
||||
"discovered_at_mtp": mtp,
|
||||
"phase": phase,
|
||||
})
|
||||
.map(|(txid, offered_cat, offering_cat, params_raw, mtp, phase)| {
|
||||
format_ido(txid, offered_cat, offering_cat, params_raw, mtp, phase)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(cached_ok(json!({ "idos": idos_json }), CACHE_NONE))
|
||||
}
|
||||
|
||||
/// Get a specific IDO by token category.
|
||||
/// Get all IDOs for a token category (offered_token_category) with parsed parameters.
|
||||
///
|
||||
/// - category: Token category hex (32 bytes)
|
||||
///
|
||||
/// **Response Example:**
|
||||
/// ```json
|
||||
/// {
|
||||
/// "creation_txid": "abc123...",
|
||||
/// "category": "def456...",
|
||||
/// "params_raw": "...",
|
||||
/// "discovered_at_mtp": 1700000000,
|
||||
/// "phase": "fundraising"
|
||||
/// }
|
||||
/// ```
|
||||
/// Returns a list — multiple IDOs per token are allowed.
|
||||
#[get("/ido/<category>")]
|
||||
pub async fn get_ido(category: &str, conn: &State<DB>) -> CachedApiResult<Value> {
|
||||
let category = TokenID::from_hex(category).map_err(|e| {
|
||||
|
|
@ -74,67 +62,52 @@ pub async fn get_ido(category: &str, conn: &State<DB>) -> CachedApiResult<Value>
|
|||
)
|
||||
})?;
|
||||
|
||||
let result = ido::get_ido(&conn.cauldron_r, &category)
|
||||
let results = ido::get_idos_by_category(&conn.cauldron_r, &category)
|
||||
.await
|
||||
.map_err(db_error)?;
|
||||
|
||||
match result {
|
||||
Some((txid, category_hex, params_raw, mtp, phase)) => Ok(cached_ok(
|
||||
json!({
|
||||
"creation_txid": txid,
|
||||
"category": category_hex,
|
||||
"params_raw": hex::encode(params_raw),
|
||||
"discovered_at_mtp": mtp,
|
||||
"phase": phase,
|
||||
}),
|
||||
CACHE_NONE,
|
||||
)),
|
||||
None => Err(not_found(
|
||||
if results.is_empty() {
|
||||
return Err(not_found(
|
||||
ApiErrorCode::PoolNotFound,
|
||||
&format!("No IDO found for category: {category}"),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
let idos_json: Vec<Value> = results
|
||||
.into_iter()
|
||||
.map(|(txid, offered_cat, offering_cat, params_raw, mtp, phase)| {
|
||||
format_ido(txid, offered_cat, offering_cat, params_raw, mtp, phase)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(cached_ok(json!({ "idos": idos_json }), CACHE_NONE))
|
||||
}
|
||||
|
||||
/// Get active (unspent) entry NFT UTXOs for an IDO.
|
||||
/// Get active (unspent) entry NFT UTXOs for a specific IDO.
|
||||
///
|
||||
/// `creation_txid` is the txid of the IDO announcement transaction.
|
||||
/// Used by the distribution robot to find which entries still need to be processed.
|
||||
///
|
||||
/// - category: Token category hex (32 bytes)
|
||||
///
|
||||
/// **Response Example:**
|
||||
/// ```json
|
||||
/// {
|
||||
/// "entries": [
|
||||
/// {
|
||||
/// "txid": "abc123...",
|
||||
/// "n": 0,
|
||||
/// "sats": 10000,
|
||||
/// "token_amount": 100
|
||||
/// }
|
||||
/// ]
|
||||
/// }
|
||||
/// ```
|
||||
#[get("/ido/<category>/entries")]
|
||||
pub async fn get_ido_entries(category: &str, conn: &State<DB>) -> CachedApiResult<Value> {
|
||||
let category = TokenID::from_hex(category).map_err(|e| {
|
||||
#[get("/ido/<creation_txid>/entries")]
|
||||
pub async fn get_ido_entries(creation_txid: &str, conn: &State<DB>) -> CachedApiResult<Value> {
|
||||
let creation_txid = Txid::from_hex(creation_txid).map_err(|e| {
|
||||
bad_request(
|
||||
ApiErrorCode::InvalidTokenId,
|
||||
&format!("Invalid category: {e}"),
|
||||
&format!("Invalid creation_txid: {e}"),
|
||||
)
|
||||
})?;
|
||||
|
||||
let entries = ido::get_ido_entries(&conn.cauldron_r, &category)
|
||||
let entries = ido::get_ido_entries(&conn.cauldron_r, &creation_txid)
|
||||
.await
|
||||
.map_err(db_error)?;
|
||||
|
||||
let entries_json: Vec<Value> = entries
|
||||
.into_iter()
|
||||
.map(|(txid, n, sats, token_amount)| {
|
||||
.map(|(txid, n, sats, commitment)| {
|
||||
json!({
|
||||
"txid": txid,
|
||||
"n": n,
|
||||
"sats": sats,
|
||||
"token_amount": token_amount,
|
||||
"commitment": commitment,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue