Skip to content

Commit

Permalink
Merge pull request #87 from xch-dev/view-offer
Browse files Browse the repository at this point in the history
Add ability to view and take offer
  • Loading branch information
Rigidity authored Nov 12, 2024
2 parents 3a2f149 + c323a61 commit dacd97f
Show file tree
Hide file tree
Showing 16 changed files with 642 additions and 86 deletions.
2 changes: 2 additions & 0 deletions crates/sage-api/src/records.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod did;
mod nft;
mod nft_collection;
mod nft_status;
mod offer_summary;
mod peer;
mod pending_transaction;
mod sync_status;
Expand All @@ -15,6 +16,7 @@ pub use did::*;
pub use nft::*;
pub use nft_collection::*;
pub use nft_status::*;
pub use offer_summary::*;
pub use peer::*;
pub use pending_transaction::*;
pub use sync_status::*;
Expand Down
26 changes: 26 additions & 0 deletions crates/sage-api/src/records/offer_summary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use serde::{Deserialize, Serialize};
use specta::Type;

use crate::{Amount, AssetKind};

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
pub struct OfferSummary {
pub fee: Amount,
pub offered: Vec<OfferedCoin>,
pub requested: Vec<RequestedAsset>,
}

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
pub struct OfferedCoin {
pub coin_id: String,
pub offered_amount: Amount,
#[serde(flatten)]
pub kind: AssetKind,
}

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
pub struct RequestedAsset {
pub amount: Amount,
#[serde(flatten)]
pub kind: AssetKind,
}
28 changes: 2 additions & 26 deletions crates/sage-api/src/records/transaction_summary.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use specta::Type;

