mirror of
https://github.com/haveno-dex/haveno-ts.git
synced 2025-07-31 02:28:36 -04:00
add HavenoDaemon api class and jest tests supporting version and balances (#8)
This commit is contained in:
parent
56975a6022
commit
bea11ab1f4
9 changed files with 6316 additions and 2834 deletions
31
src/App.tsx
31
src/App.tsx
|
@ -1,20 +1,19 @@
|
|||
import React from 'react';
|
||||
import logo from './logo.png';
|
||||
import './App.css';
|
||||
import {HavenoDaemon} from './HavenoDaemon';
|
||||
|
||||
/**
|
||||
* These files 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:./`
|
||||
*/
|
||||
const {GetVersionRequest} = require('./grpc_grpc_web_pb.js');
|
||||
const {GetVersionClient} = require('./grpc_pb.js');
|
||||
const HAVENO_DAEMON_URL = "http://localhost:8080";
|
||||
const HAVENO_DAEMON_PASSWORD = "apitest";
|
||||
|
||||
class App extends React.Component<{}, {daemonVersion: string}> {
|
||||
|
||||
daemon: HavenoDaemon;
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = {daemonVersion: ""};
|
||||
this.daemon = new HavenoDaemon(HAVENO_DAEMON_URL, HAVENO_DAEMON_PASSWORD);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -42,18 +41,12 @@ class App extends React.Component<{}, {daemonVersion: string}> {
|
|||
}
|
||||
|
||||
async componentDidMount() {
|
||||
this.setState({daemonVersion: await this.getDaemonVersion()});
|
||||
}
|
||||
|
||||
async getDaemonVersion(): Promise<string> {
|
||||
let getVersionClient = new GetVersionClient('http://localhost:8080');
|
||||
let request = new GetVersionRequest();
|
||||
return new Promise(function(resolve, reject) {
|
||||
getVersionClient.getVersion(request, {password: 'apitest'}, function(err: any, response: any) {
|
||||
if (err) reject(err);
|
||||
else resolve(response.getVersion());
|
||||
});
|
||||
});
|
||||
try {
|
||||
this.setState({daemonVersion: await this.daemon.getVersion()});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
this.setState({daemonVersion: " not available"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
32
src/HavenoDaemon.test.tsx
Normal file
32
src/HavenoDaemon.test.tsx
Normal file
|
@ -0,0 +1,32 @@
|
|||
import {HavenoDaemon, HavenoBalances, HavenoOffer} from "./HavenoDaemon";
|
||||
|
||||
const HAVENO_UI_VERSION = "1.6.2";
|
||||
const HAVENO_DAEMON_URL = "http://localhost:8080";
|
||||
const HAVENO_DAEMON_PASSWORD = "apitest";
|
||||
|
||||
const daemon = new HavenoDaemon(HAVENO_DAEMON_URL, HAVENO_DAEMON_PASSWORD);
|
||||
|
||||
test("Can get the version", async () => {
|
||||
let version = await daemon.getVersion();
|
||||
expect(version).toEqual(HAVENO_UI_VERSION);
|
||||
});
|
||||
|
||||
test("Can get the user's balances", async () => {
|
||||
let balances: HavenoBalances = await daemon.getBalances();
|
||||
expect(balances.unlockedBalance);
|
||||
expect(balances.lockedBalance);
|
||||
expect(balances.reservedOfferBalance);
|
||||
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
|
||||
}
|
212
src/HavenoDaemon.tsx
Normal file
212
src/HavenoDaemon.tsx
Normal file
|
@ -0,0 +1,212 @@
|
|||
/**
|
||||
* 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:./`
|
||||
*/
|
||||
const {GetVersionRequest, WalletsClient, OffersClient} = require('./grpc_grpc_web_pb.js');
|
||||
const {GetVersionClient, GetBalancesRequest, GetOffersRequest} = require('./grpc_pb.js');
|
||||
|
||||
/**
|
||||
* Haveno daemon client using gRPC.
|
||||
*/
|
||||
class HavenoDaemon {
|
||||
|
||||
// instance variables
|
||||
_url: string;
|
||||
_password?: string;
|
||||
_getVersionClient: any;
|
||||
_walletsClient?: any;
|
||||
_offersClient?: any;
|
||||
|
||||
/**
|
||||
* Construct a client connected to a Haveno daemon.
|
||||
*
|
||||
* @param {string} url - Haveno daemon url
|
||||
* @param {string} password - Haveno daemon password if applicable
|
||||
*/
|
||||
constructor(url: string, password?: string) {
|
||||
this._url = url;
|
||||
this._password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Haveno version.
|
||||
*
|
||||
* @return {string} the Haveno daemon version
|
||||
*/
|
||||
async getVersion(): Promise<string> {
|
||||
if (!this._getVersionClient) this._getVersionClient = new GetVersionClient(this._url);
|
||||
let request = new GetVersionRequest();
|
||||
let that = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
that._getVersionClient.getVersion(request, {password: that._password}, function(err: any, response: any) {
|
||||
if (err) reject(err);
|
||||
else resolve(response.getVersion());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user's balances.
|
||||
*
|
||||
* @return {HavenoBalances} the user's balances
|
||||
*/
|
||||
async getBalances(): Promise<HavenoBalances> {
|
||||
if (!this._walletsClient) this._walletsClient = new WalletsClient(this._url);
|
||||
let request = new GetBalancesRequest();
|
||||
let that = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
that._walletsClient.getBalances(request, {password: that._password}, function(err: any, response: any) {
|
||||
if (err) reject(err);
|
||||
else resolve(new HavenoBalances(
|
||||
BigInt(response.getBalances().getXmr().getUnlockedbalance()),
|
||||
BigInt(response.getBalances().getXmr().getLockedbalance()),
|
||||
BigInt(response.getBalances().getXmr().getReservedofferbalance()),
|
||||
BigInt(response.getBalances().getXmr().getReservedtradebalance())));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 HavenoBalances {
|
||||
unlockedBalance: bigint;
|
||||
lockedBalance: bigint;
|
||||
reservedOfferBalance: bigint;
|
||||
reservedTradeBalance: bigint;
|
||||
constructor(unlockedBalance: bigint,
|
||||
lockedBalance: bigint,
|
||||
reservedOfferBalance: bigint,
|
||||
reservedTradeBalance: bigint) {
|
||||
this.unlockedBalance = unlockedBalance;
|
||||
this.lockedBalance = lockedBalance;
|
||||
this.reservedOfferBalance = reservedOfferBalance;
|
||||
this.reservedTradeBalance = reservedTradeBalance;
|
||||
}
|
||||
}
|
||||
|
||||
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};
|
|
@ -16533,11 +16533,10 @@ proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.toObject = function(opt_inclu
|
|||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
balance: jspb.Message.getFieldWithDefault(msg, 1, 0),
|
||||
availablebalance: jspb.Message.getFieldWithDefault(msg, 2, 0),
|
||||
lockedbalance: jspb.Message.getFieldWithDefault(msg, 3, 0),
|
||||
reservedbalance: jspb.Message.getFieldWithDefault(msg, 4, 0),
|
||||
totalbalance: jspb.Message.getFieldWithDefault(msg, 5, 0)
|
||||
unlockedbalance: jspb.Message.getFieldWithDefault(msg, 1, 0),
|
||||
lockedbalance: jspb.Message.getFieldWithDefault(msg, 2, 0),
|
||||
reservedofferbalance: jspb.Message.getFieldWithDefault(msg, 3, 0),
|
||||
reservedtradebalance: jspb.Message.getFieldWithDefault(msg, 4, 0)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
|
@ -16576,23 +16575,19 @@ proto.io.bisq.protobuffer.XmrBalanceInfo.deserializeBinaryFromReader = function(
|
|||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {number} */ (reader.readUint64());
|
||||
msg.setBalance(value);
|
||||
msg.setUnlockedbalance(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {number} */ (reader.readUint64());
|
||||
msg.setAvailablebalance(value);
|
||||
msg.setLockedbalance(value);
|
||||
break;
|
||||
case 3:
|
||||
var value = /** @type {number} */ (reader.readUint64());
|
||||
msg.setLockedbalance(value);
|
||||
msg.setReservedofferbalance(value);
|
||||
break;
|
||||
case 4:
|
||||
var value = /** @type {number} */ (reader.readUint64());
|
||||
msg.setReservedbalance(value);
|
||||
break;
|
||||
case 5:
|
||||
var value = /** @type {number} */ (reader.readUint64());
|
||||
msg.setTotalbalance(value);
|
||||
msg.setReservedtradebalance(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
|
@ -16623,49 +16618,42 @@ proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.serializeBinary = function()
|
|||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getBalance();
|
||||
f = message.getUnlockedbalance();
|
||||
if (f !== 0) {
|
||||
writer.writeUint64(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getAvailablebalance();
|
||||
f = message.getLockedbalance();
|
||||
if (f !== 0) {
|
||||
writer.writeUint64(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getLockedbalance();
|
||||
f = message.getReservedofferbalance();
|
||||
if (f !== 0) {
|
||||
writer.writeUint64(
|
||||
3,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getReservedbalance();
|
||||
f = message.getReservedtradebalance();
|
||||
if (f !== 0) {
|
||||
writer.writeUint64(
|
||||
4,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getTotalbalance();
|
||||
if (f !== 0) {
|
||||
writer.writeUint64(
|
||||
5,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional uint64 balance = 1;
|
||||
* optional uint64 unlockedBalance = 1;
|
||||
* @return {number}
|
||||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getBalance = function() {
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getUnlockedbalance = function() {
|
||||
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
|
||||
};
|
||||
|
||||
|
@ -16674,16 +16662,16 @@ proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getBalance = function() {
|
|||
* @param {number} value
|
||||
* @return {!proto.io.bisq.protobuffer.XmrBalanceInfo} returns this
|
||||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.setBalance = function(value) {
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.setUnlockedbalance = function(value) {
|
||||
return jspb.Message.setProto3IntField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional uint64 availableBalance = 2;
|
||||
* optional uint64 lockedBalance = 2;
|
||||
* @return {number}
|
||||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getAvailablebalance = function() {
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getLockedbalance = function() {
|
||||
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
|
||||
};
|
||||
|
||||
|
@ -16692,16 +16680,16 @@ proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getAvailablebalance = functio
|
|||
* @param {number} value
|
||||
* @return {!proto.io.bisq.protobuffer.XmrBalanceInfo} returns this
|
||||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.setAvailablebalance = function(value) {
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.setLockedbalance = function(value) {
|
||||
return jspb.Message.setProto3IntField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional uint64 lockedBalance = 3;
|
||||
* optional uint64 reservedOfferBalance = 3;
|
||||
* @return {number}
|
||||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getLockedbalance = function() {
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getReservedofferbalance = function() {
|
||||
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
|
||||
};
|
||||
|
||||
|
@ -16710,16 +16698,16 @@ proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getLockedbalance = function()
|
|||
* @param {number} value
|
||||
* @return {!proto.io.bisq.protobuffer.XmrBalanceInfo} returns this
|
||||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.setLockedbalance = function(value) {
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.setReservedofferbalance = function(value) {
|
||||
return jspb.Message.setProto3IntField(this, 3, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional uint64 reservedBalance = 4;
|
||||
* optional uint64 reservedTradeBalance = 4;
|
||||
* @return {number}
|
||||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getReservedbalance = function() {
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getReservedtradebalance = function() {
|
||||
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
|
||||
};
|
||||
|
||||
|
@ -16728,29 +16716,11 @@ proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getReservedbalance = function
|
|||
* @param {number} value
|
||||
* @return {!proto.io.bisq.protobuffer.XmrBalanceInfo} returns this
|
||||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.setReservedbalance = function(value) {
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.setReservedtradebalance = function(value) {
|
||||
return jspb.Message.setProto3IntField(this, 4, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional uint64 totalBalance = 5;
|
||||
* @return {number}
|
||||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.getTotalbalance = function() {
|
||||
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
* @return {!proto.io.bisq.protobuffer.XmrBalanceInfo} returns this
|
||||
*/
|
||||
proto.io.bisq.protobuffer.XmrBalanceInfo.prototype.setTotalbalance = function(value) {
|
||||
return jspb.Message.setProto3IntField(this, 5, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
8108
src/pb_pb.js
8108
src/pb_pb.js
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue