test basic end-to-end trade completion

add methods to take offer and indicate payment to haveno daemon
add getNewDepositSubaddress() to haveno daemon
automatically fund haveno wallets and await unlocked funds
run tests sequentially
update protobuf definition
This commit is contained in:
woodser 2021-09-19 14:00:22 -04:00
parent e35f8c5e95
commit a268b26784
7 changed files with 649 additions and 58 deletions

View File

@ -431,6 +431,8 @@ message TxInfo {
service Wallets {
rpc GetBalances (GetBalancesRequest) returns (GetBalancesReply) {
}
rpc GetNewDepositSubaddress (GetNewDepositSubaddressRequest) returns (GetNewDepositSubaddressReply) {
}
rpc GetAddressBalance (GetAddressBalanceRequest) returns (GetAddressBalanceReply) {
}
rpc GetUnusedBsqAddress (GetUnusedBsqAddressRequest) returns (GetUnusedBsqAddressReply) {
@ -469,6 +471,13 @@ message GetBalancesReply {
BalancesInfo balances = 1;
}
message GetNewDepositSubaddressRequest {
}
message GetNewDepositSubaddressReply {
string subaddress = 1;
}
message GetAddressBalanceRequest {
string address = 1;
}

View File

@ -21,7 +21,7 @@
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"test": "react-scripts test --runInBand",
"eject": "react-scripts eject"
},
"eslintConfig": {

View File

@ -1,23 +1,26 @@
// import haveno types
import {HavenoDaemon} from "./HavenoDaemon";
import {XmrBalanceInfo, OfferInfo} from './protobuf/grpc_pb'; // TODO (woodser): better names; haveno_grpc_pb, haveno_pb
import {XmrBalanceInfo, OfferInfo, TradeInfo} from './protobuf/grpc_pb'; // TODO (woodser): better names; haveno_grpc_pb, haveno_pb
import {PaymentAccount} from './protobuf/pb_pb';
// import monero-javascript
const monerojs = require("monero-javascript"); // TODO (woodser): support typescript and `npm install @types/monero-javascript` in monero-javascript
const MoneroDaemonRpc = monerojs.MoneroDaemonRpc;
const MoneroWalletRpc = monerojs.MoneroWalletRpc;
const MoneroTxConfig = monerojs.MoneroTxConfig;
const TaskLooper = monerojs.TaskLooper;
// import console because jest swallows messages in real time
const console = require('console');
// alice config
const havenoVersion = "1.6.2";
const aliceDaemonUrl = "http://localhost:8080";
const aliceDaemonPassword = "apitest";
const alice: HavenoDaemon = new HavenoDaemon(aliceDaemonUrl, aliceDaemonPassword);
const aliceWalletUrl = "http://127.0.0.1:51743"; // alice's internal haveno wallet for direct testing // TODO (woodser): make configurable rather than randomly generated
const aliceWalletUrl = "http://127.0.0.1:57983"; // alice's internal haveno wallet for direct testing // TODO (woodser): make configurable rather than randomly generated
const aliceWalletUsername = "rpc_user";
const aliceWalletPassword = "abc123";
const aliceWallet = new MoneroWalletRpc(aliceWalletUrl, aliceWalletUsername, aliceWalletPassword);
const aliceWalletSyncPeriod = 5000;
let aliceWallet: any;
// bob config
const bobDaemonUrl = "http://localhost:8081";
@ -27,15 +30,35 @@ const bob: HavenoDaemon = new HavenoDaemon(bobDaemonUrl, bobDaemonPassword);
// monero daemon config
const moneroDaemonUrl = "http://localhost:38081"
const moneroDaemonUsername = "superuser";
const moneroDaemonPassword = "abctesting123";
const moneroDaemonPassword = "abctesting123";
const miningAddress = "59M2dSSmrKiimFavjWQ8zFGWe6ziHr9XUjhHcMVEj9ut4EdkcmcqawfgMrtEERipUJA8iNzU65eaELoFYcor1c4jK4FRj1N";
let monerod: any;
// source funding wallet
const fundingWalletUrl = "http://localhost:38084";
const fundingWalletUsername = "rpc_user";
const fundingWalletPassword = "abc123";
let fundingWallet: any;
// other test config
const MAX_TIME_PEER_NOTICE = 3000;
beforeAll(async () => {
await monerojs.LibraryUtils.setWorkerDistPath("./node_modules/monero-javascript/src/main/js/common/MoneroWebWorker.js"); // TODO (woodser): remove this when update to monero-javascript-v0.5.6 which correctly detects node environment
// TODO (woodser): remove this when update to monero-javascript-v0.5.6 which correctly detects node environment
await monerojs.LibraryUtils.setWorkerDistPath("./node_modules/monero-javascript/src/main/js/common/MoneroWebWorker.js");
// initialize clients of wallet and daemon rpc
aliceWallet = await monerojs.connectToWalletRpc(aliceWalletUrl, aliceWalletUsername, aliceWalletPassword);
fundingWallet = await monerojs.connectToWalletRpc(fundingWalletUrl, fundingWalletUsername, fundingWalletPassword);
monerod = await monerojs.connectToDaemonRpc(moneroDaemonUrl, moneroDaemonUsername, moneroDaemonPassword);
// debug tools
//for (let offer of await alice.getMyOffers("BUY")) await alice.removeOffer(offer.getId());
//for (let offer of await alice.getMyOffers("SELL")) await alice.removeOffer(offer.getId());
//for (let frozenOutput of await aliceWallet.getOutputs({isFrozen: true})) await aliceWallet.thawOutput(frozenOutput.getKeyImage().getHex());
//console.log((await alice.getBalances()).getUnlockedBalance() + ", " + (await alice.getBalances()).getLockedBalance());
//console.log((await bob.getBalances()).getUnlockedBalance() + ", " + (await bob.getBalances()).getLockedBalance());
});
test("Can get the version", async () => {
@ -119,7 +142,7 @@ test("Invalidates offers when reserved funds are spent", async () => {
}
// offer is available to peers
await wait(3000);
await wait(MAX_TIME_PEER_NOTICE);
if (!getOffer(await bob.getOffers("buy"), offer.getId())) throw new Error("Offer " + offer.getId() + " was not found in peer's offers after posting");
// spend one of offer's reserved outputs
@ -149,18 +172,86 @@ test("Invalidates offers when reserved funds are spent", async () => {
await monerod.flushTxPool(tx.getHash());
});
jest.setTimeout(120000);
test("Can complete a trade", async () => {
console.log("Alice balances: " + getBalancesStr(await alice.getBalances()));
// wait for alice and bob to have unlocked balance for trade
let tradeAmount: bigint = BigInt("250000000000");
await waitForUnlockedBalance(tradeAmount, alice, bob);
// TODO: finish this test
// alice posts offer to buy xmr
console.log("Alice posting offer");
let offer: OfferInfo = await postOffer();
console.log("Alice done posting offer");
// bob sees offer
await wait(MAX_TIME_PEER_NOTICE);
// get bob's ethereum payment account
let ethPaymentAccount: PaymentAccount | undefined;
for (let paymentAccount of await bob.getPaymentAccounts()) {
if (paymentAccount.getSelectedTradeCurrency()?.getCode() === "ETH") {
ethPaymentAccount = paymentAccount;
break;
}
}
if (!ethPaymentAccount) throw new Error("Bob must have ethereum payment account to take offer");
// bob takes offer
let startTime = Date.now();
let bobBalancesBefore: XmrBalanceInfo = await bob.getBalances();
console.log("Bob taking offer");
let trade: TradeInfo = await bob.takeOffer(offer.getId(), ethPaymentAccount.getId()); // TODO (woodser): this returns before trade is fully initialized
console.log("Bob done taking offer in " + (Date.now() - startTime) + " ms");
// bob can get trade
let fetchedTrade: TradeInfo = await bob.getTrade(trade.getTradeId());
// TODO: test fetched trade
// test bob's balances after taking trade
let bobBalancesAfter: XmrBalanceInfo = await bob.getBalances();
expect(BigInt(bobBalancesAfter.getUnlockedBalance())).toBeLessThan(BigInt(bobBalancesBefore.getUnlockedBalance()));
expect(BigInt(bobBalancesAfter.getReservedOfferBalance()) + BigInt(bobBalancesAfter.getReservedTradeBalance())).toBeGreaterThan(BigInt(bobBalancesBefore.getReservedOfferBalance()) + BigInt(bobBalancesBefore.getReservedTradeBalance()));
// bob is notified of balance change
// alice notified of balance changes and that offer is taken
await wait(MAX_TIME_PEER_NOTICE);
// alice can get trade
fetchedTrade = await alice.getTrade(trade.getTradeId());
// mine until deposit txs unlock
console.log("Mining to unlock deposit txs");
await waitForUnlockedTxs(fetchedTrade.getMakerDepositTxId(), fetchedTrade.getTakerDepositTxId());
console.log("Done mining to unlock deposit txs");
// alice notified to send payment
await wait(5000);
// alice indicates payment is sent
await alice.confirmPaymentStarted(trade.getTradeId());
// bob notified payment is sent
await wait(MAX_TIME_PEER_NOTICE);
// bob confirms payment is received
await bob.confirmPaymentReceived(trade.getTradeId());
// bob notified trade is complete
fetchedTrade = await bob.getTrade(trade.getTradeId());
console.log(fetchedTrade.getState()); // TODO (woodser): this should be complete state
// test bob's balances after confirming payment
// alice notified trade is complete and of balance changes
});
// ------------------------------- HELPERS ------------------------------------
async function postOffer() {
async function postOffer() { // TODO (woodser): postOffer(maker, peer)
// test requires ethereum payment account
let ethPaymentAccount: PaymentAccount | undefined;
@ -177,7 +268,7 @@ async function postOffer() {
// post offer
// TODO: don't define variables, just document in comments
let amount: bigint = BigInt("250000000000");
let amount: bigint = BigInt("200000000000");
let minAmount: bigint = BigInt("150000000000");
let price: number = 12.378981; // TODO: price is optional? price string gets converted to long?
let useMarketBasedPrice: boolean = true;
@ -208,8 +299,8 @@ async function postOffer() {
return offer;
}
async function waitForUnlockedBalance(amount: bigint, ...clients: HavenoDaemon[]) {
throw new Error("waitForUnlockedFunds() not implemented"); // TODO: implement
function getBalancesStr(balances: XmrBalanceInfo) {
return "[unlocked balance=" + balances.getUnlockedBalance() + ", locked balance=" + balances.getLockedBalance() + ", reserved offer balance=" + balances.getReservedOfferBalance() + ", reserved trade balance: " + balances.getReservedTradeBalance() + "]";
}
function getOffer(offers: OfferInfo[], id: string): OfferInfo | undefined {
@ -228,4 +319,71 @@ function testOffer(offer: OfferInfo) {
async function wait(durationMs: number) {
return new Promise(function(resolve) { setTimeout(resolve, durationMs); });
}
async function startMining() {
try {
await monerod.startMining(miningAddress, 1);
} catch (err) {
if (err.message !== "Already mining") throw err;
}
}
async function waitForUnlockedBalance(amount: bigint, ...clients: HavenoDaemon[]) {
// fund haveno clients with insufficient balance
let miningNeeded = false;
let fundConfig = new MoneroTxConfig().setAccountIndex(0).setRelay(true);
for (let client of clients) {
let balances = await client.getBalances();
if (BigInt(balances.getUnlockedBalance()) < amount) miningNeeded = true;
let depositNeeded: BigInt = amount - BigInt(balances.getUnlockedBalance()) - BigInt(balances.getLockedBalance());
if (depositNeeded > BigInt("0")) fundConfig.addDestination(await client.getNewDepositSubaddress(), depositNeeded);
}
if (fundConfig.getDestinations()) {
try { await fundingWallet.createTx(fundConfig); }
catch (err) { throw new Error("Error funding haveno daemons: " + err.message); }
}
// done if all clients have sufficient unlocked balance
if (!miningNeeded) return;
// wait for funds to unlock
console.log("Mining for unlocked trader balances")
await startMining();
let promises: Promise<void>[] = []
for (let client of clients) {
promises.push(new Promise(async function(resolve, reject) {
let taskLooper: any = new TaskLooper(async function() {
let balances: XmrBalanceInfo = await client.getBalances();
if (BigInt(balances.getUnlockedBalance()) >= amount) {
taskLooper.stop();
resolve();
}
});
taskLooper.start(5000);
}));
}
await Promise.all(promises);
await monerod.stopMining();
console.log("Funds unlocked, done mining");
};
async function waitForUnlockedTxs(...txHashes: string[]) {
await startMining();
let promises: Promise<void>[] = []
for (let txHash of txHashes) {
promises.push(new Promise(async function(resolve, reject) {
let taskLooper: any = new TaskLooper(async function() {
let tx = await monerod.getTx(txHash);
if (tx.isConfirmed() && tx.getBlock().getHeight() <= await monerod.getHeight() - 10) {
taskLooper.stop();
resolve();
}
});
taskLooper.start(5000);
}));
}
await Promise.all(promises);
await monerod.stopMining();
}

View File

@ -1,7 +1,7 @@
import * as grpcWeb from 'grpc-web';
import {GetVersionClient, WalletsClient, OffersClient, PaymentAccountsClient} from './protobuf/GrpcServiceClientPb';
import {GetVersionRequest, GetVersionReply, GetBalancesRequest, GetBalancesReply, XmrBalanceInfo, GetOffersRequest, GetOffersReply, OfferInfo, GetPaymentAccountsRequest, GetPaymentAccountsReply, CreateCryptoCurrencyPaymentAccountRequest, CreateCryptoCurrencyPaymentAccountReply, CreateOfferRequest, CreateOfferReply, CancelOfferRequest} from './protobuf/grpc_pb';
import {PaymentAccount} from './protobuf/pb_pb';
import {GetVersionClient, WalletsClient, OffersClient, PaymentAccountsClient, TradesClient} from './protobuf/GrpcServiceClientPb';
import {GetVersionRequest, GetVersionReply, GetBalancesRequest, GetBalancesReply, XmrBalanceInfo, GetOffersRequest, GetOffersReply, OfferInfo, GetPaymentAccountsRequest, GetPaymentAccountsReply, CreateCryptoCurrencyPaymentAccountRequest, CreateCryptoCurrencyPaymentAccountReply, CreateOfferRequest, CreateOfferReply, CancelOfferRequest, TakeOfferRequest, TakeOfferReply, TradeInfo, GetTradeRequest, GetTradeReply, GetNewDepositSubaddressRequest, GetNewDepositSubaddressReply, ConfirmPaymentStartedRequest, ConfirmPaymentReceivedRequest} from './protobuf/grpc_pb';
import {PaymentAccount, AvailabilityResult} from './protobuf/pb_pb';
/**
* Haveno daemon client using gRPC.
@ -13,8 +13,9 @@ class HavenoDaemon {
_password: string;
_getVersionClient: GetVersionClient;
_walletsClient: WalletsClient;
_offersClient: OffersClient;
_paymentAccountsClient: PaymentAccountsClient;
_offersClient: OffersClient;
_tradesClient: TradesClient;
/**
* Construct a client connected to a Haveno daemon.
@ -27,8 +28,9 @@ class HavenoDaemon {
this._password = password;
this._getVersionClient = new GetVersionClient(this._url);
this._walletsClient = new WalletsClient(this._url);
this._offersClient = new OffersClient(this._url);
this._paymentAccountsClient = new PaymentAccountsClient(this._url);
this._offersClient = new OffersClient(this._url);
this._tradesClient = new TradesClient(this._url);
}
/**
@ -38,9 +40,8 @@ class HavenoDaemon {
*/
async getVersion(): Promise<string> {
let that = this;
let request = new GetVersionRequest();
return new Promise(function(resolve, reject) {
that._getVersionClient.getVersion(request, {password: that._password}, function(err: grpcWeb.Error, response: GetVersionReply) {
that._getVersionClient.getVersion(new GetVersionRequest(), {password: that._password}, function(err: grpcWeb.Error, response: GetVersionReply) {
if (err) reject(err);
else resolve(response.getVersion());
});
@ -54,9 +55,8 @@ class HavenoDaemon {
*/
async getBalances(): Promise<XmrBalanceInfo> {
let that = this;
let request = new GetBalancesRequest();
return new Promise(function(resolve, reject) {
that._walletsClient.getBalances(request, {password: that._password}, function(err: grpcWeb.Error, response: GetBalancesReply) {
that._walletsClient.getBalances(new GetBalancesRequest(), {password: that._password}, function(err: grpcWeb.Error, response: GetBalancesReply) {
if (err) reject(err);
else resolve(response.getBalances()!.getXmr()!);
});
@ -64,41 +64,16 @@ class HavenoDaemon {
}
/**
* Get available offers to buy or sell XMR.
* Get a new subaddress in the Haveno wallet to receive deposits.
*
* @param {string} direction - one of "BUY" or "SELL"
*
* @return {OfferInfo[]} available offers
* @return {string} the deposit address (a subaddress in the Haveno wallet)
*/
async getOffers(direction: string): Promise<OfferInfo[]> {
let request = new GetOffersRequest()
.setDirection(direction)
.setCurrencyCode("XMR");
async getNewDepositSubaddress(): Promise<string> {
let that = this;
return new Promise(function(resolve, reject) {
that._offersClient.getOffers(request, {password: that._password}, function(err: grpcWeb.Error, response: GetOffersReply) {
that._walletsClient.getNewDepositSubaddress(new GetNewDepositSubaddressRequest(), {password: that._password}, function(err: grpcWeb.Error, response: GetNewDepositSubaddressReply) {
if (err) reject(err);
else resolve(response.getOffersList());
});
});
}
/**
* Get user's created offers to buy or sell XMR.
*
* @param {string} direction - one of "BUY" or "SELL"
*
* @return {OfferInfo[]} the user's created offers
*/
async getMyOffers(direction: string): Promise<OfferInfo[]> {
let that = this;
let request = new GetOffersRequest()
.setDirection(direction)
.setCurrencyCode("XMR");
return new Promise(function(resolve, reject) {
that._offersClient.getMyOffers(request, {password: that._password}, function(err: grpcWeb.Error, response: GetOffersReply) {
if (err) reject(err);
else resolve(response.getOffersList());
else resolve(response.getSubaddress());
});
});
}
@ -145,6 +120,40 @@ class HavenoDaemon {
});
}
/**
* Get available offers to buy or sell XMR.
*
* @param {string} direction - one of "BUY" or "SELL"
*
* @return {OfferInfo[]} available offers
*/
async getOffers(direction: string): Promise<OfferInfo[]> {
let that = this;
return new Promise(function(resolve, reject) {
that._offersClient.getOffers(new GetOffersRequest().setDirection(direction).setCurrencyCode("XMR"), {password: that._password}, function(err: grpcWeb.Error, response: GetOffersReply) {
if (err) reject(err);
else resolve(response.getOffersList());
});
});
}
/**
* Get user's created offers to buy or sell XMR.
*
* @param {string} direction - one of "BUY" or "SELL"
*
* @return {OfferInfo[]} the user's created offers
*/
async getMyOffers(direction: string): Promise<OfferInfo[]> {
let that = this;
return new Promise(function(resolve, reject) {
that._offersClient.getMyOffers(new GetOffersRequest().setDirection(direction).setCurrencyCode("XMR"), {password: that._password}, function(err: grpcWeb.Error, response: GetOffersReply) {
if (err) reject(err);
else resolve(response.getOffersList());
});
});
}
/**
* Post an offer.
*
@ -158,7 +167,7 @@ class HavenoDaemon {
* @param {number} buyerSecurityDeposit - buyer security deposit as % of trade amount
* @param {string} paymentAccountId - payment account id
* @param {number} triggerPrice - price to remove offer
* @return {HavenoOffer[]} created offers
* @return {OfferInfo} the created offer
*/
async postOffer(currencyCode: string,
direction: string,
@ -194,12 +203,80 @@ class HavenoDaemon {
/**
* Remove a posted offer, releasing its reserved funds.
*
* @param {string} id - the offer id to cancel
* @param {string} offerId - the offer id to cancel
*/
async removeOffer(id: string): Promise<void> {
async removeOffer(offerId: string): Promise<void> {
let that = this;
return new Promise(function(resolve, reject) {
that._offersClient.cancelOffer(new CancelOfferRequest().setId(id), {password: that._password}, function(err: grpcWeb.Error) {
that._offersClient.cancelOffer(new CancelOfferRequest().setId(offerId), {password: that._password}, function(err: grpcWeb.Error) {
if (err) reject(err);
else resolve();
});
});
}
/**
* Take an offer.
*
* @param {string} offerId - id of the offer to take
* @param {string} paymentAccountId - id of the payment account
* @return {TradeInfo} the initialized trade
*/
async takeOffer(offerId: string, paymentAccountId: string): Promise<TradeInfo> {
let that = this;
let request = new TakeOfferRequest()
.setOfferId(offerId)
.setPaymentAccountId(paymentAccountId)
.setTakerFeeCurrencyCode("XMR");
return new Promise(function(resolve, reject) {
that._tradesClient.takeOffer(request, {password: that._password}, function(err: grpcWeb.Error, response: TakeOfferReply) {
if (err) reject(err);
else if (response.getFailureReason() && response.getFailureReason()!.getAvailabilityResult() !== AvailabilityResult.AVAILABLE) reject(response.getFailureReason()!.getDescription());
else resolve(response.getTrade());
});
});
}
/**
* Get a trade by id.
*
* @param {string} tradeId - the id of the trade and its offer
* @return {TradeInfo} the trade with the given id
*/
async getTrade(tradeId: string): Promise<TradeInfo> {
let that = this;
return new Promise(function(resolve, reject) {
that._tradesClient.getTrade(new GetTradeRequest().setTradeId(tradeId), {password: that._password}, function(err: grpcWeb.Error, response: GetTradeReply) {
if (err) reject(err);
else resolve(response.getTrade());
});
});
}
/**
* Confirm a payment is started.
*
* @param {string} tradeId - the id of the trade
*/
async confirmPaymentStarted(tradeId: string): Promise<void> {
let that = this;
return new Promise(function(resolve, reject) {
that._tradesClient.confirmPaymentStarted(new ConfirmPaymentStartedRequest().setTradeId(tradeId), {password: that._password}, function(err: grpcWeb.Error) {
if (err) reject(err);
else resolve();
});
});
}
/**
* Confirm a payment is received.
*
* @param {string} tradeId - the id of the trade
*/
async confirmPaymentReceived(tradeId: string): Promise<void> {
let that = this;
return new Promise(function(resolve, reject) {
that._tradesClient.confirmPaymentReceived(new ConfirmPaymentReceivedRequest().setTradeId(tradeId), {password: that._password}, function(err: grpcWeb.Error) {
if (err) reject(err);
else resolve();
});

View File

@ -1163,6 +1163,46 @@ export class WalletsClient {
this.methodInfoGetBalances);
}
methodInfoGetNewDepositSubaddress = new grpcWeb.AbstractClientBase.MethodInfo(
grpc_pb.GetNewDepositSubaddressReply,
(request: grpc_pb.GetNewDepositSubaddressRequest) => {
return request.serializeBinary();
},
grpc_pb.GetNewDepositSubaddressReply.deserializeBinary
);
getNewDepositSubaddress(
request: grpc_pb.GetNewDepositSubaddressRequest,
metadata: grpcWeb.Metadata | null): Promise<grpc_pb.GetNewDepositSubaddressReply>;
getNewDepositSubaddress(
request: grpc_pb.GetNewDepositSubaddressRequest,
metadata: grpcWeb.Metadata | null,
callback: (err: grpcWeb.Error,
response: grpc_pb.GetNewDepositSubaddressReply) => void): grpcWeb.ClientReadableStream<grpc_pb.GetNewDepositSubaddressReply>;
getNewDepositSubaddress(
request: grpc_pb.GetNewDepositSubaddressRequest,
metadata: grpcWeb.Metadata | null,
callback?: (err: grpcWeb.Error,
response: grpc_pb.GetNewDepositSubaddressReply) => void) {
if (callback !== undefined) {
return this.client_.rpcCall(
this.hostname_ +
'/io.bisq.protobuffer.Wallets/GetNewDepositSubaddress',
request,
metadata || {},
this.methodInfoGetNewDepositSubaddress,
callback);
}
return this.client_.unaryCall(
this.hostname_ +
'/io.bisq.protobuffer.Wallets/GetNewDepositSubaddress',
request,
metadata || {},
this.methodInfoGetNewDepositSubaddress);
}
methodInfoGetAddressBalance = new grpcWeb.AbstractClientBase.MethodInfo(
grpc_pb.GetAddressBalanceReply,
(request: grpc_pb.GetAddressBalanceRequest) => {

View File

@ -1343,6 +1343,38 @@ export namespace GetBalancesReply {
}
}
export class GetNewDepositSubaddressRequest extends jspb.Message {
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): GetNewDepositSubaddressRequest.AsObject;
static toObject(includeInstance: boolean, msg: GetNewDepositSubaddressRequest): GetNewDepositSubaddressRequest.AsObject;
static serializeBinaryToWriter(message: GetNewDepositSubaddressRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): GetNewDepositSubaddressRequest;
static deserializeBinaryFromReader(message: GetNewDepositSubaddressRequest, reader: jspb.BinaryReader): GetNewDepositSubaddressRequest;
}
export namespace GetNewDepositSubaddressRequest {
export type AsObject = {
}
}
export class GetNewDepositSubaddressReply extends jspb.Message {
getSubaddress(): string;
setSubaddress(value: string): GetNewDepositSubaddressReply;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): GetNewDepositSubaddressReply.AsObject;
static toObject(includeInstance: boolean, msg: GetNewDepositSubaddressReply): GetNewDepositSubaddressReply.AsObject;
static serializeBinaryToWriter(message: GetNewDepositSubaddressReply, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): GetNewDepositSubaddressReply;
static deserializeBinaryFromReader(message: GetNewDepositSubaddressReply, reader: jspb.BinaryReader): GetNewDepositSubaddressReply;
}
export namespace GetNewDepositSubaddressReply {
export type AsObject = {
subaddress: string,
}
}
export class GetAddressBalanceRequest extends jspb.Message {
getAddress(): string;
setAddress(value: string): GetAddressBalanceRequest;

View File

@ -49,6 +49,8 @@ goog.exportSymbol('proto.io.bisq.protobuffer.GetMyOfferReply', null, global);
goog.exportSymbol('proto.io.bisq.protobuffer.GetMyOfferRequest', null, global);
goog.exportSymbol('proto.io.bisq.protobuffer.GetMyOffersReply', null, global);
goog.exportSymbol('proto.io.bisq.protobuffer.GetMyOffersRequest', null, global);
goog.exportSymbol('proto.io.bisq.protobuffer.GetNewDepositSubaddressReply', null, global);
goog.exportSymbol('proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest', null, global);
goog.exportSymbol('proto.io.bisq.protobuffer.GetOfferReply', null, global);
goog.exportSymbol('proto.io.bisq.protobuffer.GetOfferRequest', null, global);
goog.exportSymbol('proto.io.bisq.protobuffer.GetOffersReply', null, global);
@ -1262,6 +1264,48 @@ if (goog.DEBUG && !COMPILED) {
*/
proto.io.bisq.protobuffer.GetBalancesReply.displayName = 'proto.io.bisq.protobuffer.GetBalancesReply';
}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
* server response, or constructed directly in Javascript. The array is used
* in place and becomes part of the constructed object. It is not cloned.
* If no data is provided, the constructed object will be empty, but still
* valid.
* @extends {jspb.Message}
* @constructor
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest = function(opt_data) {
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest, jspb.Message);
if (goog.DEBUG && !COMPILED) {
/**
* @public
* @override
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest.displayName = 'proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest';
}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
* server response, or constructed directly in Javascript. The array is used
* in place and becomes part of the constructed object. It is not cloned.
* If no data is provided, the constructed object will be empty, but still
* valid.
* @extends {jspb.Message}
* @constructor
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply = function(opt_data) {
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.io.bisq.protobuffer.GetNewDepositSubaddressReply, jspb.Message);
if (goog.DEBUG && !COMPILED) {
/**
* @public
* @override
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.displayName = 'proto.io.bisq.protobuffer.GetNewDepositSubaddressReply';
}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
@ -11955,6 +11999,237 @@ proto.io.bisq.protobuffer.GetBalancesReply.prototype.hasBalances = function() {
if (jspb.Message.GENERATE_TO_OBJECT) {
/**
* Creates an object representation of this proto.
* Field names that are reserved in JavaScript and will be renamed to pb_name.
* Optional fields that are not set will be set to undefined.
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
* For the list of reserved names please see:
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
* JSPB instance for transitional soy proto support:
* http://goto/soy-param-migration
* @return {!Object}
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest.prototype.toObject = function(opt_includeInstance) {
return proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest.toObject(opt_includeInstance, this);
};
/**
* Static version of the {@see toObject} method.
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
* the JSPB instance for transitional soy proto support:
* http://goto/soy-param-migration
* @param {!proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest} msg The msg instance to transform.
* @return {!Object}
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest.toObject = function(includeInstance, msg) {
var f, obj = {
};
if (includeInstance) {
obj.$jspbMessageInstance = msg;
}
return obj;
};
}
/**
* Deserializes binary data (in protobuf wire format).
* @param {jspb.ByteSource} bytes The bytes to deserialize.
* @return {!proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest}
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest.deserializeBinary = function(bytes) {
var reader = new jspb.BinaryReader(bytes);
var msg = new proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest;
return proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest.deserializeBinaryFromReader(msg, reader);
};
/**
* Deserializes binary data (in protobuf wire format) from the
* given reader into the given message object.
* @param {!proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest} msg The message object to deserialize into.
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
* @return {!proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest}
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest.deserializeBinaryFromReader = function(msg, reader) {
while (reader.nextField()) {
if (reader.isEndGroup()) {
break;
}
var field = reader.getFieldNumber();
switch (field) {
default:
reader.skipField();
break;
}
}
return msg;
};
/**
* Serializes the message to binary data (in protobuf wire format).
* @return {!Uint8Array}
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest.prototype.serializeBinary = function() {
var writer = new jspb.BinaryWriter();
proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest.serializeBinaryToWriter(this, writer);
return writer.getResultBuffer();
};
/**
* Serializes the given message to binary data (in protobuf wire
* format), writing to the given BinaryWriter.
* @param {!proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest} message
* @param {!jspb.BinaryWriter} writer
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressRequest.serializeBinaryToWriter = function(message, writer) {
var f = undefined;
};
if (jspb.Message.GENERATE_TO_OBJECT) {
/**
* Creates an object representation of this proto.
* Field names that are reserved in JavaScript and will be renamed to pb_name.
* Optional fields that are not set will be set to undefined.
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
* For the list of reserved names please see:
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
* JSPB instance for transitional soy proto support:
* http://goto/soy-param-migration
* @return {!Object}
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.prototype.toObject = function(opt_includeInstance) {
return proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.toObject(opt_includeInstance, this);
};
/**
* Static version of the {@see toObject} method.
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
* the JSPB instance for transitional soy proto support:
* http://goto/soy-param-migration
* @param {!proto.io.bisq.protobuffer.GetNewDepositSubaddressReply} msg The msg instance to transform.
* @return {!Object}
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.toObject = function(includeInstance, msg) {
var f, obj = {
subaddress: jspb.Message.getFieldWithDefault(msg, 1, "")
};
if (includeInstance) {
obj.$jspbMessageInstance = msg;
}
return obj;
};
}
/**
* Deserializes binary data (in protobuf wire format).
* @param {jspb.ByteSource} bytes The bytes to deserialize.
* @return {!proto.io.bisq.protobuffer.GetNewDepositSubaddressReply}
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.deserializeBinary = function(bytes) {
var reader = new jspb.BinaryReader(bytes);
var msg = new proto.io.bisq.protobuffer.GetNewDepositSubaddressReply;
return proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.deserializeBinaryFromReader(msg, reader);
};
/**
* Deserializes binary data (in protobuf wire format) from the
* given reader into the given message object.
* @param {!proto.io.bisq.protobuffer.GetNewDepositSubaddressReply} msg The message object to deserialize into.
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
* @return {!proto.io.bisq.protobuffer.GetNewDepositSubaddressReply}
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.deserializeBinaryFromReader = function(msg, reader) {
while (reader.nextField()) {
if (reader.isEndGroup()) {
break;
}
var field = reader.getFieldNumber();
switch (field) {
case 1:
var value = /** @type {string} */ (reader.readString());
msg.setSubaddress(value);
break;
default:
reader.skipField();
break;
}
}
return msg;
};
/**
* Serializes the message to binary data (in protobuf wire format).
* @return {!Uint8Array}
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.prototype.serializeBinary = function() {
var writer = new jspb.BinaryWriter();
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.serializeBinaryToWriter(this, writer);
return writer.getResultBuffer();
};
/**
* Serializes the given message to binary data (in protobuf wire
* format), writing to the given BinaryWriter.
* @param {!proto.io.bisq.protobuffer.GetNewDepositSubaddressReply} message
* @param {!jspb.BinaryWriter} writer
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.serializeBinaryToWriter = function(message, writer) {
var f = undefined;
f = message.getSubaddress();
if (f.length > 0) {
writer.writeString(
1,
f
);
}
};
/**
* optional string subaddress = 1;
* @return {string}
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.prototype.getSubaddress = function() {
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};
/**
* @param {string} value
* @return {!proto.io.bisq.protobuffer.GetNewDepositSubaddressReply} returns this
*/
proto.io.bisq.protobuffer.GetNewDepositSubaddressReply.prototype.setSubaddress = function(value) {
return jspb.Message.setProto3StringField(this, 1, value);
};
if (jspb.Message.GENERATE_TO_OBJECT) {
/**
* Creates an object representation of this proto.