use crate::Amount;
use crate::{Amount, AssetKind};

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
pub struct TransactionSummary {
Expand Down Expand Up @@ -36,7 +36,7 @@ pub struct Input {
pub amount: Amount,
pub address: String,
#[serde(flatten)]
pub kind: InputKind,
pub kind: AssetKind,
pub outputs: Vec<Output>,
}

Expand All @@ -48,27 +48,3 @@ pub struct Output {
pub receiving: bool,
pub burning: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum InputKind {
Unknown,
Xch,
Launcher,
Cat {
asset_id: String,
name: Option<String>,
ticker: Option<String>,
icon_url: Option<String>,
},
Did {
launcher_id: String,
name: Option<String>,
},
Nft {
launcher_id: String,
image_data: Option<String>,
image_mime_type: Option<String>,
name: Option<String>,
},
}
2 changes: 2 additions & 0 deletions crates/sage-api/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod amount;
mod asset_kind;
mod nft_uri_kind;
mod unit;

pub use amount::*;
pub use asset_kind::*;
pub use nft_uri_kind::*;
pub use unit::*;
26 changes: 26 additions & 0 deletions crates/sage-api/src/types/asset_kind.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use serde::{Deserialize, Serialize};
use specta::Type;

#[derive(Debug, Clone, Serialize, Deserialize, Type)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum AssetKind {
Unknown,
Xch,
Launcher,
Cat {
asset_id: String,
name: Option<String>,
ticker: Option<String>,
icon_url: Option<String>,
},
Did {
launcher_id: String,
name: Option<String>,
},
Nft {
launcher_id: String,
image_data: Option<String>,
image_mime_type: Option<String>,
name: Option<String>,
},
}
56 changes: 35 additions & 21 deletions crates/sage-wallet/src/child_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use chia::{
puzzles::{nft::NftMetadata, singleton::SINGLETON_LAUNCHER_PUZZLE_HASH, LineageProof, Proof},
};
use chia_wallet_sdk::{run_puzzle, Cat, Condition, Did, DidInfo, HashedPtr, Nft, NftInfo, Puzzle};
use clvmr::Allocator;
use clvmr::{Allocator, NodePtr};
use tracing::{debug_span, warn};

use crate::WalletError;
Expand Down Expand Up @@ -38,6 +38,33 @@ impl ChildKind {
parent_puzzle: &Program,
parent_solution: &Program,
coin: Coin,
) -> Result<Self, WalletError> {
let mut allocator = Allocator::new();

let parent_puzzle_ptr = parent_puzzle.to_clvm(&mut allocator)?;
let parent_puzzle = Puzzle::parse(&allocator, parent_puzzle_ptr);
let parent_solution = parent_solution.to_clvm(&mut allocator)?;

let output = run_puzzle(&mut allocator, parent_puzzle.ptr(), parent_solution)?;
let conditions = Vec::<Condition>::from_clvm(&allocator, output)?;

Self::from_parent_cached(
&mut allocator,
parent_coin,
parent_puzzle,
parent_solution,
conditions,
coin,
)
}

pub fn from_parent_cached(
allocator: &mut Allocator,
parent_coin: Coin,
parent_puzzle: Puzzle,
parent_solution: NodePtr,
conditions: Vec<Condition>,
coin: Coin,
) -> Result<Self, WalletError> {
let parse_span = debug_span!(
"parse from parent",
Expand All @@ -50,15 +77,6 @@ impl ChildKind {
return Ok(Self::Launcher);
}

let mut allocator = Allocator::new();

let parent_puzzle_ptr = parent_puzzle.to_clvm(&mut allocator)?;
let parent_puzzle = Puzzle::parse(&allocator, parent_puzzle_ptr);
let parent_solution = parent_solution.to_clvm(&mut allocator)?;

let output = run_puzzle(&mut allocator, parent_puzzle_ptr, parent_solution)?;
let conditions = Vec::<Condition>::from_clvm(&allocator, output)?;

let Some(mut create_coin) = conditions
.into_iter()
.filter_map(Condition::into_create_coin)
Expand All @@ -77,7 +95,7 @@ impl ChildKind {

let unknown = Self::Unknown { hint: Some(hint) };

match Cat::parse_children(&mut allocator, parent_coin, parent_puzzle, parent_solution) {
match Cat::parse_children(allocator, parent_coin, parent_puzzle, parent_solution) {
// If there was an error parsing the CAT, we can exit early.
Err(error) => {
warn!("Invalid CAT: {}", error);
Expand Down Expand Up @@ -107,12 +125,8 @@ impl ChildKind {
Ok(None) => {}
}

match Nft::<HashedPtr>::parse_child(
&mut allocator,
parent_coin,
parent_puzzle,
parent_solution,
) {
match Nft::<HashedPtr>::parse_child(allocator, parent_coin, parent_puzzle, parent_solution)
{
// If there was an error parsing the NFT, we can exit early.
Err(error) => {
warn!("Invalid NFT: {}", error);
Expand All @@ -131,8 +145,8 @@ impl ChildKind {
return Ok(unknown);
};

let metadata_program = Program::from_clvm(&allocator, nft.info.metadata.ptr())?;
let metadata = NftMetadata::from_clvm(&allocator, nft.info.metadata.ptr()).ok();
let metadata_program = Program::from_clvm(allocator, nft.info.metadata.ptr())?;
let metadata = NftMetadata::from_clvm(allocator, nft.info.metadata.ptr()).ok();

return Ok(Self::Nft {
lineage_proof,
Expand All @@ -146,7 +160,7 @@ impl ChildKind {
}

match Did::<HashedPtr>::parse_child(
&mut allocator,
allocator,
parent_coin,
parent_puzzle,
parent_solution,
Expand All @@ -165,7 +179,7 @@ impl ChildKind {
return Ok(unknown);
};

let metadata = Program::from_clvm(&allocator, did.info.metadata.ptr())?;
let metadata = Program::from_clvm(allocator, did.info.metadata.ptr())?;

return Ok(Self::Did {
lineage_proof,
Expand Down
22 changes: 13 additions & 9 deletions crates/sage-wallet/src/coin_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,23 @@ pub enum CoinKind {

impl CoinKind {
pub fn from_puzzle(puzzle: &Program) -> Result<Self, WalletError> {
let parse_span = debug_span!("parse puzzle");
let _span = parse_span.enter();

let mut allocator = Allocator::new();

let puzzle_ptr = puzzle.to_clvm(&mut allocator)?;
let puzzle = Puzzle::parse(&allocator, puzzle_ptr);

Self::from_puzzle_cached(&allocator, puzzle)
}

pub fn from_puzzle_cached(allocator: &Allocator, puzzle: Puzzle) -> Result<Self, WalletError> {
let parse_span = debug_span!("parse puzzle");
let _span = parse_span.enter();

if puzzle.curried_puzzle_hash() == SINGLETON_LAUNCHER_PUZZLE_HASH {
return Ok(Self::Launcher);
}

match CatLayer::<HashedPtr>::parse_puzzle(&allocator, puzzle) {
match CatLayer::<HashedPtr>::parse_puzzle(allocator, puzzle) {
// If there was an error parsing the CAT, we can exit early.
Err(error) => {
warn!("Invalid CAT: {}", error);
Expand All @@ -60,7 +64,7 @@ impl CoinKind {
Ok(None) => {}
}

match NftInfo::<HashedPtr>::parse(&allocator, puzzle) {
match NftInfo::<HashedPtr>::parse(allocator, puzzle) {
// If there was an error parsing the NFT, we can exit early.
Err(error) => {
warn!("Invalid NFT: {}", error);
Expand All @@ -69,8 +73,8 @@ impl CoinKind {

// If the coin is a NFT coin, return the relevant information.
Ok(Some((nft, _inner_puzzle))) => {
let metadata_program = Program::from_clvm(&allocator, nft.metadata.ptr())?;
let metadata = NftMetadata::from_clvm(&allocator, nft.metadata.ptr()).ok();
let metadata_program = Program::from_clvm(allocator, nft.metadata.ptr())?;
let metadata = NftMetadata::from_clvm(allocator, nft.metadata.ptr()).ok();

return Ok(Self::Nft {
info: nft.with_metadata(metadata_program),
Expand All @@ -82,7 +86,7 @@ impl CoinKind {
Ok(None) => {}
}

match DidInfo::<HashedPtr>::parse(&allocator, puzzle) {
match DidInfo::<HashedPtr>::parse(allocator, puzzle) {
// If there was an error parsing the DID, we can exit early.
Err(error) => {
warn!("Invalid DID: {}", error);
Expand All @@ -91,7 +95,7 @@ impl CoinKind {

// If the coin is a DID coin, return the relevant information.
Ok(Some((did, _inner_puzzle))) => {
let metadata = Program::from_clvm(&allocator, did.metadata.ptr())?;
let metadata = Program::from_clvm(allocator, did.metadata.ptr())?;

return Ok(Self::Did {
info: did.with_metadata(metadata),
Expand Down
Loading

0 comments on commit dacd97f

Please sign in to comment.