If the switch is enabled, the maker gets price suggestions based on the current
ask price on Bitmex + 3% spread.
Auto-refresh turns off whenever user modifies the field manually, and can be
re-enabled later if desired.
Fixes#214
Add support for multiple update proposals.
A taker might request to update/change a CFD in different ways, e.g.: propose to settle it or roll over.
In order to support different scenarios we introduce another layer of abstraction.
The rest of the changes creates a boilerplate for the actual rollover protocol.
* Offer price based on current price
To keep it simple we set the offer price to current price + 3% spread if we have a current price and the offer's initial value is 0.
This. means we cannot set the offer price to 0 anymore, but that is OK.
Additionally, there is a refresh button so the maker can refresh the offer price (no auto-refresh for now).
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
All display related decisions are taken in the UI, but on top of the UI's model.
For this purpose we introduce classes for `CfdState` and `Position` so we can add the relevant mapping functions to these classes.
To achieve the mapping from daemon sse even to the `Cfd` / `Order` interface (that now contain classes instead of just primitives) we extend the sse hook to accept a mapping function.
We define this mapping function for `Cfd` and `Order`, because those contain classes, for all others we just use the default mapping.
Actions are dynamically rendered based on the state.
The daemon decides on the action name.
A single post endpoint handles all actions.
The UI maps the actions to icons.
Co-authored-by: Thomas Eizinger <thomas@coblox.tech>
The Grid was restrictive and caused problems overlapping things.
We can achieve better layouting with flex components (for now mostly HStack and VStack flexes).
We can eventually also add space bounds to the flexes for more layourting (i.e. graph should take 70% on right...), but for now I kept it rather simple.
I experimented with Grids for the tiles where we group information (i.e. Buy, Order) but it did not look good, so I amd using flexes with fixed label width for better looks.
The only thing that has to stay in the root is the `index.html` file,
otherwise the dev server doesn't pick it up.
Also make sure our frontend tests actually run and pass in CI.
- wallet feed that sends balance + current address
- display in UI (balance + address) in separate wallet component (shared for taker and maker for now)
Includes two seed files that are already funded with some testnet coins. We can share those for testing for now. If more funds are needed I'm happy to top them up.
Achieving this is rather tricky due to the nature of our multi-page
project. We need to solve several problems:
1. We want a single npm project that produces two independent bundles.
2. We want our paths to be relative to the serving URL, that is `localhost:3000`
in development and in production, whereever the backend is hosted.
3. We have independent backends, hence requiring different `server.proxy`
configurations.
We solve (1) by using vite (already prior to this commit).
To solve (2), we simply remove all absolute URLs from the code and replace
them with absolute paths which will be relative to the serving host.
This creates a problem: Prior to this patch, we only have one devServer running
that would serve both frontends under a different sub-directory (/maker and /taker).
Even though this worked, it was impossible to create a proxy configuration that would:
- Forward API requests from `/maker` to `localhost:8001`
- Forward API requests from `/taker` to `localhost:8000`
Because in both cases, the API requests would simply start with `/api`, making
them indistinguishable from each other.
To solve this problem, we needed to serve each frontend separately. Doing so
would allow us to have dedicated proxy server configurations and forward the
requests to `/api` to the correct backend.
Unfortunately, the intuitive approach of solving this (have a `maker.html` and
`taker.html` file) does not work. With React being a client-side routing framework,
full page-reloads would be broken with this approach because they would be looking
for an `index.html` file which doesn't exist.
To work around this issue, our final solution is:
1. Use a dynamic ID to reference the desired app from within the `index.html`: `__app__`
2. Use a vite plugin to resolve this ID to the file in question: `maker.tsx` or `taker.tsx`
Fixes#6.