Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Limit Orders]: Feat add v3 designs #3612

Merged
merged 108 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
52da424
feat: added gas fee esimate to place limit state
crnbarr93 Jul 23, 2024
72cf757
feat: reduced fee estimate calls
crnbarr93 Jul 23, 2024
409b13a
Merge branch 'feat/implement-limit-orders' into connor/gas-fee-estimates
crnbarr93 Jul 25, 2024
6fd53c7
fix: fixed isTyping field for inAmountInput
crnbarr93 Jul 25, 2024
438020b
feat: redesign widget base layout & top selectors
fabryscript Jul 26, 2024
49150b8
chore: remove unused old commented code
fabryscript Jul 26, 2024
f1f71ea
chore: remove tab uqs
fabryscript Jul 26, 2024
17c16ac
feat: update token selection & input/output designs
fabryscript Jul 26, 2024
5d27e3e
feat: redesign quote selection
fabryscript Jul 26, 2024
9461630
feat: WIP redesign limit price selector and update page widget size
fabryscript Jul 26, 2024
c412f04
Merge branch 'feat/implement-limit-orders' into fabryscript/feat-add-…
fabryscript Jul 29, 2024
0467185
fix: invert triangles direction and comment out unused code
fabryscript Jul 29, 2024
e283f4b
fix: fix button click disabled when tooltip open
fabryscript Jul 29, 2024
7dec55d
feat: re-implement open orders card
fabryscript Jul 29, 2024
e7d36c7
feat: WIP init implementing focus switching
fabryscript Jul 29, 2024
b8843c4
feat: add switching button UI
fabryscript Jul 29, 2024
11309f5
feat: change default percent adjustment and label render logic
fabryscript Jul 29, 2024
74dd987
feat: re-add trade details
fabryscript Jul 29, 2024
1562414
chore: remove unused code
fabryscript Jul 29, 2024
90a8ebf
refactor: extract AssetFieldset
fabryscript Jul 29, 2024
40cc6b5
chore: comment out unused code
fabryscript Jul 29, 2024
dc6000a
feat: wire-up trade details limit variant
fabryscript Jul 29, 2024
0f4c64d
feat: WIP implement new swap tool designs
fabryscript Jul 29, 2024
707891d
refactor: moved order mapping to caching function
crnbarr93 Jul 29, 2024
257ea3b
build: fixed build errors
crnbarr93 Jul 29, 2024
f5e740c
feat: added refetch to cancel/claim [WARNING DO NOT TEST]
crnbarr93 Jul 29, 2024
20289d0
fix: fixed refetching on order table
crnbarr93 Jul 29, 2024
ad12f9d
Merge branch 'fabryscript/feat-add-v3-designs' into connor/order-hist…
crnbarr93 Jul 29, 2024
4495569
feat: finish implementing swap tool redesign
fabryscript Jul 29, 2024
3c8e2ac
feat: add popover on limit order disabled & tweak GenericDisclaimer c…
fabryscript Jul 30, 2024
82413ab
feat: refetch orders on first load
crnbarr93 Jul 30, 2024
02dc2bc
feat: add "add funds" button to asset fieldset header balance
fabryscript Jul 30, 2024
a22eb70
feat: add no balance logics to place limit tool & swap tool
fabryscript Jul 30, 2024
0a345ea
fix: inputs adjust value of other input for limit orders
crnbarr93 Jul 30, 2024
780be4b
feat: change all site bg & fix earn page radio buttons opacity
fabryscript Jul 30, 2024
8cd430f
fix: removed unnecessary button disabled state
crnbarr93 Jul 30, 2024
389b3ce
feat: add trade bg
fabryscript Jul 30, 2024
c8ae72d
chore: removed unused code
crnbarr93 Jul 30, 2024
f9b043d
fix: fixed price input error on 0 input
crnbarr93 Jul 30, 2024
167273f
fix: fixed rounding issue with max button
crnbarr93 Jul 30, 2024
b646aeb
Merge pull request #3629 from osmosis-labs/connor/v3-max-button
fabryscript Jul 30, 2024
6e0c425
fix: fix faulting overflow-hidden on alt swap tool
fabryscript Jul 30, 2024
1f5f54a
fix: fix bar width
fabryscript Jul 30, 2024
ad7e453
fix: fix alt swap tool labels
fabryscript Jul 30, 2024
07145e3
fix: fix scroll on home fixed container
fabryscript Jul 30, 2024
185e96a
fix: fix "add funds" display on wallet disconnected
fabryscript Jul 30, 2024
f12a07e
fix: fix alt headers and remove old code
fabryscript Jul 30, 2024
09a0ef9
fix: fix spacing on tool
fabryscript Jul 30, 2024
fd9ed43
fix: fix trade details bugged animation
fabryscript Jul 30, 2024
9dc0ba3
feat: add prefixes/suffixes empty states
fabryscript Jul 30, 2024
f9eba89
fix: disable ticker on sell tab balance
fabryscript Jul 30, 2024
4b05410
fix: fix sell balance precision & fieldset footer height
fabryscript Jul 30, 2024
5ca5441
fix: fix buy available usdc amount formatting
fabryscript Jul 30, 2024
ed2a5e0
feat: update selectableQuotes to cover wallet not connected case
fabryscript Jul 30, 2024
311da45
fix: hide add funds button when wallet is disconnected
fabryscript Jul 30, 2024
d75ad86
fix: hide add funds cta on price selector and fix lint
fabryscript Jul 30, 2024
b63f395
fix: filter in UI default quotes on defaultQuotesWithBalances
fabryscript Jul 31, 2024
fe52f29
feat: add empty states to swap widget footers
fabryscript Jul 31, 2024
3546c8c
feat: make "stablecoin" tooltip trigger underlined
fabryscript Jul 31, 2024
d8e55d7
Merge branch 'fabryscript/feat-add-v3-designs' into connor/gas-fee-es…
crnbarr93 Jul 31, 2024
087ff3f
fix: update decimal places and add "<$0.01" to trade details fees
fabryscript Jul 31, 2024
e36a1f7
build: fixed build errors
crnbarr93 Jul 31, 2024
494685a
fix: update display of gasUsdValueToPay
fabryscript Jul 31, 2024
4dffe1e
Merge branch 'fabryscript/feat-add-v3-designs' into connor/gas-fee-es…
fabryscript Jul 31, 2024
bce6afe
Merge pull request #3584 from osmosis-labs/connor/gas-fee-estimates
fabryscript Jul 31, 2024
35b8fce
feat: update rendering of gasAmount and wire it up on swap tool
fabryscript Jul 31, 2024
3f0bf9e
refactor: updated button disabled & loading states
crnbarr93 Jul 31, 2024
22b76e0
fix: update gas display on review modal
fabryscript Jul 31, 2024
b879790
chore: readded insufficient balance display to hidden error messages
crnbarr93 Jul 31, 2024
b2cd80f
fix: update chart icon size and variant display logic
fabryscript Jul 31, 2024
759ee2c
feat: remove triangle indicator when percentAdjusted is zero
fabryscript Jul 31, 2024
8f5d6a5
fix: update token-details-shadow color
fabryscript Jul 31, 2024
fc2c766
chore: sentence case adjustments
crnbarr93 Jul 31, 2024
7cda9fe
fix: fixed review modal changing price and incorrect values
crnbarr93 Jul 31, 2024
fc4fa94
feat: WIP add scaling to asset input
fabryscript Jul 31, 2024
234747a
Merge branch 'fabryscript/feat-add-v3-designs' of github.com:osmosis-…
fabryscript Jul 31, 2024
57bb5fe
Merge pull request #3637 from osmosis-labs/connor/buy-sell-button-state
fabryscript Jul 31, 2024
8324fa3
Merge pull request #3638 from osmosis-labs/connor/limit-review
fabryscript Jul 31, 2024
33f3e13
fix: fix rounding issues on order type selector and wrapping on paren…
fabryscript Jul 31, 2024
8658986
fix: move isValidNumericalRawInput validation to useLimitPrice
fabryscript Jul 31, 2024
3849bf9
refactor: move orderType prop computation to ReviewOrder and remove u…
fabryscript Jul 31, 2024
fc5fef1
fix: fixed low price value display in limit price selector
crnbarr93 Jul 31, 2024
7d847ff
feat: WIP add diffGteSlippage handling
fabryscript Jul 31, 2024
6d39361
fix: update isManualSlippageTooHigh treshold
fabryscript Jul 31, 2024
942122a
feat: truncate last slippage number if it's gt 50
fabryscript Jul 31, 2024
47299fd
feat: add isManualSlippageTooLow disclaimer and update designs
fabryscript Jul 31, 2024
6a64941
fix: fix max button spinner distortion
fabryscript Jul 31, 2024
12e278f
fix: fix sticky scroll bg color to thead
fabryscript Jul 31, 2024
ebafac3
feat: add tooltip on order history page
fabryscript Jul 31, 2024
d781312
feat: update order history columns
fabryscript Jul 31, 2024
af50e3f
fix: fixed overflow on trade details and insufficient funds not disab…
crnbarr93 Jul 31, 2024
c33df32
fix: added label for limit price input and fixed hover state for deno…
crnbarr93 Jul 31, 2024
36ee65a
feat: button hover states for price selection
crnbarr93 Jul 31, 2024
353cc0a
fix: removed place limit msg generation for market orders
crnbarr93 Jul 31, 2024
f242a65
build: fixed build error
crnbarr93 Jul 31, 2024
d6c30da
fix: adjusted text overflow for expected output
crnbarr93 Aug 1, 2024
e19e6a8
feat: :sparkles: add limit orders localizations
DavideSegullo Aug 1, 2024
3b6c3c8
feat: added no gas fee estimation state to trade details
crnbarr93 Aug 1, 2024
a483834
Merge pull request #3639 from osmosis-labs/connor/limit-price-decimals
crnbarr93 Aug 1, 2024
276eb54
feat: added gas estimate changes to review order
crnbarr93 Aug 1, 2024
9e14d30
chore: machine translate
crnbarr93 Aug 1, 2024
4c18118
Merge branch 'fabryscript/feat-add-v3-designs' into connor/gas-estima…
crnbarr93 Aug 1, 2024
ef571b3
chore: added more localisations
crnbarr93 Aug 1, 2024
949e0f8
feat: added refetchOnMount to all/claimable orders queries
crnbarr93 Aug 1, 2024
7eaa406
Merge branch 'fabryscript/feat-add-v3-designs' into connor/order-hist…
crnbarr93 Aug 1, 2024
9879bed
Merge pull request #3647 from osmosis-labs/connor/gas-estimate-failure
crnbarr93 Aug 1, 2024
567fe35
Merge pull request #3623 from osmosis-labs/connor/order-history-caching
crnbarr93 Aug 1, 2024
22f3792
Merge branch 'feat/implement-limit-orders' into fabryscript/feat-add-…
crnbarr93 Aug 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 128 additions & 3 deletions packages/server/src/queries/complex/orderbooks/active-orders.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,157 @@
import { Chain } from "@osmosis-labs/types";
import { Dec, Int } from "@keplr-wallet/unit";
import { tickToPrice } from "@osmosis-labs/math";
import { AssetList, Chain } from "@osmosis-labs/types";
import { getAssetFromAssetList } from "@osmosis-labs/utils";
import cachified, { CacheEntry } from "cachified";
import dayjs from "dayjs";
import { LRUCache } from "lru-cache";

