diff --git a/daemon/src/model.rs b/daemon/src/model.rs index 4d2e71a..7a918e3 100644 --- a/daemon/src/model.rs +++ b/daemon/src/model.rs @@ -207,6 +207,10 @@ impl BitMexPriceEventId { .join(&self.to_string()) .expect("Event id can be joined") } + + pub fn timestamp(&self) -> OffsetDateTime { + self.timestamp + } } impl fmt::Display for BitMexPriceEventId { diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index 9df889b..34ce357 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -17,7 +17,7 @@ use std::collections::HashMap; use std::fmt; use std::ops::{Neg, RangeInclusive}; use std::time::SystemTime; -use time::Duration; +use time::{Duration, OffsetDateTime}; use uuid::adapter::Hyphenated; use uuid::Uuid; @@ -686,6 +686,10 @@ impl Cfd { (self.order.term * Cfd::REFUND_THRESHOLD).as_blocks().ceil() as u32 } + pub fn expiry_timestamp(&self) -> OffsetDateTime { + self.order.oracle_event_id.timestamp() + } + /// A factor to be added to the CFD order term for calculating the refund timelock. /// /// The refund timelock is important in case the oracle disappears or never publishes a diff --git a/daemon/src/to_sse_event.rs b/daemon/src/to_sse_event.rs index fb5d26d..4a9a083 100644 --- a/daemon/src/to_sse_event.rs +++ b/daemon/src/to_sse_event.rs @@ -10,6 +10,7 @@ use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; use std::convert::TryInto; use std::time::{SystemTime, UNIX_EPOCH}; +use time::OffsetDateTime; use tokio::sync::watch; #[derive(Debug, Clone, Serialize)] @@ -38,6 +39,9 @@ pub struct Cfd { pub state_transition_timestamp: u64, pub details: CfdDetails, + + #[serde(with = "::time::serde::timestamp")] + pub expiry_timestamp: OffsetDateTime, } #[derive(Debug, Clone, Serialize)] @@ -261,6 +265,7 @@ impl ToSseEvent for CfdsWithAuxData { margin: cfd.margin().unwrap(), margin_counterparty: cfd.counterparty_margin().unwrap(), details, + expiry_timestamp: cfd.expiry_timestamp(), } }) .collect::>(); diff --git a/frontend/src/components/Types.tsx b/frontend/src/components/Types.tsx index 1311aad..97055e0 100644 --- a/frontend/src/components/Types.tsx +++ b/frontend/src/components/Types.tsx @@ -49,6 +49,7 @@ export interface Cfd { actions: Action[]; state_transition_timestamp: number; details: CfdDetails; + expiry_timestamp: number; } export interface CfdDetails { diff --git a/frontend/src/components/cfdtables/CfdTable.tsx b/frontend/src/components/cfdtables/CfdTable.tsx index d905b39..cb91270 100644 --- a/frontend/src/components/cfdtables/CfdTable.tsx +++ b/frontend/src/components/cfdtables/CfdTable.tsx @@ -20,6 +20,7 @@ import { Table as CUITable, Tbody, Td, + Text, Th, Thead, Tooltip, @@ -30,6 +31,7 @@ import { import React from "react"; import { useAsync } from "react-async"; import { Column, Row, useExpanded, useSortBy, useTable } from "react-table"; +import Timestamp from "../Timestamp"; import { Action, Cfd } from "../Types"; interface CfdTableProps { @@ -95,7 +97,7 @@ export function CfdTable( }, { Header: "Details", - accessor: ({ details }) => { + accessor: ({ details, expiry_timestamp }) => { const txs = details.tx_url_list.map((tx) => { return ( {tx.label + " transaction"} @@ -108,6 +110,10 @@ export function CfdTable( {txs} {details.payout && Payout: {details.payout}} + + Expires on: + + ); @@ -260,7 +266,7 @@ function colorSchemaForAction(action: Action): string { function renderRowSubComponent(row: Row) { let cells = row.allCells .filter((cell) => { - return ["Details"].includes(cell.column.id); + return ["Details", "Timestamp"].includes(cell.column.id); }) .map((cell) => { return cell;