mirror of
https://github.com/haveno-dex/haveno-ts.git
synced 2024-10-01 01:35:42 -04:00
test completed payout state
This commit is contained in:
parent
a382b18a6d
commit
796f14c9ef
@ -54,7 +54,7 @@ const TestConfig = {
|
|||||||
testDataDir: "./testdata",
|
testDataDir: "./testdata",
|
||||||
haveno: {
|
haveno: {
|
||||||
path: "../haveno",
|
path: "../haveno",
|
||||||
version: "0.0.2"
|
version: "1.0.0"
|
||||||
},
|
},
|
||||||
monerod: {
|
monerod: {
|
||||||
url: "http://localhost:" + getNetworkStartPort() + "8081", // 18081, 28081, 38081 for mainnet, testnet, stagenet respectively
|
url: "http://localhost:" + getNetworkStartPort() + "8081", // 18081, 28081, 38081 for mainnet, testnet, stagenet respectively
|
||||||
@ -170,7 +170,7 @@ const TestConfig = {
|
|||||||
buyerSendsPayment: true,
|
buyerSendsPayment: true,
|
||||||
sellerReceivesPayment: true,
|
sellerReceivesPayment: true,
|
||||||
arbitrator: {} as HavenoClient, // test arbitrator state (does not choose arbitrator). assigned to default arbitrator before all tests
|
arbitrator: {} as HavenoClient, // test arbitrator state (does not choose arbitrator). assigned to default arbitrator before all tests
|
||||||
resolveDispute: true, // resolve dispute after opening,
|
resolveDispute: true, // resolve dispute after opening
|
||||||
disputeWinner: DisputeResult.Winner.SELLER,
|
disputeWinner: DisputeResult.Winner.SELLER,
|
||||||
disputeReason: DisputeResult.Reason.PEER_WAS_LATE,
|
disputeReason: DisputeResult.Reason.PEER_WAS_LATE,
|
||||||
disputeSummary: "Seller is winner"
|
disputeSummary: "Seller is winner"
|
||||||
@ -214,6 +214,7 @@ interface TradeConfig {
|
|||||||
testTraderChat?: boolean,
|
testTraderChat?: boolean,
|
||||||
buyer?: HavenoClient,
|
buyer?: HavenoClient,
|
||||||
seller?: HavenoClient,
|
seller?: HavenoClient,
|
||||||
|
tradeStarted?: boolean,
|
||||||
|
|
||||||
// resolve dispute config
|
// resolve dispute config
|
||||||
resolveDispute?: boolean
|
resolveDispute?: boolean
|
||||||
@ -1213,11 +1214,11 @@ test("Can schedule offers with locked funds", async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("Can complete a trade", async () => {
|
test("Can complete a trade", async () => {
|
||||||
await executeTrade();
|
await executeTrade();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Can complete trades at the same time", async () => {
|
test("Can complete trades at the same time", async () => {
|
||||||
await executeTrades(getTradeConfigs(6));
|
await executeTrades(getTradeConfigs(6));
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Can go offline while completing a trade", async () => {
|
test("Can go offline while completing a trade", async () => {
|
||||||
@ -1266,47 +1267,42 @@ test("Can resolve disputes", async () => {
|
|||||||
HavenoUtils.log(1, "Opening disputes");
|
HavenoUtils.log(1, "Opening disputes");
|
||||||
const trade2 = await user1.getTrade(tradeIds[2]);
|
const trade2 = await user1.getTrade(tradeIds[2]);
|
||||||
const trade3 = await user1.getTrade(tradeIds[3]);
|
const trade3 = await user1.getTrade(tradeIds[3]);
|
||||||
const disputeConfigs: TradeConfig[] = [{
|
Object.assign(configs[0], {
|
||||||
offerId: tradeIds[0],
|
|
||||||
takeOffer: false,
|
|
||||||
resolveDispute: false,
|
resolveDispute: false,
|
||||||
sellerOpensDisputeAfterDepositsUnlock: true,
|
sellerOpensDisputeAfterDepositsUnlock: true,
|
||||||
disputeWinner: DisputeResult.Winner.SELLER,
|
disputeWinner: DisputeResult.Winner.SELLER,
|
||||||
disputeReason: DisputeResult.Reason.PEER_WAS_LATE,
|
disputeReason: DisputeResult.Reason.PEER_WAS_LATE,
|
||||||
disputeSummary: "Seller is winner"
|
disputeSummary: "Seller is winner"
|
||||||
}, {
|
});
|
||||||
offerId: tradeIds[1],
|
Object.assign(configs[1], {
|
||||||
takeOffer: false,
|
|
||||||
resolveDispute: false,
|
resolveDispute: false,
|
||||||
buyerOpensDisputeAfterDepositsUnlock: true,
|
buyerOpensDisputeAfterDepositsUnlock: true,
|
||||||
disputeWinner: DisputeResult.Winner.BUYER,
|
disputeWinner: DisputeResult.Winner.BUYER,
|
||||||
disputeReason: DisputeResult.Reason.SELLER_NOT_RESPONDING,
|
disputeReason: DisputeResult.Reason.SELLER_NOT_RESPONDING,
|
||||||
disputeSummary: "Buyer is winner"
|
disputeSummary: "Buyer is winner"
|
||||||
}, {
|
});
|
||||||
offerId: tradeIds[2],
|
Object.assign(configs[2], {
|
||||||
takeOffer: false,
|
|
||||||
resolveDispute: false,
|
resolveDispute: false,
|
||||||
sellerOpensDisputeAfterDepositsUnlock: true,
|
sellerOpensDisputeAfterDepositsUnlock: true,
|
||||||
disputeWinner: DisputeResult.Winner.BUYER,
|
disputeWinner: DisputeResult.Winner.BUYER,
|
||||||
disputeReason: DisputeResult.Reason.WRONG_SENDER_ACCOUNT,
|
disputeReason: DisputeResult.Reason.WRONG_SENDER_ACCOUNT,
|
||||||
disputeSummary: "Split trade amount",
|
disputeSummary: "Split trade amount",
|
||||||
disputeWinnerAmount: BigInt(trade2.getAmountAsLong()) / BigInt(2) + HavenoUtils.centinerosToAtomicUnits(trade2.getOffer()!.getBuyerSecurityDeposit())
|
disputeWinnerAmount: BigInt(trade2.getAmountAsLong()) / BigInt(2) + HavenoUtils.centinerosToAtomicUnits(trade2.getOffer()!.getBuyerSecurityDeposit())
|
||||||
}, {
|
});
|
||||||
offerId: tradeIds[3],
|
Object.assign(configs[3], {
|
||||||
takeOffer: false,
|
|
||||||
resolveDispute: false,
|
resolveDispute: false,
|
||||||
buyerOpensDisputeAfterDepositsUnlock: true,
|
buyerOpensDisputeAfterDepositsUnlock: true,
|
||||||
disputeWinner: DisputeResult.Winner.SELLER,
|
disputeWinner: DisputeResult.Winner.SELLER,
|
||||||
disputeReason: DisputeResult.Reason.TRADE_ALREADY_SETTLED,
|
disputeReason: DisputeResult.Reason.TRADE_ALREADY_SETTLED,
|
||||||
disputeSummary: "Seller gets everything",
|
disputeSummary: "Seller gets everything",
|
||||||
disputeWinnerAmount: BigInt(trade3.getAmountAsLong()) + HavenoUtils.centinerosToAtomicUnits(trade3.getOffer()!.getBuyerSecurityDeposit() + trade3.getOffer()!.getSellerSecurityDeposit())
|
disputeWinnerAmount: BigInt(trade3.getAmountAsLong()) + HavenoUtils.centinerosToAtomicUnits(trade3.getOffer()!.getBuyerSecurityDeposit() + trade3.getOffer()!.getSellerSecurityDeposit())
|
||||||
}];
|
});
|
||||||
await executeTrades(disputeConfigs);
|
await executeTrades(configs);
|
||||||
|
|
||||||
// resolve disputes
|
// resolve disputes
|
||||||
HavenoUtils.log(1, "Resolving disputes");
|
HavenoUtils.log(1, "Resolving disputes");
|
||||||
for (const config of disputeConfigs) config.resolveDispute = true;
|
for (const config of configs) config.resolveDispute = true;
|
||||||
await executeTrades(disputeConfigs, false); // resolve in sequence to test balances before and after
|
await executeTrades(configs, false); // resolve in sequence to test balances before and after
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Cannot make or take offer with insufficient unlocked funds", async () => {
|
test("Cannot make or take offer with insufficient unlocked funds", async () => {
|
||||||
@ -1729,8 +1725,12 @@ async function executeTrade(config?: TradeConfig): Promise<string> {
|
|||||||
|
|
||||||
// take offer or get existing trade
|
// take offer or get existing trade
|
||||||
let trade: TradeInfo|undefined = undefined;
|
let trade: TradeInfo|undefined = undefined;
|
||||||
if (config.takeOffer) trade = await takeOffer(config);
|
if (config.tradeStarted) trade = await config.taker!.getTrade(config.offerId!);
|
||||||
else trade = await config.taker!.getTrade(config.offerId!);
|
else {
|
||||||
|
if (!config.takeOffer) return config.offerId!;
|
||||||
|
trade = await takeOffer(config);
|
||||||
|
config.tradeStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
// test trader chat
|
// test trader chat
|
||||||
if (config.testTraderChat) await testTradeChat(trade.getTradeId(), config.maker!, config.taker!);
|
if (config.testTraderChat) await testTradeChat(trade.getTradeId(), config.maker!, config.taker!);
|
||||||
@ -1757,7 +1757,7 @@ async function executeTrade(config?: TradeConfig): Promise<string> {
|
|||||||
await waitForUnlockedTxs(trade.getMakerDepositTxId(), trade.getTakerDepositTxId());
|
await waitForUnlockedTxs(trade.getMakerDepositTxId(), trade.getTakerDepositTxId());
|
||||||
|
|
||||||
// buyer comes online if offline
|
// buyer comes online if offline
|
||||||
if (config.buyerOfflineAfterPaymentSent) {
|
if (config.buyerOfflineAfterTake) {
|
||||||
config.buyer = await initHaveno({appName: buyerAppName});
|
config.buyer = await initHaveno({appName: buyerAppName});
|
||||||
if (isBuyerMaker) config.maker = config.buyer;
|
if (isBuyerMaker) config.maker = config.buyer;
|
||||||
else config.taker = config.buyer;
|
else config.taker = config.buyer;
|
||||||
@ -1824,13 +1824,20 @@ async function executeTrade(config?: TradeConfig): Promise<string> {
|
|||||||
if (config.sellerOfflineAfterTake) await wait(TestConfig.walletSyncPeriodMs); // wait to process mailbox messages
|
if (config.sellerOfflineAfterTake) await wait(TestConfig.walletSyncPeriodMs); // wait to process mailbox messages
|
||||||
fetchedTrade = await config.seller.getTrade(trade.getTradeId());
|
fetchedTrade = await config.seller.getTrade(trade.getTradeId());
|
||||||
expect(fetchedTrade.getPhase()).toEqual("PAYMENT_SENT");
|
expect(fetchedTrade.getPhase()).toEqual("PAYMENT_SENT");
|
||||||
|
expect(fetchedTrade.getPayoutState()).toEqual("UNPUBLISHED");
|
||||||
|
|
||||||
// seller confirms payment is received
|
// seller confirms payment is received
|
||||||
if (!config.sellerReceivesPayment) return offer!.getId();
|
if (!config.sellerReceivesPayment) return offer!.getId();
|
||||||
HavenoUtils.log(1, "Seller confirming payment received");
|
HavenoUtils.log(1, "Seller confirming payment received");
|
||||||
await config.seller.confirmPaymentReceived(trade.getTradeId());
|
await config.seller.confirmPaymentReceived(trade.getTradeId());
|
||||||
fetchedTrade = await config.seller.getTrade(trade.getTradeId());
|
fetchedTrade = await config.seller.getTrade(trade.getTradeId());
|
||||||
expect(fetchedTrade.getPhase()).toEqual(config.sellerOfflineAfterTake ? "PAYMENT_RECEIVED" : "PAYOUT_PUBLISHED"); // payout can only be published if seller remained online after first confirmation to share updated multisig info
|
expect(fetchedTrade.getPhase()).toEqual("PAYMENT_RECEIVED");
|
||||||
|
expect(fetchedTrade.getPayoutState()).toEqual(config.sellerOfflineAfterTake ? "UNPUBLISHED" : "PUBLISHED"); // payout published iff seller remained online after first confirmation to share updated multisig info
|
||||||
|
|
||||||
|
// payout tx is published by buyer (priority) or arbitrator
|
||||||
|
await wait(TestConfig.walletSyncPeriodMs);
|
||||||
|
await testTradeState(await config.seller!.getTrade(trade.getTradeId()), "PAYMENT_RECEIVED", ["PUBLISHED", "CONFIRMED", "UNLOCKED"], false, true);
|
||||||
|
await testTradeState(await config.arbitrator!.getTrade(trade.getTradeId()), "COMPLETED", ["PUBLISHED", "CONFIRMED", "UNLOCKED"], true, true); // arbitrator trade auto completes
|
||||||
|
|
||||||
// buyer comes online if offline
|
// buyer comes online if offline
|
||||||
if (config.buyerOfflineAfterPaymentSent) {
|
if (config.buyerOfflineAfterPaymentSent) {
|
||||||
@ -1838,18 +1845,19 @@ async function executeTrade(config?: TradeConfig): Promise<string> {
|
|||||||
if (isBuyerMaker) config.maker = config.buyer;
|
if (isBuyerMaker) config.maker = config.buyer;
|
||||||
else config.taker = config.buyer;
|
else config.taker = config.buyer;
|
||||||
HavenoUtils.log(1, "Done starting buyer");
|
HavenoUtils.log(1, "Done starting buyer");
|
||||||
|
await wait(TestConfig.maxWalletStartupMs + TestConfig.walletSyncPeriodMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// test notifications
|
// test trade state
|
||||||
await wait(TestConfig.maxWalletStartupMs + TestConfig.walletSyncPeriodMs * 2);
|
await testTradeState(await config.buyer!.getTrade(trade.getTradeId()), "PAYMENT_RECEIVED", ["PUBLISHED", "CONFIRMED", "UNLOCKED"], false, true);
|
||||||
fetchedTrade = await config.buyer!.getTrade(trade.getTradeId());
|
await testTradeState(await config.seller!.getTrade(trade.getTradeId()), "PAYMENT_RECEIVED", ["PUBLISHED", "CONFIRMED", "UNLOCKED"], false, true);
|
||||||
expect(fetchedTrade.getPhase()).toEqual("PAYOUT_PUBLISHED"); // TODO: this should be WITHDRAW_COMPLETED?
|
await testTradeState(await config.arbitrator!.getTrade(trade.getTradeId()), "COMPLETED", ["PUBLISHED", "CONFIRMED", "UNLOCKED"], true, true);
|
||||||
fetchedTrade = await config.seller.getTrade(trade.getTradeId());
|
|
||||||
expect(fetchedTrade.getPhase()).toEqual("PAYOUT_PUBLISHED");
|
|
||||||
const arbitratorTrade = await config.arbitrator!.getTrade(trade.getTradeId());
|
|
||||||
expect(arbitratorTrade.getState()).toEqual("WITHDRAW_COMPLETED");
|
|
||||||
|
|
||||||
// TODO: traders mark trades as complete
|
// test trade completion
|
||||||
|
await config.buyer!.completeTrade(trade.getTradeId());
|
||||||
|
await testTradeState(await config.buyer!.getTrade(trade.getTradeId()), "COMPLETED", ["PUBLISHED", "CONFIRMED", "UNLOCKED"], true, true);
|
||||||
|
await config.seller!.completeTrade(trade.getTradeId());
|
||||||
|
await testTradeState(await config.buyer!.getTrade(trade.getTradeId()), "COMPLETED", ["PUBLISHED", "CONFIRMED", "UNLOCKED"], true, true);
|
||||||
|
|
||||||
// test balances after payout tx unless other trades can interfere
|
// test balances after payout tx unless other trades can interfere
|
||||||
if (!config.concurrentTrades) {
|
if (!config.concurrentTrades) {
|
||||||
@ -1863,10 +1871,44 @@ async function executeTrade(config?: TradeConfig): Promise<string> {
|
|||||||
expect(sellerFee).toBeLessThanOrEqual(TestConfig.maxFee);
|
expect(sellerFee).toBeLessThanOrEqual(TestConfig.maxFee);
|
||||||
expect(sellerFee).toBeGreaterThan(BigInt("0"));
|
expect(sellerFee).toBeGreaterThan(BigInt("0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mine at least one block
|
||||||
|
const height = await monerod.getHeight();
|
||||||
|
await mineToHeight(height + 1);
|
||||||
|
await wait(TestConfig.maxWalletStartupMs + TestConfig.walletSyncPeriodMs * 2);
|
||||||
|
fetchedTrade = await config.buyer!.getTrade(trade.getTradeId());
|
||||||
|
assert(GenUtils.arrayContains(["CONFIRMED", "UNLOCKED"], fetchedTrade.getPayoutState()));
|
||||||
|
fetchedTrade = await config.seller!.getTrade(trade.getTradeId());
|
||||||
|
assert(GenUtils.arrayContains(["CONFIRMED", "UNLOCKED"], fetchedTrade.getPayoutState()));
|
||||||
|
|
||||||
|
// mine until unlock
|
||||||
|
await mineToHeight(height + 10);
|
||||||
|
await wait(TestConfig.walletSyncPeriodMs * 2);
|
||||||
|
fetchedTrade = await config.buyer!.getTrade(trade.getTradeId());
|
||||||
|
assert(GenUtils.arrayContains(["UNLOCKED"], fetchedTrade.getPayoutState()));
|
||||||
|
fetchedTrade = await config.seller!.getTrade(trade.getTradeId());
|
||||||
|
assert(GenUtils.arrayContains(["UNLOCKED"], fetchedTrade.getPayoutState()));
|
||||||
|
|
||||||
return offer!.getId();
|
return offer!.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function mineToHeight(height: number) {
|
||||||
|
if (await monerod.getHeight() >= height) return;
|
||||||
|
const miningStarted = await startMining();
|
||||||
|
while (await monerod.getHeight() < height) {
|
||||||
|
await GenUtils.waitFor(TestConfig.walletSyncPeriodMs);
|
||||||
|
}
|
||||||
|
if (miningStarted) await stopMining();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testTradeState(trade: TradeInfo, phase: string, payoutStates: string[], isCompleted: boolean, isPayoutPublished: boolean) {
|
||||||
|
expect(trade.getPhase()).toEqual(phase);
|
||||||
|
assert(GenUtils.arrayContains(payoutStates, trade.getPayoutState()));
|
||||||
|
expect(trade.getIsCompleted()).toEqual(isCompleted);
|
||||||
|
expect(trade.getIsPayoutPublished()).toEqual(isPayoutPublished);
|
||||||
|
//expect(trade.getIsPayoutConfirmed()).toEqual(isPayoutPublished); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
async function makeOffer(config?: TradeConfig): Promise<OfferInfo> {
|
async function makeOffer(config?: TradeConfig): Promise<OfferInfo> {
|
||||||
|
|
||||||
// assign default config
|
// assign default config
|
||||||
@ -2104,6 +2146,12 @@ async function resolveDispute(config: TradeConfig) {
|
|||||||
dispute = await config.disputePeer!.getDispute(config.offerId!);
|
dispute = await config.disputePeer!.getDispute(config.offerId!);
|
||||||
expect(dispute.getIsClosed()).toBe(true);
|
expect(dispute.getIsClosed()).toBe(true);
|
||||||
|
|
||||||
|
// test trade state
|
||||||
|
await wait(TestConfig.maxWalletStartupMs + TestConfig.walletSyncPeriodMs * 2);
|
||||||
|
expect((await config.buyer!.getTrade(config.offerId!)).getPhase()).toEqual("COMPLETED");
|
||||||
|
expect((await config.seller!.getTrade(config.offerId!)).getPhase()).toEqual("COMPLETED");
|
||||||
|
expect((await config.arbitrator!.getTrade(config.offerId!)).getPhase()).toEqual("COMPLETED");
|
||||||
|
|
||||||
// check balances after payout tx unless concurrent trades
|
// check balances after payout tx unless concurrent trades
|
||||||
if (config.concurrentTrades) return;
|
if (config.concurrentTrades) return;
|
||||||
await wait(TestConfig.walletSyncPeriodMs * 2);
|
await wait(TestConfig.walletSyncPeriodMs * 2);
|
||||||
|
@ -4,7 +4,7 @@ import HavenoUtils from "./utils/HavenoUtils";
|
|||||||
import TaskLooper from "./utils/TaskLooper";
|
import TaskLooper from "./utils/TaskLooper";
|
||||||
import type * as grpcWeb from "grpc-web";
|
import type * as grpcWeb from "grpc-web";
|
||||||
import { GetVersionClient, AccountClient, MoneroConnectionsClient, DisputesClient, DisputeAgentsClient, NotificationsClient, WalletsClient, PriceClient, OffersClient, PaymentAccountsClient, TradesClient, ShutdownServerClient, MoneroNodeClient } from './protobuf/GrpcServiceClientPb';
|
import { GetVersionClient, AccountClient, MoneroConnectionsClient, DisputesClient, DisputeAgentsClient, NotificationsClient, WalletsClient, PriceClient, OffersClient, PaymentAccountsClient, TradesClient, ShutdownServerClient, MoneroNodeClient } from './protobuf/GrpcServiceClientPb';
|
||||||
import { GetVersionRequest, GetVersionReply, IsAppInitializedRequest, IsAppInitializedReply, RegisterDisputeAgentRequest, UnregisterDisputeAgentRequest, MarketPriceRequest, MarketPriceReply, MarketPricesRequest, MarketPricesReply, MarketPriceInfo, MarketDepthRequest, MarketDepthReply, MarketDepthInfo, GetBalancesRequest, GetBalancesReply, XmrBalanceInfo, GetMyOfferRequest, GetMyOfferReply, GetOffersRequest, GetOffersReply, OfferInfo, GetPaymentMethodsRequest, GetPaymentMethodsReply, GetPaymentAccountFormRequest, CreatePaymentAccountRequest, ValidateFormFieldRequest, CreatePaymentAccountReply, GetPaymentAccountFormReply, GetPaymentAccountsRequest, GetPaymentAccountsReply, CreateCryptoCurrencyPaymentAccountRequest, CreateCryptoCurrencyPaymentAccountReply, CreateOfferRequest, CreateOfferReply, CancelOfferRequest, TakeOfferRequest, TakeOfferReply, TradeInfo, GetTradeRequest, GetTradeReply, GetTradesRequest, GetTradesReply, GetXmrSeedRequest, GetXmrSeedReply, GetXmrPrimaryAddressRequest, GetXmrPrimaryAddressReply, GetXmrNewSubaddressRequest, GetXmrNewSubaddressReply, 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, GetDisputeRequest, GetDisputeReply, GetDisputesRequest, GetDisputesReply, OpenDisputeRequest, ResolveDisputeRequest, SendDisputeChatMessageRequest, SendChatMessageRequest, GetChatMessagesRequest, GetChatMessagesReply, StartMoneroNodeRequest, StopMoneroNodeRequest, IsMoneroNodeOnlineRequest, IsMoneroNodeOnlineReply, GetMoneroNodeSettingsRequest, GetMoneroNodeSettingsReply } from "./protobuf/grpc_pb";
|
import { GetVersionRequest, GetVersionReply, IsAppInitializedRequest, IsAppInitializedReply, RegisterDisputeAgentRequest, UnregisterDisputeAgentRequest, MarketPriceRequest, MarketPriceReply, MarketPricesRequest, MarketPricesReply, MarketPriceInfo, MarketDepthRequest, MarketDepthReply, MarketDepthInfo, GetBalancesRequest, GetBalancesReply, XmrBalanceInfo, GetMyOfferRequest, GetMyOfferReply, GetOffersRequest, GetOffersReply, OfferInfo, GetPaymentMethodsRequest, GetPaymentMethodsReply, GetPaymentAccountFormRequest, CreatePaymentAccountRequest, ValidateFormFieldRequest, CreatePaymentAccountReply, GetPaymentAccountFormReply, GetPaymentAccountsRequest, GetPaymentAccountsReply, CreateCryptoCurrencyPaymentAccountRequest, CreateCryptoCurrencyPaymentAccountReply, CreateOfferRequest, CreateOfferReply, CancelOfferRequest, TakeOfferRequest, TakeOfferReply, TradeInfo, GetTradeRequest, GetTradeReply, GetTradesRequest, GetTradesReply, GetXmrSeedRequest, GetXmrSeedReply, GetXmrPrimaryAddressRequest, GetXmrPrimaryAddressReply, GetXmrNewSubaddressRequest, GetXmrNewSubaddressReply, ConfirmPaymentStartedRequest, ConfirmPaymentReceivedRequest, CompleteTradeRequest, 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, GetDisputeRequest, GetDisputeReply, GetDisputesRequest, GetDisputesReply, OpenDisputeRequest, ResolveDisputeRequest, SendDisputeChatMessageRequest, SendChatMessageRequest, GetChatMessagesRequest, GetChatMessagesReply, StartMoneroNodeRequest, StopMoneroNodeRequest, IsMoneroNodeOnlineRequest, IsMoneroNodeOnlineReply, GetMoneroNodeSettingsRequest, GetMoneroNodeSettingsReply } from "./protobuf/grpc_pb";
|
||||||
import { PaymentMethod, PaymentAccountForm, PaymentAccountFormField, PaymentAccount, AvailabilityResult, Attachment, DisputeResult, Dispute, ChatMessage, MoneroNodeSettings } from "./protobuf/pb_pb";
|
import { PaymentMethod, PaymentAccountForm, PaymentAccountFormField, PaymentAccount, AvailabilityResult, Attachment, DisputeResult, Dispute, ChatMessage, MoneroNodeSettings } from "./protobuf/pb_pb";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1354,6 +1354,24 @@ export default class HavenoClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acknowledge that a trade has completed.
|
||||||
|
*
|
||||||
|
* @param {string} tradeId - the id of the trade
|
||||||
|
*/
|
||||||
|
async completeTrade(tradeId: string): Promise<void> {
|
||||||
|
try {
|
||||||
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
this._tradesClient.completeTrade(new CompleteTradeRequest().setTradeId(tradeId), {password: this._password}, function(err: grpcWeb.RpcError) {
|
||||||
|
if (err) reject(err);
|
||||||
|
else resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new HavenoError(e.message, e.code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all chat messages for a trade.
|
* Get all chat messages for a trade.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user