mirror of
https://github.com/haveno-dex/haveno-ts.git
synced 2024-12-26 07:49:37 -05:00
Add market depth API call (#47)
This commit is contained in:
parent
0df355faa7
commit
f89ed9d3bb
@ -104,7 +104,19 @@ const TestConfig = {
|
|||||||
["8086", ["10005", "7781"]],
|
["8086", ["10005", "7781"]],
|
||||||
]),
|
]),
|
||||||
devPrivilegePrivKey: "6ac43ea1df2a290c1c8391736aa42e4339c5cb4f110ff0257a13b63211977b7a", // from DEV_PRIVILEGE_PRIV_KEY
|
devPrivilegePrivKey: "6ac43ea1df2a290c1c8391736aa42e4339c5cb4f110ff0257a13b63211977b7a", // from DEV_PRIVILEGE_PRIV_KEY
|
||||||
timeout: 900000 // timeout in ms for all tests to complete (15 minutes)
|
timeout: 900000, // timeout in ms for all tests to complete (15 minutes),
|
||||||
|
postOffer: {
|
||||||
|
direction: "buy", // buy or sell xmr
|
||||||
|
amount: BigInt("200000000000"),
|
||||||
|
counterCurrency: "eth",
|
||||||
|
price: undefined, // use market price if undefined // TODO: converted to long on backend
|
||||||
|
paymentAcountId: undefined,
|
||||||
|
priceMargin: 0.0,
|
||||||
|
minAmount: BigInt("150000000000"), // TODO: disable by default
|
||||||
|
buyerSecurityDeposit: 0.15,
|
||||||
|
awaitUnlockedBalance: false,
|
||||||
|
triggerPrice: undefined // TODO: fails if there is a decimal, converted to long on backend
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
interface TxContext {
|
interface TxContext {
|
||||||
@ -562,6 +574,76 @@ test("Can get market prices", async () => {
|
|||||||
.toThrow('Currency not found: INVALID_CURRENCY');
|
.toThrow('Currency not found: INVALID_CURRENCY');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Can get market depth", async () => {
|
||||||
|
let counterCurrency = "eth";
|
||||||
|
|
||||||
|
// clear offers
|
||||||
|
await clearOffers(alice, counterCurrency);
|
||||||
|
await clearOffers(bob, counterCurrency);
|
||||||
|
async function clearOffers(havenod: HavenoDaemon, counterCurrency: string) {
|
||||||
|
for (let offer of await havenod.getMyOffers()) {
|
||||||
|
if (offer.getBaseCurrencyCode().toLowerCase() === counterCurrency.toLowerCase()) { // TODO (woodser): offer base currency and counter currency are switched
|
||||||
|
await havenod.removeOffer(offer.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// market depth has no data
|
||||||
|
await wait(TestConfig.maxTimePeerNoticeMs);
|
||||||
|
let marketDepth = await alice.getMarketDepth(counterCurrency);
|
||||||
|
expect(marketDepth.getBuyPricesList().length).toEqual(0);
|
||||||
|
expect(marketDepth.getBuyDepthList().length).toEqual(0);
|
||||||
|
expect(marketDepth.getSellPricesList().length).toEqual(0);
|
||||||
|
expect(marketDepth.getSellDepthList().length).toEqual(0);
|
||||||
|
|
||||||
|
// post offers to buy and sell
|
||||||
|
await postOffer(alice, {direction: "buy", amount: BigInt("150000000000"), counterCurrency: counterCurrency, priceMargin: 0.00, awaitUnlockedBalance: true, price: 17.0}); // TODO: offer price is reversed. fix everywhere
|
||||||
|
await postOffer(alice, {direction: "buy", amount: BigInt("150000000000"), counterCurrency: counterCurrency, priceMargin: 0.02, awaitUnlockedBalance: true, price: 17.2});
|
||||||
|
await postOffer(alice, {direction: "buy", amount: BigInt("200000000000"), counterCurrency: counterCurrency, priceMargin: 0.05, awaitUnlockedBalance: true, price: 17.3});
|
||||||
|
await postOffer(alice, {direction: "buy", amount: BigInt("150000000000"), counterCurrency: counterCurrency, priceMargin: 0.02, awaitUnlockedBalance: true, price: 17.3});
|
||||||
|
await postOffer(alice, {direction: "sell", amount: BigInt("300000000000"), counterCurrency: counterCurrency, priceMargin: 0.00, awaitUnlockedBalance: true});
|
||||||
|
await postOffer(alice, {direction: "sell", amount: BigInt("300000000000"), counterCurrency: counterCurrency, priceMargin: 0.02, awaitUnlockedBalance: true});
|
||||||
|
await postOffer(alice, {direction: "sell", amount: BigInt("400000000000"), counterCurrency: counterCurrency, priceMargin: 0.05, awaitUnlockedBalance: true});
|
||||||
|
|
||||||
|
// get bob's market depth
|
||||||
|
await wait(TestConfig.maxTimePeerNoticeMs);
|
||||||
|
marketDepth = await alice.getMarketDepth(counterCurrency);
|
||||||
|
|
||||||
|
// each unique price has a depth
|
||||||
|
expect(marketDepth.getBuyPricesList().length).toEqual(3);
|
||||||
|
expect(marketDepth.getSellPricesList().length).toEqual(3);
|
||||||
|
expect(marketDepth.getBuyPricesList().length).toEqual(marketDepth.getBuyDepthList().length);
|
||||||
|
expect(marketDepth.getSellPricesList().length).toEqual(marketDepth.getSellDepthList().length);
|
||||||
|
|
||||||
|
// test buy prices and depths
|
||||||
|
const priceDivisor = 100000000; // TODO: offer price = price * 100000000
|
||||||
|
let buyOffers = (await alice.getOffers("buy")).concat(await alice.getMyOffers("buy")).sort(function(a, b) { return a.getPrice() - b.getPrice() });
|
||||||
|
expect(marketDepth.getBuyPricesList()[0]).toEqual(1 / (buyOffers[0].getPrice() / priceDivisor)); // TODO: price when posting offer is reversed. this assumes crypto counter currency
|
||||||
|
expect(marketDepth.getBuyPricesList()[1]).toEqual(1 / (buyOffers[1].getPrice() / priceDivisor));
|
||||||
|
expect(marketDepth.getBuyPricesList()[2]).toEqual(1 / (buyOffers[2].getPrice() / priceDivisor));
|
||||||
|
expect(marketDepth.getBuyDepthList()[0]).toEqual(0.15);
|
||||||
|
expect(marketDepth.getBuyDepthList()[1]).toEqual(0.30);
|
||||||
|
expect(marketDepth.getBuyDepthList()[2]).toEqual(0.65);
|
||||||
|
|
||||||
|
// test sell prices and depths
|
||||||
|
let sellOffers = (await alice.getOffers("sell")).concat(await alice.getMyOffers("sell")).sort(function(a, b) { return b.getPrice() - a.getPrice() });
|
||||||
|
expect(marketDepth.getSellPricesList()[0]).toEqual(1 / (sellOffers[0].getPrice() / priceDivisor));
|
||||||
|
expect(marketDepth.getSellPricesList()[1]).toEqual(1 / (sellOffers[1].getPrice() / priceDivisor));
|
||||||
|
expect(marketDepth.getSellPricesList()[2]).toEqual(1 / (sellOffers[2].getPrice() / priceDivisor));
|
||||||
|
expect(marketDepth.getSellDepthList()[0]).toEqual(0.3);
|
||||||
|
expect(marketDepth.getSellDepthList()[1]).toEqual(0.6);
|
||||||
|
expect(marketDepth.getSellDepthList()[2]).toEqual(1);
|
||||||
|
|
||||||
|
// clear offers
|
||||||
|
await clearOffers(alice, counterCurrency);
|
||||||
|
await clearOffers(bob, counterCurrency);
|
||||||
|
|
||||||
|
// test invalid currency
|
||||||
|
await expect(async () => {await alice.getMarketDepth("INVALID_CURRENCY")})
|
||||||
|
.rejects
|
||||||
|
.toThrow('Currency not found: INVALID_CURRENCY');
|
||||||
|
});
|
||||||
|
|
||||||
test("Can register as dispute agents", async () => {
|
test("Can register as dispute agents", async () => {
|
||||||
await arbitrator.registerDisputeAgent("mediator", TestConfig.devPrivilegePrivKey); // TODO: bisq mediator = haveno arbitrator
|
await arbitrator.registerDisputeAgent("mediator", TestConfig.devPrivilegePrivKey); // TODO: bisq mediator = haveno arbitrator
|
||||||
await arbitrator.registerDisputeAgent("refundagent", TestConfig.devPrivilegePrivKey); // TODO: no refund agent in haveno
|
await arbitrator.registerDisputeAgent("refundagent", TestConfig.devPrivilegePrivKey); // TODO: no refund agent in haveno
|
||||||
@ -657,7 +739,7 @@ test("Can post and remove an offer", async () => {
|
|||||||
let unlockedBalanceBefore: bigint = BigInt((await alice.getBalances()).getUnlockedBalance());
|
let unlockedBalanceBefore: bigint = BigInt((await alice.getBalances()).getUnlockedBalance());
|
||||||
|
|
||||||
// post offer
|
// post offer
|
||||||
let offer: OfferInfo = await postOffer(alice, "buy", BigInt("200000000000"), undefined);
|
let offer: OfferInfo = await postOffer(alice);
|
||||||
assert.equal(offer.getState(), "AVAILABLE");
|
assert.equal(offer.getState(), "AVAILABLE");
|
||||||
|
|
||||||
// has offer
|
// has offer
|
||||||
@ -688,7 +770,7 @@ test("Invalidates offers when reserved funds are spent", async () => {
|
|||||||
|
|
||||||
// post offer
|
// post offer
|
||||||
await wait(1000);
|
await wait(1000);
|
||||||
let offer: OfferInfo = await postOffer(alice, "buy", tradeAmount, undefined);
|
let offer: OfferInfo = await postOffer(alice, {amount: tradeAmount});
|
||||||
|
|
||||||
// get key images reserved by offer
|
// get key images reserved by offer
|
||||||
let reservedKeyImages = [];
|
let reservedKeyImages = [];
|
||||||
@ -749,7 +831,7 @@ test("Handles unexpected errors during trade initialization", async () => {
|
|||||||
|
|
||||||
// trader 0 posts offer
|
// trader 0 posts offer
|
||||||
console.log("Posting offer");
|
console.log("Posting offer");
|
||||||
let offer = await postOffer(traders[0], "buy", tradeAmount, undefined);
|
let offer = await postOffer(traders[0], {amount: tradeAmount});
|
||||||
offer = await traders[0].getMyOffer(offer.getId());
|
offer = await traders[0].getMyOffer(offer.getId());
|
||||||
assert.equal(offer.getState(), "AVAILABLE");
|
assert.equal(offer.getState(), "AVAILABLE");
|
||||||
|
|
||||||
@ -841,7 +923,7 @@ test("Cannot make or take offer with insufficient unlocked funds", async () => {
|
|||||||
|
|
||||||
// charlie cannot make offer with insufficient funds
|
// charlie cannot make offer with insufficient funds
|
||||||
try {
|
try {
|
||||||
await postOffer(charlie, "buy", BigInt("200000000000"), paymentAccount.getId());
|
await postOffer(charlie, {paymentAccountId: paymentAccount.getId()});
|
||||||
throw new Error("Should have failed making offer with insufficient funds")
|
throw new Error("Should have failed making offer with insufficient funds")
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
let errTyped = err as grpcWeb.RpcError;
|
let errTyped = err as grpcWeb.RpcError;
|
||||||
@ -856,7 +938,7 @@ test("Cannot make or take offer with insufficient unlocked funds", async () => {
|
|||||||
else {
|
else {
|
||||||
let tradeAmount: bigint = BigInt("250000000000");
|
let tradeAmount: bigint = BigInt("250000000000");
|
||||||
await waitForUnlockedBalance(tradeAmount * BigInt("2"), alice);
|
await waitForUnlockedBalance(tradeAmount * BigInt("2"), alice);
|
||||||
offer = await postOffer(alice, "buy", tradeAmount, undefined);
|
offer = await postOffer(alice, {amount: tradeAmount});
|
||||||
assert.equal(offer.getState(), "AVAILABLE");
|
assert.equal(offer.getState(), "AVAILABLE");
|
||||||
await wait(TestConfig.walletSyncPeriodMs * 2);
|
await wait(TestConfig.walletSyncPeriodMs * 2);
|
||||||
}
|
}
|
||||||
@ -907,7 +989,7 @@ test("Can complete a trade", async () => {
|
|||||||
// alice posts offer to buy xmr
|
// alice posts offer to buy xmr
|
||||||
console.log("Alice posting offer");
|
console.log("Alice posting offer");
|
||||||
let direction = "buy";
|
let direction = "buy";
|
||||||
let offer: OfferInfo = await postOffer(alice, direction, tradeAmount, undefined);
|
let offer: OfferInfo = await postOffer(alice, {direction: direction, amount: tradeAmount});
|
||||||
expect(offer.getState()).toEqual("AVAILABLE");
|
expect(offer.getState()).toEqual("AVAILABLE");
|
||||||
console.log("Alice done posting offer");
|
console.log("Alice done posting offer");
|
||||||
|
|
||||||
@ -1073,7 +1155,7 @@ async function initHavenoDaemon(config?: any): Promise<HavenoDaemon> {
|
|||||||
return havenod;
|
return havenod;
|
||||||
|
|
||||||
async function getAvailablePort(): Promise<number> {
|
async function getAvailablePort(): Promise<number> {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve) {
|
||||||
let srv = net.createServer();
|
let srv = net.createServer();
|
||||||
srv.listen(0, function() {
|
srv.listen(0, function() {
|
||||||
let port = srv.address().port;
|
let port = srv.address().port;
|
||||||
@ -1204,7 +1286,7 @@ async function waitForUnlockedBalance(amount: bigint, ...wallets: any[]) {
|
|||||||
await startMining();
|
await startMining();
|
||||||
let promises: Promise<void>[] = [];
|
let promises: Promise<void>[] = [];
|
||||||
for (let wallet of wallets) {
|
for (let wallet of wallets) {
|
||||||
promises.push(new Promise(async function(resolve, reject) {
|
promises.push(new Promise(async function(resolve) {
|
||||||
let taskLooper: any = new TaskLooper(async function() {
|
let taskLooper: any = new TaskLooper(async function() {
|
||||||
if (await wallet.getUnlockedBalance() >= amount) {
|
if (await wallet.getUnlockedBalance() >= amount) {
|
||||||
taskLooper.stop();
|
taskLooper.stop();
|
||||||
@ -1224,7 +1306,7 @@ async function waitForUnlockedTxs(...txHashes: string[]) {
|
|||||||
let promises: Promise<void>[] = []
|
let promises: Promise<void>[] = []
|
||||||
for (let txHash of txHashes) {
|
for (let txHash of txHashes) {
|
||||||
promises.push(new Promise(async function(resolve, reject) {
|
promises.push(new Promise(async function(resolve, reject) {
|
||||||
let taskLooper: any = new TaskLooper(async function() {
|
let taskLooper = new TaskLooper(async function() {
|
||||||
let tx = await monerod.getTx(txHash);
|
let tx = await monerod.getTx(txHash);
|
||||||
if (tx.isConfirmed() && tx.getBlock().getHeight() <= await monerod.getHeight() - 10) {
|
if (tx.isConfirmed() && tx.getBlock().getHeight() <= await monerod.getHeight() - 10) {
|
||||||
taskLooper.stop();
|
taskLooper.stop();
|
||||||
@ -1286,10 +1368,10 @@ function testTx(tx: XmrTx, ctx: TxContext) {
|
|||||||
assert(tx.getOutgoingTransfer() || tx.getIncomingTransfersList().length); // TODO (woodser): test transfers
|
assert(tx.getOutgoingTransfer() || tx.getIncomingTransfersList().length); // TODO (woodser): test transfers
|
||||||
for (let incomingTransfer of tx.getIncomingTransfersList()) testTransfer(incomingTransfer, ctx);
|
for (let incomingTransfer of tx.getIncomingTransfersList()) testTransfer(incomingTransfer, ctx);
|
||||||
if (tx.getOutgoingTransfer()) testTransfer(tx.getOutgoingTransfer()!, ctx);
|
if (tx.getOutgoingTransfer()) testTransfer(tx.getOutgoingTransfer()!, ctx);
|
||||||
if (ctx.isCreatedTx) testCreatedTx(tx, ctx);
|
if (ctx.isCreatedTx) testCreatedTx(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testCreatedTx(tx: XmrTx, ctx: TxContext) {
|
function testCreatedTx(tx: XmrTx) {
|
||||||
assert.equal(tx.getTimestamp(), 0);
|
assert.equal(tx.getTimestamp(), 0);
|
||||||
assert.equal(tx.getIsConfirmed(), false);
|
assert.equal(tx.getIsConfirmed(), false);
|
||||||
assert.equal(tx.getIsLocked(), true);
|
assert.equal(tx.getIsLocked(), true);
|
||||||
@ -1299,11 +1381,11 @@ function testCreatedTx(tx: XmrTx, ctx: TxContext) {
|
|||||||
function testTransfer(transfer: XmrIncomingTransfer | XmrOutgoingTransfer, ctx: TxContext) {
|
function testTransfer(transfer: XmrIncomingTransfer | XmrOutgoingTransfer, ctx: TxContext) {
|
||||||
expect(BigInt(transfer.getAmount())).toBeGreaterThanOrEqual(BigInt("0"));
|
expect(BigInt(transfer.getAmount())).toBeGreaterThanOrEqual(BigInt("0"));
|
||||||
assert(transfer.getAccountIndex() >= 0);
|
assert(transfer.getAccountIndex() >= 0);
|
||||||
if (transfer instanceof XmrIncomingTransfer) testIncomingTransfer(transfer, ctx);
|
if (transfer instanceof XmrIncomingTransfer) testIncomingTransfer(transfer);
|
||||||
else testOutgoingTransfer(transfer, ctx);
|
else testOutgoingTransfer(transfer, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
function testIncomingTransfer(transfer: XmrIncomingTransfer, ctx: TxContext) {
|
function testIncomingTransfer(transfer: XmrIncomingTransfer) {
|
||||||
assert(transfer.getAddress());
|
assert(transfer.getAddress());
|
||||||
assert(transfer.getSubaddressIndex() >= 0);
|
assert(transfer.getSubaddressIndex() >= 0);
|
||||||
assert(transfer.getNumSuggestedConfirmations() > 0);
|
assert(transfer.getNumSuggestedConfirmations() > 0);
|
||||||
@ -1330,34 +1412,45 @@ function testDestination(destination: XmrDestination) {
|
|||||||
expect(BigInt(destination.getAmount())).toBeGreaterThan(BigInt("0"));
|
expect(BigInt(destination.getAmount())).toBeGreaterThan(BigInt("0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createCryptoPaymentAccount(trader: HavenoDaemon): Promise<PaymentAccount> {
|
async function createCryptoPaymentAccount(trader: HavenoDaemon, currencyCode = "eth"): Promise<PaymentAccount> {
|
||||||
let testAccount = TestConfig.cryptoAccounts[0];
|
for (let cryptoAccount of TestConfig.cryptoAccounts) {
|
||||||
let paymentAccount: PaymentAccount = await trader.createCryptoPaymentAccount(
|
if (cryptoAccount.currencyCode.toLowerCase() !== currencyCode.toLowerCase()) continue;
|
||||||
testAccount.currencyCode + " " + testAccount.address.substr(0, 8) + "... " + GenUtils.getUUID(),
|
return trader.createCryptoPaymentAccount(
|
||||||
testAccount.currencyCode,
|
cryptoAccount.currencyCode + " " + cryptoAccount.address.substr(0, 8) + "... " + GenUtils.getUUID(),
|
||||||
testAccount.address);
|
cryptoAccount.currencyCode,
|
||||||
return paymentAccount;
|
cryptoAccount.address);
|
||||||
|
}
|
||||||
|
throw new Error("No test config for crypto: " + currencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function postOffer(maker: HavenoDaemon, direction: string, amount: bigint, paymentAccountId: string|undefined) {
|
// TODO: specify counter currency code
|
||||||
|
async function postOffer(maker: HavenoDaemon, config?: any) {
|
||||||
|
|
||||||
|
// assign default options
|
||||||
|
config = Object.assign({}, TestConfig.postOffer, config);
|
||||||
|
|
||||||
|
// wait for unlocked balance
|
||||||
|
if (config.awaitUnlockedBalance) await waitForUnlockedBalance(config.amount * BigInt("2"), maker);
|
||||||
|
|
||||||
// create payment account if not given
|
// create payment account if not given
|
||||||
if (!paymentAccountId) paymentAccountId = (await createCryptoPaymentAccount(maker)).getId();
|
if (!config.paymentAccountId) config.paymentAccountId = (await createCryptoPaymentAccount(maker, config.counterCurrency)).getId();
|
||||||
|
|
||||||
// get unlocked balance before reserving offer
|
// get unlocked balance before reserving offer
|
||||||
let unlockedBalanceBefore: bigint = BigInt((await maker.getBalances()).getUnlockedBalance());
|
let unlockedBalanceBefore: bigint = BigInt((await maker.getBalances()).getUnlockedBalance());
|
||||||
|
|
||||||
// post offer
|
// post offer
|
||||||
let offer: OfferInfo = await maker.postOffer("eth",
|
// TODO: re-arrange post offer parameters like this postOffer() or use config interface?
|
||||||
direction, // buy or sell xmr for eth
|
let offer: OfferInfo = await maker.postOffer(
|
||||||
12.378981, // price TODO: price is optional? price string gets converted to long?
|
config.counterCurrency,
|
||||||
true, // use market price
|
config.direction,
|
||||||
0.02, // market price margin, e.g. within 2%
|
config.price,
|
||||||
amount, // amount
|
config.price ? false : true, // TODO: redundant with price field?
|
||||||
BigInt("150000000000"), // min amount
|
config.priceMargin,
|
||||||
0.15, // buyer security deposit, e.g. 15%
|
config.amount,
|
||||||
paymentAccountId, // payment account id
|
config.minAmount,
|
||||||
undefined); // trigger price // TODO: fails if there is a decimal, gets converted to long?
|
config.buyerSecurityDeposit,
|
||||||
|
config.paymentAccountId,
|
||||||
|
config.triggerPrice);
|
||||||
testOffer(offer);
|
testOffer(offer);
|
||||||
|
|
||||||
// unlocked balance has decreased
|
// unlocked balance has decreased
|
||||||
@ -1365,12 +1458,12 @@ async function postOffer(maker: HavenoDaemon, direction: string, amount: bigint,
|
|||||||
if (unlockedBalanceAfter === unlockedBalanceBefore) throw new Error("unlocked balance did not change after posting offer");
|
if (unlockedBalanceAfter === unlockedBalanceBefore) throw new Error("unlocked balance did not change after posting offer");
|
||||||
|
|
||||||
// offer is included in my offers only
|
// offer is included in my offers only
|
||||||
if (!getOffer(await maker.getMyOffers(direction), offer.getId())) {
|
if (!getOffer(await maker.getMyOffers(config.amountdirection), offer.getId())) {
|
||||||
await wait(10000);
|
await wait(10000);
|
||||||
if (!getOffer(await maker.getMyOffers(direction), offer.getId())) throw new Error("Offer " + offer.getId() + " was not found in my offers");
|
if (!getOffer(await maker.getMyOffers(config.amountdirection), offer.getId())) throw new Error("Offer " + offer.getId() + " was not found in my offers");
|
||||||
else console.log("The offer finally posted!");
|
else console.log("The offer finally posted!");
|
||||||
}
|
}
|
||||||
if (getOffer(await maker.getOffers(direction), offer.getId())) throw new Error("My offer " + offer.getId() + " should not appear in available offers");
|
if (getOffer(await maker.getOffers(config.amountdirection), offer.getId())) throw new Error("My offer " + offer.getId() + " should not appear in available offers");
|
||||||
|
|
||||||
return offer;
|
return offer;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import {HavenoUtils} from "./utils/HavenoUtils";
|
|||||||
import {TaskLooper} from "./utils/TaskLooper";
|
import {TaskLooper} from "./utils/TaskLooper";
|
||||||
import * as grpcWeb from 'grpc-web';
|
import * as grpcWeb from 'grpc-web';
|
||||||
import {GetVersionClient, AccountClient, MoneroConnectionsClient, DisputeAgentsClient, NotificationsClient, WalletsClient, PriceClient, OffersClient, PaymentAccountsClient, TradesClient, ShutdownServerClient} from './protobuf/GrpcServiceClientPb';
|
import {GetVersionClient, AccountClient, MoneroConnectionsClient, DisputeAgentsClient, NotificationsClient, WalletsClient, PriceClient, OffersClient, PaymentAccountsClient, TradesClient, ShutdownServerClient} from './protobuf/GrpcServiceClientPb';
|
||||||
import {GetVersionRequest, GetVersionReply, IsAppInitializedRequest, IsAppInitializedReply, RegisterDisputeAgentRequest, MarketPriceRequest, MarketPriceReply, MarketPricesRequest, MarketPricesReply, MarketPriceInfo, GetBalancesRequest, GetBalancesReply, XmrBalanceInfo, GetOffersRequest, GetOffersReply, OfferInfo, GetPaymentAccountsRequest, GetPaymentAccountsReply, CreateCryptoCurrencyPaymentAccountRequest, CreateCryptoCurrencyPaymentAccountReply, CreateOfferRequest, CreateOfferReply, CancelOfferRequest, TakeOfferRequest, TakeOfferReply, TradeInfo, GetTradeRequest, GetTradeReply, GetTradesRequest, GetTradesReply, GetNewDepositSubaddressRequest, GetNewDepositSubaddressReply, ConfirmPaymentStartedRequest, ConfirmPaymentReceivedRequest, XmrTx, GetXmrTxsRequest, GetXmrTxsReply, XmrDestination, CreateXmrTxRequest, CreateXmrTxReply, RelayXmrTxRequest, RelayXmrTxReply, CreateAccountRequest, AccountExistsRequest, AccountExistsReply, DeleteAccountRequest, OpenAccountRequest, IsAccountOpenRequest, IsAccountOpenReply, CloseAccountRequest, ChangePasswordRequest, BackupAccountRequest, BackupAccountReply, RestoreAccountRequest, StopRequest, NotificationMessage, RegisterNotificationListenerRequest, SendNotificationRequest, UrlConnection, AddConnectionRequest, RemoveConnectionRequest, GetConnectionRequest, GetConnectionsRequest, SetConnectionRequest, CheckConnectionRequest, CheckConnectionsReply, CheckConnectionsRequest, StartCheckingConnectionsRequest, StopCheckingConnectionsRequest, GetBestAvailableConnectionRequest, SetAutoSwitchRequest, CheckConnectionReply, GetConnectionsReply, GetConnectionReply, GetBestAvailableConnectionReply} from './protobuf/grpc_pb';
|
import {GetVersionRequest, GetVersionReply, IsAppInitializedRequest, IsAppInitializedReply, RegisterDisputeAgentRequest, MarketPriceRequest, MarketPriceReply, MarketPricesRequest, MarketPricesReply, MarketPriceInfo, MarketDepthRequest, MarketDepthReply, MarketDepthInfo, GetBalancesRequest, GetBalancesReply, XmrBalanceInfo, GetOffersRequest, GetOffersReply, OfferInfo, GetPaymentAccountsRequest, GetPaymentAccountsReply, CreateCryptoCurrencyPaymentAccountRequest, CreateCryptoCurrencyPaymentAccountReply, CreateOfferRequest, CreateOfferReply, CancelOfferRequest, TakeOfferRequest, TakeOfferReply, TradeInfo, GetTradeRequest, GetTradeReply, GetTradesRequest, GetTradesReply, GetNewDepositSubaddressRequest, GetNewDepositSubaddressReply, ConfirmPaymentStartedRequest, ConfirmPaymentReceivedRequest, XmrTx, GetXmrTxsRequest, GetXmrTxsReply, XmrDestination, CreateXmrTxRequest, CreateXmrTxReply, RelayXmrTxRequest, RelayXmrTxReply, CreateAccountRequest, AccountExistsRequest, AccountExistsReply, DeleteAccountRequest, OpenAccountRequest, IsAccountOpenRequest, IsAccountOpenReply, CloseAccountRequest, ChangePasswordRequest, BackupAccountRequest, BackupAccountReply, RestoreAccountRequest, StopRequest, NotificationMessage, RegisterNotificationListenerRequest, SendNotificationRequest, UrlConnection, AddConnectionRequest, RemoveConnectionRequest, GetConnectionRequest, GetConnectionsRequest, SetConnectionRequest, CheckConnectionRequest, CheckConnectionsReply, CheckConnectionsRequest, StartCheckingConnectionsRequest, StopCheckingConnectionsRequest, GetBestAvailableConnectionRequest, SetAutoSwitchRequest, CheckConnectionReply, GetConnectionsReply, GetConnectionReply, GetBestAvailableConnectionReply} from './protobuf/grpc_pb';
|
||||||
import {PaymentAccount, AvailabilityResult} from './protobuf/pb_pb';
|
import {PaymentAccount, AvailabilityResult} from './protobuf/pb_pb';
|
||||||
const console = require('console');
|
const console = require('console');
|
||||||
|
|
||||||
@ -716,7 +716,7 @@ class HavenoDaemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current market prices of all the currencies.
|
* Get the current market prices of all currencies.
|
||||||
*
|
*
|
||||||
* @return {MarketPrice[]} price per 1 XMR in all supported currencies (fiat & crypto)
|
* @return {MarketPrice[]} price per 1 XMR in all supported currencies (fiat & crypto)
|
||||||
*/
|
*/
|
||||||
@ -730,6 +730,21 @@ class HavenoDaemon {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the market depth of a currency.
|
||||||
|
*
|
||||||
|
* @return {MarketDepthInfo} market depth of the given currency
|
||||||
|
*/
|
||||||
|
async getMarketDepth(currencyCode: string): Promise<MarketDepthInfo> {
|
||||||
|
let that = this;
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
that._priceClient.getMarketDepth(new MarketDepthRequest().setCurrencyCode(currencyCode), {password: that._password}, function(err: grpcWeb.RpcError, response: MarketDepthReply) {
|
||||||
|
if (err) reject(err);
|
||||||
|
else resolve(response.getMarketDepth());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get payment accounts.
|
* Get payment accounts.
|
||||||
*
|
*
|
||||||
@ -773,10 +788,11 @@ class HavenoDaemon {
|
|||||||
/**
|
/**
|
||||||
* Get available offers to buy or sell XMR.
|
* Get available offers to buy or sell XMR.
|
||||||
*
|
*
|
||||||
* @param {string} direction - one of "BUY" or "SELL" // TODO (woodser): make optional
|
* @param {string|undefined} direction - "buy" or "sell" (default all)
|
||||||
* @return {OfferInfo[]} available offers
|
* @return {OfferInfo[]} the available offers
|
||||||
*/
|
*/
|
||||||
async getOffers(direction: string): Promise<OfferInfo[]> {
|
async getOffers(direction?: string): Promise<OfferInfo[]> {
|
||||||
|
if (!direction) return (await this.getOffers("buy")).concat(await this.getOffers("sell")); // TODO: implement in backend
|
||||||
let that = this;
|
let that = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
that._offersClient.getOffers(new GetOffersRequest().setDirection(direction).setCurrencyCode("XMR"), {password: that._password}, function(err: grpcWeb.RpcError, response: GetOffersReply) {
|
that._offersClient.getOffers(new GetOffersRequest().setDirection(direction).setCurrencyCode("XMR"), {password: that._password}, function(err: grpcWeb.RpcError, response: GetOffersReply) {
|
||||||
@ -787,12 +803,13 @@ class HavenoDaemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get user's created offers to buy or sell XMR.
|
* Get the user's posted offers to buy or sell XMR.
|
||||||
*
|
*
|
||||||
* @param {string} direction - one of "BUY" or "SELL" // TODO (woodser): make optional
|
* @param {string|undefined} direction - "buy" or "sell" (default all)
|
||||||
* @return {OfferInfo[]} the user's created offers
|
* @return {OfferInfo[]} the user's created offers
|
||||||
*/
|
*/
|
||||||
async getMyOffers(direction: string): Promise<OfferInfo[]> {
|
async getMyOffers(direction?: string): Promise<OfferInfo[]> {
|
||||||
|
if (!direction) return (await this.getMyOffers("buy")).concat(await this.getMyOffers("sell")); // TODO: implement in backend
|
||||||
let that = this;
|
let that = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
that._offersClient.getMyOffers(new GetOffersRequest().setDirection(direction).setCurrencyCode("XMR"), {password: that._password}, function(err: grpcWeb.RpcError, response: GetOffersReply) {
|
that._offersClient.getMyOffers(new GetOffersRequest().setDirection(direction).setCurrencyCode("XMR"), {password: that._password}, function(err: grpcWeb.RpcError, response: GetOffersReply) {
|
||||||
@ -823,7 +840,7 @@ class HavenoDaemon {
|
|||||||
* @param {string} currencyCode - currency code of traded pair
|
* @param {string} currencyCode - currency code of traded pair
|
||||||
* @param {string} direction - one of "BUY" or "SELL"
|
* @param {string} direction - one of "BUY" or "SELL"
|
||||||
* @param {number} price - trade price
|
* @param {number} price - trade price
|
||||||
* @param {bool} useMarketBasedPrice - base trade on market price
|
* @param {bool} useMarketBasedPrice - base trade on market price // TODO: this field redundant with price
|
||||||
* @param {number} marketPriceMargin - % from market price to tolerate
|
* @param {number} marketPriceMargin - % from market price to tolerate
|
||||||
* @param {bigint} amount - amount to trade
|
* @param {bigint} amount - amount to trade
|
||||||
* @param {bigint} minAmount - minimum amount to trade
|
* @param {bigint} minAmount - minimum amount to trade
|
||||||
@ -846,8 +863,8 @@ class HavenoDaemon {
|
|||||||
let request = new CreateOfferRequest()
|
let request = new CreateOfferRequest()
|
||||||
.setCurrencyCode(currencyCode)
|
.setCurrencyCode(currencyCode)
|
||||||
.setDirection(direction)
|
.setDirection(direction)
|
||||||
.setPrice(price.toString())
|
|
||||||
.setUseMarketBasedPrice(useMarketBasedPrice)
|
.setUseMarketBasedPrice(useMarketBasedPrice)
|
||||||
|
.setPrice(useMarketBasedPrice ? "1.0" : price.toString()) // TODO: positive price required even if using market price
|
||||||
.setMarketPriceMargin(marketPriceMargin)
|
.setMarketPriceMargin(marketPriceMargin)
|
||||||
.setAmount(amount.toString())
|
.setAmount(amount.toString())
|
||||||
.setMinAmount(minAmount.toString())
|
.setMinAmount(minAmount.toString())
|
||||||
|
Loading…
Reference in New Issue
Block a user