diff --git a/README.md b/README.md
index 92a33b04..a31a5510 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ Running the [top-level API tests](./src/HavenoDaemon.test.tsx) is a great way to
   Example: `docker run --rm -it -v ~/git/haveno-ui-poc/config/envoy.test.yaml:/envoy.test.yaml -p 8080:8080 -p 8081:8081 envoyproxy/envoy-dev:8a2143613d43d17d1eb35a24b4a4a4c432215606 -c /envoy.test.yaml`
 5. `npm install`
 6. Modify test config as needed in [HavenoDaemon.test.tsx](./src/HavenoDaemon.test.tsx).
-7. `npm test`
+7. `npm test` to run all tests or `npm run test -- -t 'my test'` to run tests by name
 
 ## How to Update the Protobuf Client
 
diff --git a/src/HavenoDaemon.test.tsx b/src/HavenoDaemon.test.tsx
index 91bb1c47..bfd04e0b 100644
--- a/src/HavenoDaemon.test.tsx
+++ b/src/HavenoDaemon.test.tsx
@@ -5,6 +5,7 @@ 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 GenUtils = monerojs.GenUtils;
 const MoneroTxConfig = monerojs.MoneroTxConfig;
 const TaskLooper = monerojs.TaskLooper;
 
@@ -16,7 +17,7 @@ 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:56627"; // alice's internal haveno wallet for direct testing // TODO (woodser): make configurable rather than randomly generated
+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 aliceWalletUsername = "rpc_user";
 const aliceWalletPassword = "abc123";
 let aliceWallet: any;
@@ -41,6 +42,16 @@ let fundingWallet: any;
 // other test config
 const WALLET_SYNC_PERIOD = 5000;
 const MAX_TIME_PEER_NOTICE = 3000;