import { DEFAULT_LRU_OPTIONS } from "../../../utils/cache";
import { LimitOrder, queryOrderbookActiveOrders } from "../../osmosis";
import { getOrderbookDenoms } from "./denoms";
import {
getOrderbookTickState,
getOrderbookTickUnrealizedCancels,
} from "./tick-state";
import type { MappedLimitOrder, OrderStatus } from "./types";

const activeOrdersCache = new LRUCache<string, CacheEntry>(DEFAULT_LRU_OPTIONS);

export function getOrderbookActiveOrders({
orderbookAddress,
userOsmoAddress,
chainList,
assetLists,
}: {
orderbookAddress: string;
userOsmoAddress: string;
chainList: Chain[];
assetLists: AssetList[];
}) {
return cachified({
cache: activeOrdersCache,
key: `orderbookActiveOrders-${orderbookAddress}-${userOsmoAddress}`,
ttl: 1000 * 3, // 3 seconds
ttl: 500, // 2 seconds
getFreshValue: () =>
queryOrderbookActiveOrders({
orderbookAddress,
userAddress: userOsmoAddress,
chainList,
}).then(
({ data }: { data: { count: number; orders: LimitOrder[] } }) => data
async ({ data }: { data: { count: number; orders: LimitOrder[] } }) => {
const { quoteAsset, baseAsset } = await getOrderbookDenoms({
orderbookAddress,
chainList,
assetLists,
});

return getTickInfoAndTransformOrders(
orderbookAddress,
data.orders,
chainList,
quoteAsset,
baseAsset
);
}
),
});
}

