Skip to content

Commit

Permalink
Backend portion
Browse files Browse the repository at this point in the history
  • Loading branch information
Rigidity committed Nov 23, 2024
1 parent fbf259a commit 7687821
Show file tree
Hide file tree
Showing 10 changed files with 722 additions and 74 deletions.
3 changes: 3 additions & 0 deletions crates/sage-api/src/records/offer.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use serde::{Deserialize, Serialize};
use specta::Type;

use super::OfferSummary;

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
pub struct OfferRecord {
pub offer_id: String,
pub offer: String,
pub status: OfferRecordStatus,
pub creation_date: String,
pub summary: OfferSummary,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, Type)]
Expand Down
184 changes: 177 additions & 7 deletions crates/sage-database/src/offers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use std::time::{SystemTime, UNIX_EPOCH};
use chia::protocol::Bytes32;
use sqlx::SqliteExecutor;

use crate::{into_row, Database, DatabaseTx, OfferRow, OfferSql, Result};
use crate::{
into_row, Database, DatabaseTx, OfferCatRow, OfferCatSql, OfferNftRow, OfferNftSql, OfferRow,
OfferSql, OfferXchRow, OfferXchSql, Result,
};

impl Database {
pub async fn active_offers(&self) -> Result<Vec<OfferRow>> {
Expand All @@ -17,15 +20,39 @@ impl Database {
pub async fn delete_offer(&self, offer_id: Bytes32) -> Result<()> {
delete_offer(&self.pool, offer_id).await
}

pub async fn offer_xch(&self, offer_id: Bytes32) -> Result<Vec<OfferXchRow>> {
offer_xch(&self.pool, offer_id).await
}

pub async fn offer_nfts(&self, offer_id: Bytes32) -> Result<Vec<OfferNftRow>> {
offer_nfts(&self.pool, offer_id).await
}

pub async fn offer_cats(&self, offer_id: Bytes32) -> Result<Vec<OfferCatRow>> {
offer_cats(&self.pool, offer_id).await
}
}

impl DatabaseTx<'_> {
pub async fn insert_offer(&mut self, row: OfferRow) -> Result<()> {
insert_offer(&mut *self.tx, row).await
}

pub async fn insert_offer_coin(&mut self, offer_id: Bytes32, coin_id: Bytes32) -> Result<()> {
insert_offer_coin(&mut *self.tx, offer_id, coin_id).await
pub async fn insert_offered_coin(&mut self, offer_id: Bytes32, coin_id: Bytes32) -> Result<()> {
insert_offered_coin(&mut *self.tx, offer_id, coin_id).await
}

pub async fn insert_offer_xch(&mut self, row: OfferXchRow) -> Result<()> {
insert_offer_xch(&mut *self.tx, row).await
}

pub async fn insert_offer_nft(&mut self, row: OfferNftRow) -> Result<()> {
insert_offer_nft(&mut *self.tx, row).await
}

pub async fn insert_offer_cat(&mut self, row: OfferCatRow) -> Result<()> {
insert_offer_cat(&mut *self.tx, row).await
}
}

Expand All @@ -41,18 +68,22 @@ async fn insert_offer(conn: impl SqliteExecutor<'_>, row: OfferRow) -> Result<()
.to_be_bytes();
let timestamp = timestamp.as_ref();

let fee = row.fee.to_be_bytes();
let fee = fee.as_ref();

sqlx::query!(
"
INSERT OR IGNORE INTO `offers` (
`offer_id`, `encoded_offer`, `expiration_height`,
`expiration_timestamp`, `status`, `inserted_timestamp`
`expiration_timestamp`, `fee`, `status`, `inserted_timestamp`
)
VALUES (?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?)
",
offer_id,
row.encoded_offer,
row.expiration_height,
expiration_timestamp,
fee,
status,
timestamp
)
Expand All @@ -61,7 +92,7 @@ async fn insert_offer(conn: impl SqliteExecutor<'_>, row: OfferRow) -> Result<()
Ok(())
}

async fn insert_offer_coin(
async fn insert_offered_coin(
conn: impl SqliteExecutor<'_>,
offer_id: Bytes32,
coin_id: Bytes32,
Expand All @@ -70,7 +101,7 @@ async fn insert_offer_coin(
let coin_id = coin_id.as_ref();

sqlx::query!(
"INSERT OR IGNORE INTO `offer_coins` (`offer_id`, `coin_id`) VALUES (?, ?)",
"INSERT OR IGNORE INTO `offered_coins` (`offer_id`, `coin_id`) VALUES (?, ?)",
offer_id,
coin_id
)
Expand All @@ -80,6 +111,91 @@ async fn insert_offer_coin(
Ok(())
}

async fn insert_offer_xch(conn: impl SqliteExecutor<'_>, row: OfferXchRow) -> Result<()> {
let offer_id = row.offer_id.as_ref();
let amount = row.amount.to_be_bytes();
let amount = amount.as_ref();
let royalty = row.royalty.to_be_bytes();
let royalty = royalty.as_ref();

sqlx::query!(
"
INSERT OR IGNORE INTO `offer_xch` (
`offer_id`, `requested`, `amount`, `royalty`
)
VALUES (?, ?, ?, ?)
",
offer_id,
row.requested,
amount,
royalty
)
.execute(conn)
.await?;

Ok(())
}

async fn insert_offer_nft(conn: impl SqliteExecutor<'_>, row: OfferNftRow) -> Result<()> {
let offer_id = row.offer_id.as_ref();
let launcher_id = row.launcher_id.as_ref();
let royalty_puzzle_hash = row.royalty_puzzle_hash.as_ref();

sqlx::query!(
"
INSERT OR IGNORE INTO `offer_nfts` (
`offer_id`, `requested`, `launcher_id`,
`royalty_puzzle_hash`, `royalty_ten_thousandths`,
`name`, `thumbnail`, `thumbnail_mime_type`
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
",
offer_id,
row.requested,
launcher_id,
royalty_puzzle_hash,
row.royalty_ten_thousandths,
row.name,
row.thumbnail,
row.thumbnail_mime_type
)
.execute(conn)
.await?;

Ok(())
}

async fn insert_offer_cat(conn: impl SqliteExecutor<'_>, row: OfferCatRow) -> Result<()> {
let offer_id = row.offer_id.as_ref();
let asset_id = row.asset_id.as_ref();
let amount = row.amount.to_be_bytes();
let amount = amount.as_ref();
let royalty = row.royalty.to_be_bytes();
let royalty = royalty.as_ref();

sqlx::query!(
"
INSERT OR IGNORE INTO `offer_cats` (
`offer_id`, `requested`, `asset_id`,
`amount`, `royalty`, `name`, `ticker`, `icon`
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
",
offer_id,
row.requested,
asset_id,
amount,
royalty,
row.name,
row.ticker,
row.icon
)
.execute(conn)
.await?;

Ok(())
}

async fn active_offers(conn: impl SqliteExecutor<'_>) -> Result<Vec<OfferRow>> {
sqlx::query_as!(
OfferSql,
Expand Down Expand Up @@ -113,3 +229,57 @@ pub async fn delete_offer(conn: impl SqliteExecutor<'_>, offer_id: Bytes32) -> R

Ok(())
}

pub async fn offer_xch(
conn: impl SqliteExecutor<'_>,
offer_id: Bytes32,
) -> Result<Vec<OfferXchRow>> {
let offer_id = offer_id.as_ref();

sqlx::query_as!(
OfferXchSql,
"SELECT * FROM `offer_xch` WHERE `offer_id` = ?",
offer_id
)
.fetch_all(conn)
.await?
.into_iter()
.map(into_row)
.collect()
}

pub async fn offer_nfts(
conn: impl SqliteExecutor<'_>,
offer_id: Bytes32,
) -> Result<Vec<OfferNftRow>> {
let offer_id = offer_id.as_ref();

sqlx::query_as!(
OfferNftSql,
"SELECT * FROM `offer_nfts` WHERE `offer_id` = ?",
offer_id
)
.fetch_all(conn)
.await?
.into_iter()
.map(into_row)
.collect()
}

pub async fn offer_cats(
conn: impl SqliteExecutor<'_>,
offer_id: Bytes32,
) -> Result<Vec<OfferCatRow>> {
let offer_id = offer_id.as_ref();

sqlx::query_as!(
OfferCatSql,
"SELECT * FROM `offer_cats` WHERE `offer_id` = ?",
offer_id
)
.fetch_all(conn)
.await?
.into_iter()
.map(into_row)
.collect()
}
6 changes: 3 additions & 3 deletions crates/sage-database/src/primitives/cats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,12 @@ async fn spendable_cat_coins(
FROM `cat_coins` INDEXED BY `cat_asset_id`
INNER JOIN `coin_states` AS cs ON `cat_coins`.`coin_id` = cs.`coin_id`
LEFT JOIN `transaction_spends` ON cs.`coin_id` = `transaction_spends`.`coin_id`
LEFT JOIN `offer_coins` ON cs.`coin_id` = `offer_coins`.`coin_id`
LEFT JOIN `offers` ON `offer_coins`.`offer_id` = `offers`.`offer_id`
LEFT JOIN `offered_coins` ON cs.`coin_id` = `offered_coins`.`coin_id`
LEFT JOIN `offers` ON `offered_coins`.`offer_id` = `offers`.`offer_id`
WHERE `cat_coins`.`asset_id` = ?
AND cs.`spent_height` IS NULL
AND `transaction_spends`.`coin_id` IS NULL
AND (`offer_coins`.`coin_id` IS NULL OR `offers`.`status` > 0)
AND (`offered_coins`.`coin_id` IS NULL OR `offers`.`status` > 0)
AND cs.`transaction_id` IS NULL
",
asset_id
Expand Down
6 changes: 3 additions & 3 deletions crates/sage-database/src/primitives/xch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ async fn spendable_coins(conn: impl SqliteExecutor<'_>) -> Result<Vec<Coin>> {
SELECT `coin_states`.`parent_coin_id`, `coin_states`.`puzzle_hash`, `coin_states`.`amount` FROM `coin_states`
INNER JOIN `p2_coins` ON `coin_states`.`coin_id` = `p2_coins`.`coin_id`
LEFT JOIN `transaction_spends` ON `coin_states`.`coin_id` = `transaction_spends`.`coin_id`
LEFT JOIN `offer_coins` ON `coin_states`.`coin_id` = `offer_coins`.`coin_id`
LEFT JOIN `offers` ON `offer_coins`.`offer_id` = `offers`.`offer_id`
LEFT JOIN `offered_coins` ON `coin_states`.`coin_id` = `offered_coins`.`coin_id`
LEFT JOIN `offers` ON `offered_coins`.`offer_id` = `offers`.`offer_id`
WHERE `coin_states`.`spent_height` IS NULL
AND `transaction_spends`.`coin_id` IS NULL
AND (`offer_coins`.`coin_id` IS NULL OR `offers`.`status` > 0)
AND (`offered_coins`.`coin_id` IS NULL OR `offers`.`status` > 0)
AND `coin_states`.`transaction_id` IS NULL
"
)
Expand Down
Loading

0 comments on commit 7687821

Please sign in to comment.