+const TEST_CRYPTO_ACCOUNTS = [ // TODO (woodser): test other cryptos, fiat
+  {
+    currencyCode: "eth",
+    address: "0xdBdAb835Acd6fC84cF5F9aDD3c0B5a1E25fbd99f"
+  },
+  {
+    currencyCode: "btc",
+    address: "bcrt1q6j90vywv8x7eyevcnn2tn2wrlg3vsjlsvt46qz"
+  }
+];
 
 beforeAll(async () => {
   
@@ -63,6 +74,22 @@ test("Can get the version", async () => {
   expect(version).toEqual(havenoVersion);
 });
 
+test("Can get market prices", async () => {
+  
+  // test crypto prices  
+  for (let testAccount of TEST_CRYPTO_ACCOUNTS) {
+    let price = await alice.getPrice(testAccount.currencyCode);
+    console.log(testAccount.currencyCode + " price: " + price);
+    expect(price).toBeGreaterThan(0);
+    await GenUtils.waitFor(1000); // wait before next request // TODO (woodser): disable price throttle?
+  }
+    
+  // test fiat price
+  let price = await alice.getPrice("USD");
+  console.log("usd price: " + price);
+  expect(price).toBeGreaterThan(0);
+});
+
 test("Can get balances", async () => {
   let balances: XmrBalanceInfo = await alice.getBalances();
   expect(balances.getUnlockedBalance());
@@ -88,30 +115,49 @@ test("Can get my offers", async () => {
 test("Can get payment accounts", async () => {
   let paymentAccounts: PaymentAccount[] = await alice.getPaymentAccounts();
   for (let paymentAccount of paymentAccounts) {
-    testPaymentAccount(paymentAccount);
+    testCryptoPaymentAccount(paymentAccount);
   }
 });
 
-test("Can create a crypto payment account", async () => {
-  const ethAddress = "0xdBdAb835Acd6fC84cF5F9aDD3c0B5a1E25fbd99f";
-  let ethPaymentAccount: PaymentAccount = await alice.createCryptoPaymentAccount(
-        "my eth account",
-        "eth",
-        "0xdBdAb835Acd6fC84cF5F9aDD3c0B5a1E25fbd99f",
-        true);
-  expect(ethPaymentAccount.getPaymentAccountPayload()!.getInstantCryptoCurrencyAccountPayload()!.getAddress()).toEqual(ethAddress);
-  let found = false; 
-  for (let paymentAccount of await alice.getPaymentAccounts()) {
-    if (paymentAccount.getId() === ethPaymentAccount.getId()) {
-      found = true;
-      ethPaymentAccount = paymentAccount;
-      break;
+test("Can create crypto payment accounts", async () => {
+    
+  // test each stagenet crypto account
+  for (let testAccount of TEST_CRYPTO_ACCOUNTS) {
+    
+    // create payment account
+    let name = testAccount.currencyCode + " " + testAccount.address.substr(0, 8) + "... " + GenUtils.getUUID();
+    let paymentAccount: PaymentAccount = await alice.createCryptoPaymentAccount(
+      name,
+      testAccount.currencyCode,
+      testAccount.address);
+    testCryptoPaymentAccount(paymentAccount);
+    testCryptoPaymentAccountEquals(paymentAccount, testAccount, name);
+    
+    // fetch and test payment account
+    let fetchedAccount: PaymentAccount | undefined;
+    for (let account of await alice.getPaymentAccounts()) {
+      if (paymentAccount.getId() === account.getId()) {
+        fetchedAccount = account;
+        break;
+      }
     }
+    if (!fetchedAccount) throw new Error("Payment account not found after being added");
+    testCryptoPaymentAccount(paymentAccount);
+    testCryptoPaymentAccountEquals(fetchedAccount, testAccount, name);
+    
+    // wait before creating next account
+    await GenUtils.waitFor(1000);
+
+    // TODO (woodser): test rejecting account with invalid currency code
+    // TODO (woodser): test rejecting account with invalid address
+    // TODO (woodser): test rejecting account with duplicate name
+  }
+  
+  function testCryptoPaymentAccountEquals(paymentAccount: PaymentAccount, testAccount: any, name: string) {
+    expect(paymentAccount.getAccountName()).toEqual(name);
+    expect(paymentAccount.getPaymentAccountPayload()!.getCryptoCurrencyAccountPayload()!.getAddress()).toEqual(testAccount.address);
+    expect(paymentAccount.getSelectedTradeCurrency()!.getCode()).toEqual(testAccount.currencyCode.toUpperCase());
   }
-  if (!found) throw new Error("Payment account not found after being added");
-  expect(ethPaymentAccount.getAccountName()).toEqual("my eth account");
-  expect(ethPaymentAccount.getPaymentAccountPayload()!.getInstantCryptoCurrencyAccountPayload()!.getAddress()).toEqual("0xdBdAb835Acd6fC84cF5F9aDD3c0B5a1E25fbd99f");
-  //expect(ethPaymentAccount.getSelectedTradeCurrency()!.getCode()).toEqual("ETH"); // TODO: selected trade currency missing or interferes with other tests
 });
 
 test("Can post and remove an offer", async () => {
@@ -197,16 +243,12 @@ test("Can complete a trade", async () => {
   let tradeAmount: bigint = BigInt("250000000000");
   await waitForUnlockedBalance(tradeAmount, alice, bob);
   
-  // get bob's ethereum payment account
-  let ethPaymentAccount: PaymentAccount | undefined;
-  console.log("Getting bob's payment accounts");
-  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");
+  // create bob's ethereum payment account
+  let testAccount =  TEST_CRYPTO_ACCOUNTS[0];
+  let ethPaymentAccount: PaymentAccount = await bob.createCryptoPaymentAccount(
+      testAccount.currencyCode + " " +  testAccount.address.substr(0, 8) + "... " + GenUtils.getUUID(),
+      testAccount.currencyCode,
+      testAccount.address);
   
   // alice posts offer to buy xmr
   console.log("Alice posting offer");
@@ -325,9 +367,15 @@ function getOffer(offers: OfferInfo[], id: string): OfferInfo | undefined {
   return offers.find(offer => offer.getId() === id);
 }
 
-function testPaymentAccount(paymentAccount: PaymentAccount) {
+function testCryptoPaymentAccount(paymentAccount: PaymentAccount) {
   expect(paymentAccount.getId()).toHaveLength;
-  // TODO: test rest of payment account
+  expect(paymentAccount.getAccountName()).toHaveLength;
+  expect(paymentAccount.getPaymentAccountPayload()!.getCryptoCurrencyAccountPayload()!.getAddress()).toHaveLength;
+  expect(paymentAccount.getSelectedTradeCurrency()!.getCode()).toHaveLength;
+  expect(paymentAccount.getTradeCurrenciesList().length).toEqual(1);
+  let tradeCurrency = paymentAccount.getTradeCurrenciesList()[0];
+  expect(tradeCurrency.getName()).toHaveLength;
+  expect(tradeCurrency.getCode()).toEqual(paymentAccount.getSelectedTradeCurrency()!.getCode());
 }
 
 function testOffer(offer: OfferInfo) {
diff --git a/src/HavenoDaemon.tsx b/src/HavenoDaemon.tsx
index e1807e9e..b3198e22 100644
--- a/src/HavenoDaemon.tsx
+++ b/src/HavenoDaemon.tsx
@@ -1,6 +1,6 @@
 import * as grpcWeb from 'grpc-web';
-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 {GetVersionClient, PriceClient, WalletsClient, OffersClient, PaymentAccountsClient, TradesClient} from './protobuf/GrpcServiceClientPb';
+import {GetVersionRequest, GetVersionReply, MarketPriceRequest, MarketPriceReply, 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';
 
 /**
@@ -12,6 +12,7 @@ class HavenoDaemon {
   _url: string;
   _password: string;
   _getVersionClient: GetVersionClient;
+  _priceClient: PriceClient;
   _walletsClient: WalletsClient;
   _paymentAccountsClient: PaymentAccountsClient;
   _offersClient: OffersClient;
@@ -27,6 +28,7 @@ class HavenoDaemon {
     this._url = url;
     this._password = password;
     this._getVersionClient = new GetVersionClient(this._url);
+    this._priceClient = new PriceClient(this._url);
     this._walletsClient = new WalletsClient(this._url);
     this._paymentAccountsClient = new PaymentAccountsClient(this._url);
     this._offersClient = new OffersClient(this._url);
@@ -48,6 +50,22 @@ class HavenoDaemon {
     });
   }
   
+  /**
+   * Get the current market price of the given currency code as a ratio, e.g. ETH/XMR.
+   * 
+   * @param {string} currencyCode - currency code to get the price of
+   * @return {number} the current market price of the given currency code as a ratio, e.g. XMR/ETH
+   */
+  async getPrice(currencyCode: string) {
+    let that = this;
+    return new Promise(function(resolve, reject) {
+      that._priceClient.getMarketPrice(new MarketPriceRequest().setCurrencyCode(currencyCode), {password: that._password}, function(err: grpcWeb.Error, response: MarketPriceReply) {
+        if (err) reject(err);
+        else resolve(response.getPrice());
+      });
+    });
+  }
+  
   /**
    * Get the user's balances.
    * 
@@ -99,19 +117,17 @@ class HavenoDaemon {
    * @param {string} accountName - description of the account
    * @param {string} currencyCode - currency code of the account
    * @param {string} address - payment address of the account
-   * @param {boolean} tradeInstant - whether or not trade can be completed quickly
    * @return {PaymentAccount} the created payment account
    */
   async createCryptoPaymentAccount(accountName: string,
         currencyCode: string,
-        address: string,
-        tradeInstant: boolean): Promise<PaymentAccount> {
+        address: string): Promise<PaymentAccount> {
     let that = this;
     let request = new CreateCryptoCurrencyPaymentAccountRequest()
             .setAccountName(accountName)
             .setCurrencyCode(currencyCode)
             .setAddress(address)
-            .setTradeInstant(tradeInstant);
+            false; // not using instant trades
     return new Promise(function(resolve, reject) {
       that._paymentAccountsClient.createCryptoCurrencyPaymentAccount(request, {password: that._password}, function(err: grpcWeb.Error, response: CreateCryptoCurrencyPaymentAccountReply) {
         if (err) reject(err);