function mapOrderStatus(order: LimitOrder, percentFilled: Dec): OrderStatus {
const quantInt = parseInt(order.quantity);
if (quantInt === 0 || percentFilled.equals(new Dec(1))) return "filled";
if (percentFilled.isZero()) return "open";
if (percentFilled.lt(new Dec(1))) return "partiallyFilled";

return "open";
}

async function getTickInfoAndTransformOrders(
orderbookAddress: string,
orders: LimitOrder[],
chainList: Chain[],
quoteAsset: ReturnType<typeof getAssetFromAssetList>,
baseAsset: ReturnType<typeof getAssetFromAssetList>
): Promise<MappedLimitOrder[]> {
const tickIds = [...new Set(orders.map((o) => o.tick_id))];
const tickStates = await getOrderbookTickState({
orderbookAddress,
chainList,
tickIds,
});
const unrealizedTickCancels = await getOrderbookTickUnrealizedCancels({
orderbookAddress,
chainList,
tickIds,
});

const fullTickState = tickStates.map(({ tick_id, tick_state }) => ({
tickId: tick_id,
tickState: tick_state,
unrealizedCancels: unrealizedTickCancels.find((c) => c.tick_id === tick_id),
}));

return orders.map((o) => {
const { tickState, unrealizedCancels } = fullTickState.find(
({ tickId }) => tickId === o.tick_id
) ?? { tickState: undefined, unrealizedCancels: undefined };

const quantity = parseInt(o.quantity);
const placedQuantity = parseInt(o.placed_quantity);

const percentClaimed = new Dec(
(placedQuantity - quantity) / placedQuantity
);

const normalizationFactor = new Dec(10).pow(
new Int((quoteAsset?.decimals ?? 0) - (baseAsset?.decimals ?? 0))
);
const [tickEtas, tickUnrealizedCancelled] =
o.order_direction === "bid"
? [
parseInt(
tickState?.bid_values.effective_total_amount_swapped ?? "0"
),
parseInt(
unrealizedCancels?.unrealized_cancels.bid_unrealized_cancels ??
"0"
),
]
: [
parseInt(
tickState?.ask_values.effective_total_amount_swapped ?? "0"
),
parseInt(
unrealizedCancels?.unrealized_cancels.ask_unrealized_cancels ??
"0"
),
];
const tickTotalEtas = tickEtas + tickUnrealizedCancelled;
const totalFilled = Math.max(
tickTotalEtas - (parseInt(o.etas) - (placedQuantity - quantity)),
0
);
const percentFilled = new Dec(Math.min(totalFilled / placedQuantity, 1));
const price = tickToPrice(new Int(o.tick_id));
const status = mapOrderStatus(o, percentFilled);
const output =
o.order_direction === "bid"
? new Dec(placedQuantity).quo(price)
: new Dec(placedQuantity).mul(price);
return {
...o,
price: price.quo(normalizationFactor),
quantity,
placed_quantity: placedQuantity,
percentClaimed,
totalFilled,
percentFilled,
orderbookAddress,
status,
output,
quoteAsset,
baseAsset,
placed_at: dayjs(parseInt(o.placed_at) / 1_000).unix(),
};
});
}
20 changes: 17 additions & 3 deletions packages/server/src/queries/complex/orderbooks/denoms.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Chain } from "@osmosis-labs/types";
import { AssetList, Chain } from "@osmosis-labs/types";
import { getAssetFromAssetList } from "@osmosis-labs/utils";
import cachified, { CacheEntry } from "cachified";
import { LRUCache } from "lru-cache";

