haveno-dex / haveno Goto Github PK
View Code? Open in Web Editor NEWDecentralized P2P exchange built on Monero and Tor
Home Page: https://haveno.exchange
License: GNU Affero General Public License v3.0
Decentralized P2P exchange built on Monero and Tor
Home Page: https://haveno.exchange
License: GNU Affero General Public License v3.0
Bisq's history is heavy and messed up. Better to reset it.
This issue requests documenting key goals of Haveno (e.g. simplicity) and differences from Bisq (e.g. 2/3 multisig vs 2/2 multisig + refund process) in order to guide user interface design.
Bisq was using it, but we probably don't need it as it seems to be used to store DAO-related files. Files stored using git lfs:
f485f1a26f * p2p/src/main/resources/AccountAgeWitnessStore_BTC_MAINNET
0feba11eb9 * p2p/src/main/resources/BlindVoteStore_BTC_MAINNET
f56bde9875 * p2p/src/main/resources/DaoStateStore_BTC_MAINNET
ef168a7a11 * p2p/src/main/resources/ProposalStore_BTC_MAINNET
f91435a2a5 * p2p/src/main/resources/SignedWitnessStore_BTC_MAINNET
c6b7362593 * p2p/src/main/resources/TradeStatistics2Store_BTC_MAINNET
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':desktop'.
> Checksum failed for com.github.JesusMcCloud:jtorctl:389d61b1b5a85eb2f23c582c3913ede49f80c9f2b553e4762382c836270e57e5
Bisq seems to be having the same issue.
This issue requests adding a new API function to get market prices of all trade pairs.
This API call will provide market prices for the UI:
The following API function is a requested addition to HavenoDaemon.ts. Feedback is welcome.
API Function | Return | Description |
---|---|---|
havenod.getMarketPrices() |
MarketPrice[] |
Get market price data for all trade pairs. |
This function returns an array of MarketPrice
types, each with the following attributes:
MarketPrice
currencyCode: string
price: double // price per XMR
Note: the 24 hour price change and volume are not currently supported.
This new API function should be added to the Price
service of Haveno's protobuf definition, to be named GetMarketPrices
.
Follow these instructions to add and test the new API function end-to-end.
Currently fiat trades are limited to 0.01 XMR or ~4.72 USD. This issue requests increasing the limit.
This issue requests adding new API functions to start and stop a local Monero node.
The following functions are requested as additions to HavenoDaemon.ts. Feedback is welcome.
API Function | Return | Description |
---|---|---|
havenod.startMoneroNode(rpcUsername: string, rpcPassword: string) |
void |
Start local monerod process, throw error if fails. |
havenod.stopMoneroNode() |
void |
Stop local monerod process, throw error if fails. |
Start an internal monerod process using a constructor in MoneroDaemonRpc.java.
Refer to how monero-wallet-rpc instances are started and stopped in Haveno for reference as this pattern will be similar.
Follow these instructions to add and test new API functions end-to-end.
It's very important to have continuous testing. We should set up a CI service to test at least incoming PRs and the master branch. Probably the best option would be to use GitHub's workflows, but we could also consider other tools like Travis.
This issue requests fixing the price feed for the BTC/XMR pair.
Steps to reproduce:
This issue requests the ./bisq-*
cli tools be renamed to ./haveno-*.
.
"Currently, wallets make up to 4 requests each time a wallet polls a daemon: get_info, get_transaction_pool_hashes, get_transactions, and get_blocks.bin.
As a result, daemons must service up to 4 requests for each client poll, and the user may experience a noticeable delay before their wallet even starts to sync blocks if their connection is slow."
See the issue on the Monero repo for the full details: monero-project/monero#7571
Everything related to the Bisq DAO needs be removed from the platform and the repository, as we don't use it.
Feel free to open other issues related to removing the DAO, but use this one as reference of the status of the entire effort.
The legacy arbitration tab does not appear for Alice or Bob when opening their first dispute.
The legacy arbitration tab displays correctly after restarting the application.
Once a taker takes an offer, the trade in Open Trades shows errors: N/A for "Taker fee transaction ID" and "The peer's taker fee transaction is missing". These errors do not prevent trades from completing. Error checks and the legacy gui need updated to reflect the new trade protocol which does not have separate fee transactions.
Monero's multisig implementation has some vulnerabilities:
These bugs need to be fixed before Haveno goes live. @UkoeHB is working on a PR.
Haveno depends on the ability to get key images or output indices of spent outputs from transfer
and transfer_split
in monero-wallet-rpc, so this issue requests implementing that functionality in monero-project. See existing issue
This issue requests updating Haveno to use Tor v3.
See relevant issues in Bisq for reference: bisq-network/projects#23
This issue requests changing the Bisq logo currently used in the desktop client with Haveno's logo.
This issue requests a script which starts Haveno test nodes in 4 terminal tabs:
Note the node names also need to be renamed to ./haveno-*
: #24
This issue requests adding new API functions to manage Monero daemon connections.
These API calls will feed the UI to select and connect to a daemon connection:
The following API functions are requested additions to HavenoDaemon.ts. Feedback is welcome.
API Function | Return | Description |
---|---|---|
havenod.addMoneroConnection(connection: UriConnection) |
void |
Add managed connection. |
havenod.removeMoneroConnection(Uri: string) |
void |
Remove managed connection. |
havenod.getMoneroConnection() |
UriConnection |
Get current connection. |
havenod.getMoneroConnections() |
UriConnection[] |
Get all managed connections, never returns their login credentials. |
havenod.setMoneroConnection(Uri: string) |
void |
Set current connection based on current state. |
havenod.setMoneroConnection(connection: UriConnection) |
void |
Set current connection, overwrite login credentials. |
havenod.checkMoneroConnection() |
UriConnection |
Check status of current connection |
havenod.checkMoneroConnection(connection) |
UriConnection |
Check status of given connection. |
havenod.checkMoneroConnections() |
UriConnection[] |
Check status of all managed connections |
havenod.startCheckingConnection(refreshPeriod: number) |
void |
Automatically check the current connection status in a fixed period loop. |
havenod.stopCheckingConnection() |
void |
Stop automatically checking the current connection status. |
havenod.getBestAvailableConnection() |
UriConnection |
Get best available connection, null if no connections available. Checks all connections. |
havenod.setAutoSwitch(autoSwitch: boolean) |
void |
Automatically switch to best available connection if current connection disconnects. |
UriConnection
Uri: string
username: string
password: string
priority: int // the higher the number, the higher the relative priority
isOnline: boolean // whether or not the daemon is online
isAuthenticated: boolean // null if no authentication, true if authenticated, false if not authenticated
The following untested pseudocode demonstrates how the API can be used in the UI:
// get haveno's preset localhost connection
let localConnection;
for (let connection of await havenod.getMoneroConnections()) {
if (connection.getUri().contains("localhost")) {
localConnection = connection;
break;
}
}
if (!localConnection) throw new Error("Haveno expected to have preset localhost");
// connect to localhost if available
localConnectionStatus = await havenod.checkMoneroConnection(localConnection); // check localhost connection status
if (localConnectionStatus.isOnline()) {
if (localConnectionStatus.isAuthenticated() === false) {
localConnection.setCredentials("superuser", "abctesting123"); // set credentials if needed
await havenod.setMoneroConnection(localConnection); // overwrite connection credentials
} else {
await havenod.setMoneroConnection(localConnection.getUri()); // connect without changing login credentials
}
}
// select among connections
else {
let connections: UriConnection[] = await havenod.checkMoneroConnections();
let selectedConnection = connections[0]; // selectedConnection.isOnline() === true
if (selectedConnection.isAuthenticated() === false) {
selectedConnection.setCredentials("superuser", "abctesting123");
await havenod.setMoneroConnection(selectedConnection);
} else {
await havenod.setMoneroConnection(selectedConnection.getUri());
}
// verify connection
let connectionStatus = await havenod.checkMoneroConnection();
assert(connectionStatus.getUri() === selectedConnection.getUri() && connectionStatus.isOnline() && connectionStatus.isAuthenticated() !== false);
}
These new API functions should be added as a new service, e.g. MoneroConnections
, in Haveno's protobuf definition.
They should be implemented using monero-java's MoneroConnectionManager on the backend, which provides a direct mapping to these API calls.
Some hardcoded connections should be automatically added to the manager, e.g. http://localhost:38081 for default local stagenet.
Any managed connections should be persisted to disk and loaded on startup using the UriConnection
type.
Any connection passwords should probably be encrypted with the user's account password.
Follow these instructions to add and test new API functions end-to-end.
Haveno's Java backend currently consumes significantly more computing resource than is necessary.
For example, performance analysis revealed the Bisq DAO to consume significant resources which will be resolved when the DAO is removed.
This issue requests detailed reports on Haveno's current resource usage in order to achieve significant performance improvements.
Specifically requested is a list breaking down top time consumers while running the application, including references to related code in order to inform where optimizations are needed and focus developer effort.
For example, this performance analysis on Monero's daemon breaks down time consumers and related code: monero-project/monero#7913 (comment)
There are many tools to analyze performance of a Java application like JVM Monitor built into Eclipse or VisualVM.
Currently Haveno depends on a Bitcoin node, Bitcoin-Qt, for proper startup and function.
This issue requests removing this dependency completely disabling the BTC dependency, since it's not necessary for XMR as a base pair.
This issue requests supporting multiple addresses and amounts in monero-wallet-rpc's make_uri and parse_uri.
This will be used to deposit 2 outputs to the Haveno wallet, one to cover the deposit amount and one to cover the trade fee, in order to allow trades to be posted and taken once funds are available.
This issue requests adding new API functions to create or restore a Haveno account on startup.
These API calls will be used to feed Haveno's startup UI:
The following API functions are requested additions to HavenoDaemon.ts. Note it is also considered if Haveno should manage multiple accounts, identified by pathname, under one directory provided at startup. Feedback is welcome.
API Function | Return | Description |
---|---|---|
havenod.accountExists() |
boolean | Indicates if the Haveno account is created. |
havenod.isAccountOpen() |
boolean | Indicates if the Haveno account is open and authenticated with the correct password. |
havenod.createAccount(password: string) |
void | Create and open a new Haveno account. Throw error if accountExists() . |
havenod.openAccount(password: string) |
void | Open existing account. Throw error if `!accountExists() |
havenod.closeAccount() |
void | Close the currently open account. Throw error if !isAccountOpen() . |
havenod.backupAccount() |
zip bytes for download | Backup the account to a zip file. Throw error if !accountExists() . |
havenod.deleteAccount() |
void | Permanently delete the Haveno account. |
havenod.restoreAccount(zip: zip) |
void | Restore the account from a zip file. Throw error if accountExists() . |
havenod.changePassword(password: string) |
void | Change the Haveno account password. Throw error if !isAccountOpen() . |
Currently, ./haveno-daemon
automatically initializes an account folder with the name provided at startup using the --appName
argument.
Instead, ./haveno-daemon
should start its gRPC API and wait for createAccount()
or restoreAccount()
to be called to initialize the account folder.
These API calls should be added as a new service, e.g. HavenoAccount
, in Haveno's protobuf definition.
Follow these instructions to add and test new API functions end-to-end.
It'd be helpful if there was some guidance how to set up this repository in Eclipse. In particular:
Since the .gitignore contains .project
, I assume that developers are using Eclipse, too. Maybe it's also an option to commit such configuration (I also can imagine committing a physical Eclipse run configuration).
Creating such guide would ease the life of new potential developers/contributors.
To reproduce:
An error occurred at task: BuyerCreateAndSignPayoutTx
Exception message: not enough money
Error in Bob's terminal:
Feb-20 15:06:02.109 [JavaFX Application Thread] ERROR bisq.common.taskrunner.Task: An error occurred at task: BuyerCreateAndSignPayoutTx
Exception message: not enough money
Feb-20 15:06:02.116 [JavaFX Application Thread] ERROR b.common.taskrunner.TaskRunner: Task failed: BuyerCreateAndSignPayoutTx / errorMessage: An error occurred at task: BuyerCreateAndSignPayoutTx
Exception message: not enough money
Feb-20 15:06:02.119 [JavaFX Application Thread] ERROR b.c.t.protocol.TradeProtocol: Task runner failed with error An error occurred at task: BuyerCreateAndSignPayoutTx
Exception message: not enough money. Triggered from PAYMENT_SENT
Log file from: bisq.log
We use a labelling system to keep things organized and to make easy for potential contributors to jump in. These labels are purposely generic, so to be helpful, but not restricting or too time consuming.
We have 4 main categories of labels. Every issue should have at least the label specifying the issue type (is:
), but would be also good to include the 'about' label, to specify what section of Haveno the issue is about (a:
). The priority label (Pn
) is not strictly necessary, but it's helpful to make clear how urgent is the issue/request.
a:
)The part of Haveno the issue is about. Will help people to filter only the issues related to the area they are interested to.
Some examples:
is:
)The type of issue/request.
some examples:
Pn
)A simple priority process. Issues with higher priority should be worked first.
needs:
)These labels will be used as needed, for both issues and pull requests. They usually imply that the issue is blocked until a problem is solved or some info are provided.
some examples:
We might use other labels when needed. As said at the beginning, this structure aims to be simple and not too strict.
Currently Haveno is only tested using local test networks on developer machines.
This issue requests deploying a shared test network using Haveno seed nodes for developers to test.
My key was added with #133.
All files have a copyright header which says This file is part of Bisq.[...]
.
All these headers will have to say This file is part of Haveno.[...]
. I have a PR read, but on a second thought it's probably better to wait until we start to heavily trim the code of Bisq content we don't need. A lot of file will be deleted, no reason to change their copyright header now.
Monero's multisig is vulnerable to the Wagner attack, where if multiple signatures are constructed for a given address, and the wagner attack is executed, then the attacker can learn the private key shares of other participants.
This (and #102 ) has been discussed with Monero's core team (@luigi1111) and researchers (@moneromooo-monero, @SarangNoether and @UkoeHB.)
Sarang's suggestion is to fix the vulnerability by implementing the constructions specified in MRL-0009. Discussions are ongoing.
At the moment our github action workflow calls ./gradlew build
. We should change it to use the newly added Makefile instead (#105)
Haveno depends on the ability to freeze and thaw outputs from monero-wallet-rpc, so this issue requests implementing that functionality in monero-project. See existing issue
https://mvnrepository.com/com/fasterxml/jackson/module/jackson-module-jaxb-annotations/maven-metadata.xml
seems to not exist anymore.
./gradlew build --scan
:
> Configure project :desktop
Evaluating project ':desktop' using build file '/haveno/desktop/build.gradle'.
Failed to get resource: GET. [HTTP HTTP/1.1 403 Forbidden: https://mvnrepository.com/com/fasterxml/jackson/module/jackson-module-jaxb-annotations/maven-metadata.xml)]
Verifying aopalliance:aopalliance
Verifying ch.qos.logback:logback-classic
Verifying ch.qos.logback:logback-core
Verifying com.fasterxml.jackson.core:jackson-annotations
FAILURE: Build failed with an exception.
This issue requests adding new API functions to get transfers and withdraw funds.
These API calls will feed the UI wallet functionality:
The following functions are requested as additions to HavenoDaemon.ts. Feedback is welcome.
API Function | Return | Description |
---|---|---|
havenod.getXmrTxs() |
XmrTx[] |
Get all transactions with transfers from or to Haveno's Monero wallet. |
havenod.createXmrTx(destinations: XmrDestination) |
XmrTx |
Create but do not relay a transaction to send funds from Haveno's Monero wallet. |
havenod.relayXmrTx(txMetadata: string) |
string |
Relay a previously created transaction. |
XmrTx
hash: string
timestamp: timestamp
transfers: XmrTransfer[]
metadata: string // used to later relay the transaction
XmrTransfer
address: string
amount: BigInt // as string in gRPC
isIncoming: boolean
destinations: XmrDestination[] // only present on outgoing transfers from local wallet data
XmrDestination
address: string
amount: BigInt // as string in gRPC
Note these wallet functions are already implemented:
API Function | Return | Description |
---|---|---|
havenod.getNewDepositSubaddress() |
string |
Get a new subaddress in the Haveno wallet to receive deposits. |
havenod.getBalances() |
XmrBalanceInfo |
Get the user's Monero balances. |
A test should be added to HavenoDaemon.test.ts to test all Haveno wallet functions including sending and receiving funds and testing wallet balances and transactions.
Follow these instructions to add and test new API functions end-to-end.
Currently the following balances are displayed:
This issue requests the displayed balances be changed to:
Curious why you've decided to entirely fork bisq
when they're already looking at adding this?
Relevant issue set:
I mean all the power to you but just seems like burning rubber on many roads.
Currently, creating crypto payment accounts is unsupported using the grpc api.
This issue requests implementing support for crypto payments over the grpc api here:
To run a test which exercises the grpc call to create a crypto payment account:
npm test
This test should pass after support is implemented.
This issue requests support to periodically backup all XMR wallets and the BTC wallet in the application folder to ./xmr_stagenet/wallet/backup like what is currently done with the BSQ wallet.
This issue requests adding new API functions to get market depth data of a trade pair.
This API call will provide market depth data for the UI:
The following function is a requested addition to HavenoDaemon.ts. Feedback is welcome.
API Function | Return | Description |
---|---|---|
havenod.getMarketDepth(currencyCode) |
MarketDepth |
Get market depth data for a trade pair |
The following type is returned:
MarketDepth
currencyCode: string
buyPrices: double[]
buyDepth: double[]
sellPrices: double[]
sellDepth: double[]
This new API function should be added to the Price
service of Haveno's protobuf definition, to be named GetMarketDepth
.
It should return the same data points as currently used in the desktop app.
Follow these instructions to add and test the new API function end-to-end.
Currently a taker must pay a trade fee before initializing the multisig wallet with the maker and arbitrator in order to prevent takers from spamming peers with unpaid work by creating multisig wallets.
As a result, the taker must have 2 outputs available in order to take a trade, one to cover the trade fee and one to deposit to multisig, which complicates the user experience. If the multisig wallet address could be known ahead of time, the taker could use one output to pay both the trade fee and the deposit tx in a single transaction.
Chapter 10 of Zero to Monero describes a way to derive the address of a multisig wallet before initializing the wallet among peers. The first two peers (maker and arbitrator) create a shared secret and publish its public key which the third peer (the taker) can use to derive the multisig address before the wallet is initialized among them.
This issue requests implementing the ability to derive multisig wallet addresses using this method. The implementation should be added to monero-project.
At the moment XMR <-> Fiat trades are broken. The market appears always as xmr/xmr, even if we use fiat currencies (tested with EUR and USD).
To reproduce:
When looking at the "buy xmr" tab from Bob's window, Alice's offer is grey. When clicking on "TAKE OFFER TO SELL XMR", i get a pop up saying "No matching payment account" and suggest me to create one, but the payment account exists.
There are many details to consider, finalize, and harden in the core trade protocol and code.
Priorities
Trade Completion
Optimizations / Performance
API Functions
Needs Consideration
Note additional core todos are throughout the code prefixed with TODO (woodser)
.
Haveno's user interface is currently written in Java which limits design flexibility compared to modern UI frameworks like React and tightly couples frontend with backend application logic.
This issue requests a proof of concept demonstrating React communicating with the Haveno Java backend. For example, the React application could simply display posted offers or the user's open trades.
Possible technical approaches:
When attempting to clone the repository by running:
git clone https://github.com/haveno-dex/haveno.git
I get the following output:
Cloning into 'haveno'...
remote: Enumerating objects: 268676, done.
remote: Counting objects: 100% (286/286), done.
remote: Compressing objects: 100% (200/200), done.
error: RPC failed; curl 56 GnuTLS recv error (-54): Error in the pull function.
fatal: the remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
Changing the Revolut account on Bisq, it use to be that on the Revolut account you had to put username and phone number, later that was changed to just the username.
Changing just the account of Revolut to a username only on Bisq means to delete the account and lose the signed status and age. I thought that it would by nice that in Haveno there was a possibility to transfer that aged status with a private key for an upgrade account that benefits privacy, or accounts age and status to be determined by user not by individual from of payment.
As is likely that services will change overtime and they may offer a better alternative as it was on Revolut that might help having more privacy having that feature would be good for the traders to preserve status, aged and signed
When trying to add a Bitcoin address as an "altcoin" account the sanity check fails. I tried all types of Bitcoin address, but hey all fail.
Currently the reserved balance does not include all funds reserved in trades. This issue requests that all funds reserved for trades be included. That includes:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.