can get offers from haveno daemon

This commit is contained in:
woodser 2021-09-11 12:12:55 -04:00
parent 188db88629
commit 6f149b1b95
3 changed files with 168 additions and 24 deletions

View file

@ -3,6 +3,9 @@ import logo from './logo.png';
import './App.css'; import './App.css';
import {HavenoDaemon} from './HavenoDaemon'; import {HavenoDaemon} from './HavenoDaemon';
const HAVENO_DAEMON_URL = "http://localhost:8080";
const HAVENO_DAEMON_PASSWORD = "apitest";
class App extends React.Component<{}, {daemonVersion: string}> { class App extends React.Component<{}, {daemonVersion: string}> {
daemon: HavenoDaemon; daemon: HavenoDaemon;
@ -10,7 +13,7 @@ class App extends React.Component<{}, {daemonVersion: string}> {
constructor(props: any) { constructor(props: any) {
super(props); super(props);
this.state = {daemonVersion: ""}; this.state = {daemonVersion: ""};
this.daemon = new HavenoDaemon("http://localhost:8080", undefined, "apitest"); this.daemon = new HavenoDaemon(HAVENO_DAEMON_URL, HAVENO_DAEMON_PASSWORD);
} }
render() { render() {
@ -38,7 +41,12 @@ class App extends React.Component<{}, {daemonVersion: string}> {
} }
async componentDidMount() { async componentDidMount() {
try {
this.setState({daemonVersion: await this.daemon.getVersion()}); this.setState({daemonVersion: await this.daemon.getVersion()});
} catch (err) {
console.error(err);
this.setState({daemonVersion: " not available"});
}
} }
} }

View file

@ -1,11 +1,10 @@
import {HavenoDaemon, BalancesModel} from "./HavenoDaemon"; import {HavenoDaemon, HavenoBalances, HavenoOffer} from "./HavenoDaemon";
const HAVENO_UI_VERSION = "1.6.2"; const HAVENO_UI_VERSION = "1.6.2";
const HAVENO_DAEMON_URL = "http://localhost:8080"; const HAVENO_DAEMON_URL = "http://localhost:8080";
const HAVENO_DAEMON_USERNAME = undefined;
const HAVENO_DAEMON_PASSWORD = "apitest"; const HAVENO_DAEMON_PASSWORD = "apitest";
const daemon = new HavenoDaemon(HAVENO_DAEMON_URL, HAVENO_DAEMON_USERNAME, HAVENO_DAEMON_PASSWORD); const daemon = new HavenoDaemon(HAVENO_DAEMON_URL, HAVENO_DAEMON_PASSWORD);
test("Can get the version", async () => { test("Can get the version", async () => {
let version = await daemon.getVersion(); let version = await daemon.getVersion();
@ -13,9 +12,21 @@ test("Can get the version", async () => {
}); });
test("Can get the user's balances", async () => { test("Can get the user's balances", async () => {
let balances: BalancesModel = await daemon.getBalances(); let balances: HavenoBalances = await daemon.getBalances();
expect(balances.unlockedBalance); expect(balances.unlockedBalance);
expect(balances.lockedBalance); expect(balances.lockedBalance);
expect(balances.reservedOfferBalance); expect(balances.reservedOfferBalance);
expect(balances.reservedTradeBalance); expect(balances.reservedTradeBalance);
}); });
test("Can get offers", async() => {
let offers: HavenoOffer[] = await daemon.getOffers("SELL", "XMR");
for (let offer of offers) {
testOffer(offer);
}
});
function testOffer(offer: HavenoOffer) {
expect(offer.id).toHaveLength;
// TODO: test rest of offer
}

View file

@ -1,10 +1,10 @@
/** /**
* These files are generated by protoc-gen-grpc-web (created with `sudo make install-plugin` in grpc-web) using the following command: * These imports are generated by protoc-gen-grpc-web (created with `sudo make install-plugin` in grpc-web) using the following command:
* *
* `protoc -I=./ *.proto --js_out=import_style=commonjs:./ --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./` * `protoc -I=./ *.proto --js_out=import_style=commonjs:./ --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./`
*/ */
const {GetVersionRequest, WalletsClient} = require('./grpc_grpc_web_pb.js'); const {GetVersionRequest, WalletsClient, OffersClient} = require('./grpc_grpc_web_pb.js');
const {GetVersionClient, GetBalancesRequest} = require('./grpc_pb.js'); const {GetVersionClient, GetBalancesRequest, GetOffersRequest} = require('./grpc_pb.js');
/** /**
* Haveno daemon client using gRPC. * Haveno daemon client using gRPC.
@ -13,19 +13,19 @@ class HavenoDaemon {
// instance variables // instance variables
_url: string; _url: string;
_username?: string;
_password?: string; _password?: string;
_getVersionClient: any;
_walletsClient?: any;
_offersClient?: any;
/** /**
* Construct a client connected to a Haveno daemon. * Construct a client connected to a Haveno daemon.
* *
* @param {string} url - Haveno daemon url * @param {string} url - Haveno daemon url
* @param {string} username - Haveno daemon username if applicable
* @param {string} password - Haveno daemon password if applicable * @param {string} password - Haveno daemon password if applicable
*/ */
constructor(url: string, username?: string, password?: string) { constructor(url: string, password?: string) {
this._url = url; this._url = url;
this._username = username;
this._password = password; this._password = password;
} }
@ -35,11 +35,11 @@ class HavenoDaemon {
* @return {string} the Haveno daemon version * @return {string} the Haveno daemon version
*/ */
async getVersion(): Promise<string> { async getVersion(): Promise<string> {
let getVersionClient = new GetVersionClient(this._url); // TODO: use one instance, username, password if (!this._getVersionClient) this._getVersionClient = new GetVersionClient(this._url);
let request = new GetVersionRequest(); let request = new GetVersionRequest();
let that = this; let that = this;
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
getVersionClient.getVersion(request, {password: that._password}, function(err: any, response: any) { that._getVersionClient.getVersion(request, {password: that._password}, function(err: any, response: any) {
if (err) reject(err); if (err) reject(err);
else resolve(response.getVersion()); else resolve(response.getVersion());
}); });
@ -49,16 +49,16 @@ class HavenoDaemon {
/** /**
* Get the user's balances. * Get the user's balances.
* *
* @return {BalancesModel} the user's balances * @return {HavenoBalances} the user's balances
*/ */
async getBalances(): Promise<BalancesModel> { async getBalances(): Promise<HavenoBalances> {
let walletsClient = new WalletsClient(this._url); if (!this._walletsClient) this._walletsClient = new WalletsClient(this._url);
let request = new GetBalancesRequest(); let request = new GetBalancesRequest();
let that = this; let that = this;
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
walletsClient.getBalances(request, {password: that._password}, function(err: any, response: any) { that._walletsClient.getBalances(request, {password: that._password}, function(err: any, response: any) {
if (err) reject(err); if (err) reject(err);
else resolve(new BalancesModel( else resolve(new HavenoBalances(
BigInt(response.getBalances().getXmr().getUnlockedbalance()), BigInt(response.getBalances().getXmr().getUnlockedbalance()),
BigInt(response.getBalances().getXmr().getLockedbalance()), BigInt(response.getBalances().getXmr().getLockedbalance()),
BigInt(response.getBalances().getXmr().getReservedofferbalance()), BigInt(response.getBalances().getXmr().getReservedofferbalance()),
@ -66,9 +66,61 @@ class HavenoDaemon {
}); });
}); });
} }
/**
* Get available offers.
*
* @param {string} direction - one of "BUY" or "SELL"
* @param {string} currencyCode - the currency being bought or sold, e.g. "ETH"
*
* @return {HavenoOffer[]} available offers
*/
async getOffers(direction: string, currencyCode: string): Promise<HavenoOffer[]> {
if (!this._offersClient) this._offersClient = new OffersClient(this._url);
let request = new GetOffersRequest()
.setDirection(direction)
.setCurrencycode(currencyCode);
let that = this;
return new Promise(function(resolve, reject) {
that._offersClient.getOffers(request, {password: that._password}, function(err: any, response: any) {
if (err) reject(err);
else {
let offers: HavenoOffer[] = [];
for (let offer of response.getOffersList()) {
offers.push(new HavenoOffer(
offer.getId(),
offer.getDirection(),
offer.getPrice(),
offer.getUsemarketbasedprice(),
offer.getMarketpricemargin(),
offer.getAmount(),
offer.getMinamount(),
offer.getVolume(),
offer.getMinvolume(),
offer.getBuyersecuritydeposit(),
offer.getTriggerprice(),
offer.getIscurrencyformakerfeebtc(),
offer.getPaymentaccountid(),
offer.getPaymentmethodid(),
offer.getPaymentmethodshortname(),
offer.getBasecurrencycode(),
offer.getCountercurrencycode(),
offer.getDate(),
offer.getState(),
offer.getSellersecuritydeposit(),
offer.getOfferfeepaymenttxid(),
offer.getTxfee(),
offer.getMakerfee()
));
}
resolve(offers);
}
});
});
}
} }
class BalancesModel { class HavenoBalances {
unlockedBalance: bigint; unlockedBalance: bigint;
lockedBalance: bigint; lockedBalance: bigint;
reservedOfferBalance: bigint; reservedOfferBalance: bigint;
@ -84,4 +136,77 @@ class BalancesModel {
} }
} }
export {HavenoDaemon, BalancesModel}; class HavenoOffer {
id: string;
direction: string;
price: bigint;
useMarketBasedPrice: boolean;
marketPriceMargin: number;
amount: bigint;
minAmount: bigint;
volume: bigint;
minVolume: bigint;
buyerSecurityDeposit: bigint;
triggerPrice: bigint;
isCurrencyForMakerFeeBtc: boolean;
paymentAccountId: string;
paymentMethodId: string;
paymentMethodShortName: string;
baseCurrencyCode: string;
counterCurrencyCode: string;
date: bigint;
state: string;
sellerSecurityDeposit: bigint;
offerFeePaymentTxId: string;
txFee: bigint;
makerFee: bigint;
constructor(id: string,
direction: string,
price: bigint,
useMarketBasedPrice: boolean,
marketPriceMargin: number,
amount: bigint,
minAmount: bigint,
volume: bigint,
minVolume: bigint,
buyerSecurityDeposit: bigint,
triggerPrice: bigint,
isCurrencyForMakerFeeBtc: boolean,
paymentAccountId: string,
paymentMethodId: string,
paymentMethodShortName: string,
baseCurrencyCode: string,
counterCurrencyCode: string,
date: bigint,
state: string,
sellerSecurityDeposit: bigint,
offerFeePaymentTxId: string,
txFee: bigint,
makerFee: bigint,) {
this.id = id;
this.direction = direction;
this.price = price;
this.useMarketBasedPrice = useMarketBasedPrice;
this.marketPriceMargin = marketPriceMargin;
this.amount = amount;
this.minAmount = minAmount;
this.volume = volume;
this.minVolume = minVolume;
this.buyerSecurityDeposit = buyerSecurityDeposit;
this.triggerPrice = triggerPrice;
this.isCurrencyForMakerFeeBtc = isCurrencyForMakerFeeBtc;
this.paymentAccountId = paymentAccountId;
this.paymentMethodId = paymentMethodId;
this.paymentMethodShortName = paymentMethodShortName;
this.baseCurrencyCode = baseCurrencyCode;
this.counterCurrencyCode = counterCurrencyCode;
this.date = date;
this.state = state;
this.sellerSecurityDeposit = sellerSecurityDeposit;
this.offerFeePaymentTxId = offerFeePaymentTxId;
this.txFee = txFee;
this.makerFee = makerFee;
}
}
export {HavenoDaemon, HavenoBalances, HavenoOffer};