Expand All @@ -12,17 +13,30 @@ const orderbookDenomsCache = new LRUCache<string, CacheEntry>(
export function getOrderbookDenoms({
orderbookAddress,
chainList,
assetLists,
}: {
orderbookAddress: string;
chainList: Chain[];
assetLists: AssetList[];
}) {
return cachified({
cache: orderbookDenomsCache,
key: `orderbookDenoms-${orderbookAddress}`,
ttl: 1000 * 60 * 60 * 24 * 7, // 7 days
ttl: 1000 * 60 * 60 * 24 * 30, // 30 days
getFreshValue: () =>
queryOrderbookDenoms({ orderbookAddress, chainList }).then(
({ data }) => data
({ data: { quote_denom, base_denom } }) => {
const quoteAsset = getAssetFromAssetList({
coinMinimalDenom: quote_denom,
assetLists,
});
const baseAsset = getAssetFromAssetList({
coinMinimalDenom: base_denom,
assetLists,
});

return { quoteAsset, baseAsset };
}
),
});
}
129 changes: 126 additions & 3 deletions packages/server/src/queries/complex/orderbooks/historical-orders.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
import { Dec, Int } from "@keplr-wallet/unit";
import { tickToPrice } from "@osmosis-labs/math";
import { AssetList, Chain } from "@osmosis-labs/types";
import { getAssetFromAssetList } from "@osmosis-labs/utils";
import cachified, { CacheEntry } from "cachified";
import dayjs from "dayjs";
import { LRUCache } from "lru-cache";

import { DEFAULT_LRU_OPTIONS } from "../../../utils/cache";
import { HistoricalLimitOrder, queryHistoricalOrders } from "../../osmosis";
import { getOrderbookDenoms } from "./denoms";
import type { MappedLimitOrder, OrderStatus } from "./types";

const orderbookHistoricalOrdersCache = new LRUCache<string, CacheEntry>(
DEFAULT_LRU_OPTIONS
);

export function getOrderbookHistoricalOrders({
userOsmoAddress,
assetLists,
chainList,
}: {
userOsmoAddress: string;
assetLists: AssetList[];
chainList: Chain[];
}) {
return cachified({
cache: orderbookHistoricalOrdersCache,
key: `orderbookHistoricalOrders-${userOsmoAddress}`,
ttl: 1000 * 3, // 3 seconds
ttl: 1000 * 2, // 2 seconds
getFreshValue: () =>
queryHistoricalOrders(userOsmoAddress).then((data) => {
queryHistoricalOrders(userOsmoAddress).then(async (data) => {
const orders = data;
orders.forEach((o) => {
if (o.status === "cancelled" && o.claimed_quantity !== "0") {
Expand All @@ -30,7 +41,119 @@ export function getOrderbookHistoricalOrders({
orders.push(newOrder);
}
});
return orders;

return await mapHistoricalToMapped(
orders,
userOsmoAddress,
assetLists,
chainList
);
}),
});
}

/**
* Gets an object containing a mapping between an orderbook address and it's quote and base asset.
* Each orderbook address is fetched once and only those present in the provided orders are queried.
*/
async function getRelevantOrderbookDenoms(
historicalOrders: HistoricalLimitOrder[],
assetLists: AssetList[],
chainList: Chain[]
): Promise<
Record<
string,
{
quoteAsset: ReturnType<typeof getAssetFromAssetList>;
baseAsset: ReturnType<typeof getAssetFromAssetList>;
}
>
> {
const orderbookAddresses = [
...new Set(historicalOrders.map(({ contract }) => contract)),
];

const promises = orderbookAddresses.map(async (orderbookAddress) => {
const denoms = await getOrderbookDenoms({
orderbookAddress,
assetLists,
chainList,
});
return [orderbookAddress, denoms];
});

const orderbookDenoms: Record<
string,
{
quoteAsset: ReturnType<typeof getAssetFromAssetList>;
baseAsset: ReturnType<typeof getAssetFromAssetList>;
}
> = {};
const orderbookDenomsArray = await Promise.all(promises);

for (let i = 0; i < orderbookDenomsArray.length; i++) {
const [contract, denoms]: any = orderbookDenomsArray[i];
orderbookDenoms[contract] = denoms;
}

return orderbookDenoms;
}

/**
* Data returned from the Numia query does not exactly match the interface used by the webapp.
* This function maps the Numia data to the webapp interface.
*/
async function mapHistoricalToMapped(
historicalOrders: HistoricalLimitOrder[],
userAddress: string,
assetLists: AssetList[],
chainList: Chain[]
): Promise<MappedLimitOrder[]> {
const orderbookDenoms = await getRelevantOrderbookDenoms(
historicalOrders,
assetLists,
chainList
);
return historicalOrders.map((o) => {
const { quoteAsset, baseAsset } = orderbookDenoms[o.contract];
const quantityMin = parseInt(o.quantity);
const placedQuantityMin = parseInt(o.quantity);
const price = tickToPrice(new Int(o.tick_id));
const percentClaimed = new Dec(1);
const output =
o.order_direction === "bid"
? new Dec(placedQuantityMin).quo(price)
: new Dec(placedQuantityMin).mul(price);

const normalizationFactor = new Dec(10).pow(
new Int((quoteAsset?.decimals ?? 0) - (baseAsset?.decimals ?? 0))
);

return {
quoteAsset,
baseAsset,
etas: "0",
order_direction: o.order_direction,
order_id: parseInt(o.order_id),
owner: userAddress,
placed_at:
dayjs(
o.place_timestamp && o.place_timestamp.length > 0
? o.place_timestamp
: 0
).unix() * 1000,
placed_quantity: parseInt(o.quantity),
placedQuantityMin,
quantityMin,
quantity: parseInt(o.quantity),
price: price.quo(normalizationFactor),
status: o.status as OrderStatus,
tick_id: parseInt(o.tick_id),
output,
percentClaimed,
percentFilled: new Dec(1),
totalFilled: parseInt(o.quantity),
orderbookAddress: o.contract,
};
});
}
1 change: 1 addition & 0 deletions packages/server/src/queries/complex/orderbooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from "./maker-fee";
export * from "./orderbook-state";
export * from "./pools";
export * from "./tick-state";
export * from "./types";
4 changes: 2 additions & 2 deletions packages/server/src/queries/complex/orderbooks/tick-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function getOrderbookTickState({
key: `orderbookTickInfo-${orderbookAddress}-${tickIds
.sort((a, b) => a - b)
.join(",")}`,
ttl: 1000 * 3, // 3 seconds
ttl: 1000 * 2, // 3 seconds
getFreshValue: () =>
queryOrderbookTicks({ orderbookAddress, chainList, tickIds }).then(
({ data }) => data.ticks
Expand All @@ -46,7 +46,7 @@ export function getOrderbookTickUnrealizedCancels({
key: `orderbookTickUnrealizedCancels-${orderbookAddress}-${tickIds
.sort((a, b) => a - b)
.join(",")}`,
ttl: 1000 * 3, // 3 seconds
ttl: 1000 * 2, // 3 seconds
getFreshValue: () =>
queryOrderbookTickUnrealizedCancelsById({
orderbookAddress,
Expand Down
Loading
Loading