Page MenuHomePhabricator

[Cashtab] Use in-node chronik
ClosedPublic

Authored by bytesofman on Mar 13 2024, 20:37.

Details

Reviewers
emack
Group Reviewers
Restricted Project
Commits
rABC9eb260629692: [Cashtab] Use in-node chronik
Summary

Use in-node chronik to power Cashtab

Because in-node chronik returns utxos and tx objects in a different shape, many existing mocks are updated in this diff. For the most part this was scripted (i.e., call for this tx from an in-node chronik instance and use that output).

This diff impplements in-node chronik-client with minimal behavior change to Cashtab. In-node chronik makes future improvements possible. These will be in later diffs (e.g. we can get avalanche finalization status on txs from the websocket, we can deprecate SLPDB in airdrops, we can support more tokens than slpv1, etc).

Test Plan

npm test

This version is mock prod-deployed at https://cashtab-local-dev.netlify.app/

Diff Detail

Repository
rABC Bitcoin ABC
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

Tail of the build log:

Installing mock-chronik-client dependencies...
/work/modules/mock-chronik-client /work/abc-ci-builds/cashtab-tests

added 236 packages, and audited 237 packages in 1s

35 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
/work/cashtab /work/modules/mock-chronik-client /work/abc-ci-builds/cashtab-tests
npm WARN deprecated @babel/plugin-proposal-private-methods@7.18.6: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.
npm WARN deprecated @babel/plugin-proposal-nullish-coalescing-operator@7.18.6: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.
npm WARN deprecated @babel/plugin-proposal-numeric-separator@7.18.6: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.
npm WARN deprecated rollup-plugin-terser@7.0.2: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser
npm WARN deprecated abab@2.0.6: Use your platform's native atob() and btoa() methods instead
npm WARN deprecated @babel/plugin-proposal-class-properties@7.18.6: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
npm WARN deprecated @babel/plugin-proposal-private-property-in-object@7.21.11: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.
npm WARN deprecated domexception@4.0.0: Use your platform's native DOMException instead
npm WARN deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
npm WARN deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
npm WARN deprecated @babel/plugin-proposal-optional-chaining@7.21.0: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.
npm WARN deprecated workbox-cacheable-response@6.6.0: workbox-background-sync@6.6.0

added 1722 packages, and audited 1723 packages in 22s

263 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

> cashtab@2.2.0 build
> node scripts/build.js

Creating an optimized production build...
Failed to compile.

[eslint] 
src/components/Send/SendToken.js
  Line 109:32:  'cashtabCache' is assigned a value but never used  no-unused-vars

Search for the keywords to learn more about each error.


Build cashtab-tests failed with exit code 1

Failed tests logs:

====== CashTab Unit Tests: We can create and broadcast SLP v1 SEND and BURN txs from utxos of nng or in-node chronik shape Build and broadcast an SLP V1 SEND tx and an SLP V1 BURN tx from NNG chronik-client utxos: SLP send and BURN with token change, NNG utxo shape ======
Error: No token utxos for tokenId "b19b4c83056f6e3dace0e786446a8ccd73f22cfc42c3013808c532ab43490a14"
    at getSendTokenInputs (/work/cashtab/src/slpv1/index.js:147:15)
    at Object.<anonymous> (/work/cashtab/src/transactions/__tests__/index.test.js:157:54)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: We can create and broadcast SLP v1 SEND and BURN txs from utxos of nng or in-node chronik shape Build and broadcast an SLP V1 SEND tx and an SLP V1 BURN tx from NNG chronik-client utxos: SLP send and BURN with no token change, NNG utxo shape ======
Error: No token utxos for tokenId "b19b4c83056f6e3dace0e786446a8ccd73f22cfc42c3013808c532ab43490a14"
    at getSendTokenInputs (/work/cashtab/src/slpv1/index.js:147:15)
    at Object.<anonymous> (/work/cashtab/src/transactions/__tests__/index.test.js:157:54)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: We can create and broadcast SLP v1 SEND and BURN txs from utxos of nng or in-node chronik shape Build and broadcast an SLP V1 SEND tx and an SLP V1 BURN tx from NNG chronik-client utxos: SLP max send and max burn txs using all available input utxos ======
Error: No token utxos for tokenId "b19b4c83056f6e3dace0e786446a8ccd73f22cfc42c3013808c532ab43490a14"
    at getSendTokenInputs (/work/cashtab/src/slpv1/index.js:147:15)
    at Object.<anonymous> (/work/cashtab/src/transactions/__tests__/index.test.js:157:54)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: Cashtab chronik.js functions getTokenStats successfully returns a token stats object ======
Error: expect(received).toStrictEqual(expected) // deep equality

- Expected  - 4
+ Received  + 3

@@ -2,13 +2,12 @@
    "block": Object {
      "hash": "00000000000000000f305eafc05bffd14de4acf52787596b5927199c9cab37da",
      "height": 758409,
      "timestamp": "1663859004",
    },
-   "circulatingSupply": "20999996.944",
    "containsBaton": false,
-   "initialTokenQuantity": "21000000",
+   "initialTokenQuantity": "21000000000",
    "network": "XEC",
    "slpTxData": Object {
      "genesisInfo": Object {
        "decimals": 3,
        "tokenDocumentHash": "",
@@ -22,9 +21,9 @@
        "txType": "GENESIS",
      },
    },
    "timeFirstSeen": "1663858438",
    "tokenStats": Object {
-     "totalBurned": "3.056",
-     "totalMinted": "21000000",
+     "totalBurned": "3056",
+     "totalMinted": "21000000000",
    },
  }
    at Object.toStrictEqual (/work/cashtab/src/chronik/__tests__/index.test.js:68:55)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
====== CashTab Unit Tests: Cashtab chronik.js functions finalizeSlpUtxos successfully adds token quantity adjusted for token decimals to preliminarySlpUtxos ======
TypeError: Cannot read properties of undefined (reading 'tokenId')
    at tokenId (/work/cashtab/src/chronik/index.js:388:44)
    at Object.<anonymous> (/work/cashtab/src/chronik/__tests__/index.test.js:155:35)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <App /> If Cashtab starts with 1.5.* cashtabCache, it is wiped and migrated to 1.6.* cashtabCache ======
Error: expect(received).toEqual(expected) // deep equality

- Expected  - 2
+ Received  + 2

@@ -2,14 +2,14 @@
    "tokens": Array [
      Array [
        "3fee3384150b030490b7bee095a63900f66a45f2d8e3002ae2cf17ce3ef4d109",
        Object {
          "decimals": 0,
+         "hash": "",
          "success": true,
-         "tokenDocumentHash": "",
-         "tokenDocumentUrl": "https://cashtab.com/",
          "tokenName": "BearNip",
          "tokenTicker": "BEAR",
+         "url": "https://cashtab.com/",
        },
      ],
    ],
  }

Ignored nodes: comments, script, style
<html>
  <head />
  <body>
    <div
      class="ant-notification ant-notification-topRight css-dev-only-do-not-override-1rqnfsa ant-notification-stack ant-notification-stack-expanded"
      style="right: 0px; top: 24px;"
    >
      <div
        class="ant-notification-notice-wrapper"
        style="transform: translate3d(0, 0, 0);"
      >
        <div
          class="ant-notification-notice ant-notification-notice-success ant-notification-notice-closable"
        >
          <div
            class="ant-notification-notice-content"
          >
            <div
              class="ant-notification-notice-with-icon"
              role="alert"
            >
              <span
                class="ant-notification-notice-icon"
              >
                <div
                  class="ant-image css-dev-only-do-not-override-1rqnfsa"
                  style="width: 24px; height: 24px;"
                >
                  <img
                    class="ant-image-img css-dev-only-do-not-override-1rqnfsa"
                    height="24px"
                    src="test-file-stub"
                    style="height: 24px;"
                    width="24px"
                  />
                </div>
              </span>
              <div
                class="ant-notification-notice-message"
              >
                Success
              </div>
              <div
                class="ant-notification-notice-description"
              >
                <a
                  href="https://explorer.e.cash/tx/ce727c96439dfe365cb47f780c37ebb2e756051db62375e992419d5db3c81b1e"
                  rel="noopener noreferrer"
                  target="_blank"
                >
                  Transaction successful. Click to view in block explorer.
                </a>
              </div>
            </div>
          </div>
          <a
            class="ant-notification-notice-close"
            tabindex="0"
          >
            <span
              class="ant-notification-notice-close-x"
            >
              <span
                aria-label="close"
                class="anticon anticon-close ant-notification-notice-close-icon"
                role="img"
              >
                <svg
                  aria-hidden="true"
                  data-icon="close"
                  fill="currentColor"
                  fill-rule="evenodd"
                  focusable="false"
                  height="1em"
                  viewBox="64 64 896 896"
                  width="1em"
                >
                  <path
                    d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
                  />
                </svg>
              </span>
            </span>
          </a>
        </div>
      </div>
    </div>
    <div>
      <div
        class="ant-spin-nested-loading css-dev-only-do-not-override-1rqnfsa"
      >
        <div
          class="ant-spin-container"
        >
          <div
            class="sc-kZmsYB fQnjNb"
          >
            <div
              class="sc-iGPElx gCHnuu"
            >
              <div
                class="sc-kasBVs lhkNTc"
              >
                <div
                  class="sc-iSDuPN iRujPb"
                >
                  <div
                    class="sc-hgHYgh dHoKCw"
                  >
                    <img
                      alt="cashtab"
                      class="sc-eInJlc eaQkcG"
                      src="test-file-stub"
                    />
                  </div>
                  <div
                    class="sc-bYSBpT dbDmUC"
                    data-testid="wallet-info-ctn"
                  >
                    <div
                      class="sc-chbbiW htWHZo"
                    >
                      <div
                        class="sc-kxynE kQEGv"
                      >
                        Transaction Fixtures
                      </div>
                      <div>
                         
                        <button
                          aria-checked="true"
                          class="ant-switch ant-switch-small css-dev-only-do-not-override-1rqnfsa ant-switch-checked"
                          role="switch"
                          type="button"
                        >
                          <div
                            class="ant-switch-handle"
                          />
                          <span
                            class=...
    at toEqual (/work/cashtab/src/components/__tests__/App.test.js:752:63)

Each failure log is accessible here:
CashTab Unit Tests: We can create and broadcast SLP v1 SEND and BURN txs from utxos of nng or in-node chronik shape Build and broadcast an SLP V1 SEND tx and an SLP V1 BURN tx from NNG chronik-client utxos: SLP send and BURN with token change, NNG utxo shape
CashTab Unit Tests: We can create and broadcast SLP v1 SEND and BURN txs from utxos of nng or in-node chronik shape Build and broadcast an SLP V1 SEND tx and an SLP V1 BURN tx from NNG chronik-client utxos: SLP send and BURN with no token change, NNG utxo shape
CashTab Unit Tests: We can create and broadcast SLP v1 SEND and BURN txs from utxos of nng or in-node chronik shape Build and broadcast an SLP V1 SEND tx and an SLP V1 BURN tx from NNG chronik-client utxos: SLP max send and max burn txs using all available input utxos
CashTab Unit Tests: Cashtab chronik.js functions getTokenStats successfully returns a token stats object
CashTab Unit Tests: Cashtab chronik.js functions finalizeSlpUtxos successfully adds token quantity adjusted for token decimals to preliminarySlpUtxos
CashTab Unit Tests: <App /> If Cashtab starts with 1.5.* cashtabCache, it is wiped and migrated to 1.6.* cashtabCache

bytesofman edited the summary of this revision. (Show Details)

Tail of the build log:

Installing mock-chronik-client dependencies...
/work/modules/mock-chronik-client /work/abc-ci-builds/cashtab-tests

added 236 packages, and audited 237 packages in 2s

35 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
/work/cashtab /work/modules/mock-chronik-client /work/abc-ci-builds/cashtab-tests
npm WARN deprecated @babel/plugin-proposal-private-methods@7.18.6: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.
npm WARN deprecated @babel/plugin-proposal-numeric-separator@7.18.6: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.
npm WARN deprecated @babel/plugin-proposal-nullish-coalescing-operator@7.18.6: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.
npm WARN deprecated rollup-plugin-terser@7.0.2: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser
npm WARN deprecated @babel/plugin-proposal-class-properties@7.18.6: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
npm WARN deprecated @babel/plugin-proposal-private-property-in-object@7.21.11: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead.
npm WARN deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
npm WARN deprecated abab@2.0.6: Use your platform's native atob() and btoa() methods instead
npm WARN deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
npm WARN deprecated @babel/plugin-proposal-optional-chaining@7.21.0: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.
npm WARN deprecated domexception@4.0.0: Use your platform's native DOMException instead
npm WARN deprecated workbox-cacheable-response@6.6.0: workbox-background-sync@6.6.0

added 1722 packages, and audited 1723 packages in 23s

263 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

> cashtab@2.2.0 build
> node scripts/build.js

Creating an optimized production build...
Failed to compile.

[eslint] 
src/hooks/useWallet.js
  Line 21:5:  'finalizeSlpUtxos' is defined but never used  no-unused-vars

Search for the keywords to learn more about each error.


Build cashtab-tests failed with exit code 1
bytesofman edited the summary of this revision. (Show Details)

lint, match utxo shape of chronik-client in-node

tests failing again, more progress on proper ws implementation

Failed tests logs:

====== Mock Chronik Client: We can subscribe to and unsubscribe from scripts with the ws object ======
AssertionError: Expected values to be loosely deep-equal:  {   scripts: [] }  should loosely deep-equal  []
AssertionError [ERR_ASSERTION]: Expected values to be loosely deep-equal:

{
  scripts: []
}

should loosely deep-equal

[]
    at Context.<anonymous> (test/index.test.js:266:12)

      + expected - actual:  failed to generate Mocha diff

Each failure log is accessible here:
Mock Chronik Client: We can subscribe to and unsubscribe from scripts with the ws object

Failed tests logs:

====== CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices is null ======
Error: expect(received).toStrictEqual(expected) // deep equality

Expected: {"note": "alias-server is in beta and these prices are not finalized.", "prices": [{"fees": {"1": 558, "10": 551, "11": 551, "12": 551, "13": 551, "14": 551, "15": 551, "16": 551, "17": 551, "18": 551, "19": 551, "2": 557, "20": 551, "21": 551, "3": 556, "4": 555, "5": 554, "6": 553, "7": 552, "8": 551, "9": 551}, "startHeight": 823950}]}
Received: null
    at Object.toStrictEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:274:44)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices exists, server and cashtab prices array length do not match ======
Error: expect(received).toEqual(expected) // deep equality

- Expected  - 26
+ Received  +  0

@@ -25,33 +25,7 @@
          "8": 551,
          "9": 551,
        },
        "startHeight": 823944,
      },
-     Object {
-       "fees": Object {
-         "1": 558,
-         "10": 551,
-         "11": 551,
-         "12": 551,
-         "13": 551,
-         "14": 551,
-         "15": 551,
-         "16": 551,
-         "17": 551,
-         "18": 551,
-         "19": 551,
-         "2": 557,
-         "20": 551,
-         "21": 551,
-         "3": 556,
-         "4": 555,
-         "5": 554,
-         "6": 553,
-         "7": 552,
-         "8": 551,
-         "9": 551,
-       },
-       "startHeight": 823950,
-     },
    ],
  }
    at Object.toEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:399:44)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states Verify a processChronikWsMsg() new block event updates the `aliasServerError` state var upon a /prices/ endpoint error ======
Error: expect(received).toStrictEqual(expected) // deep equality

Expected: [Error: Invalid response from alias prices endpoint]
Received: false
    at Object.toStrictEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:588:49)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states An incoming tx message from the websocket causes the wallet to update ======
Error: expect(received).toBe(expected) // Object.is equality

Expected: true
Received: undefined
    at toBe (/work/cashtab/src/hooks/__tests__/useWallet.test.js:740:15)
====== CashTab Unit Tests: <App /> A new user can import a mnemonic ======
Error: Unable to find an element by: [data-testid="balance-xec"]

Ignored nodes: comments, script, style
<body>
  <div
    class="ant-notification ant-notification-topRight css-dev-only-do-not-override-1rqnfsa ant-notification-stack ant-notification-stack-expanded"
    style="right: 0px; top: 24px;"
  >
    <div
      class="ant-notification-notice-wrapper"
      style="transform: translate3d(0, 0, 0);"
    >
      <div
        class="ant-notification-notice ant-notification-notice-success ant-notification-notice-closable"
      >
        <div
          class="ant-notification-notice-content"
        >
          <div
            class="ant-notification-notice-with-icon"
            role="alert"
          >
            <span
              class="ant-notification-notice-icon"
            >
              <div
                class="ant-image css-dev-only-do-not-override-1rqnfsa"
                style="width: 24px; height: 24px;"
              >
                <img
                  class="ant-image-img css-dev-only-do-not-override-1rqnfsa"
                  height="24px"
                  src="test-file-stub"
                  style="height: 24px;"
                  width="24px"
                />
              </div>
            </span>
            <div
              class="ant-notification-notice-message"
            >
              Success
            </div>
            <div
              class="ant-notification-notice-description"
            >
              <a
                href="https://explorer.e.cash/tx/ce727c96439dfe365cb47f780c37ebb2e756051db62375e992419d5db3c81b1e"
                rel="noopener noreferrer"
                target="_blank"
              >
                Transaction successful. Click to view in block explorer.
              </a>
            </div>
          </div>
        </div>
        <a
          class="ant-notification-notice-close"
          tabindex="0"
        >
          <span
            class="ant-notification-notice-close-x"
          >
            <span
              aria-label="close"
              class="anticon anticon-close ant-notification-notice-close-icon"
              role="img"
            >
              <svg
                aria-hidden="true"
                data-icon="close"
                fill="currentColor"
                fill-rule="evenodd"
                focusable="false"
                height="1em"
                viewBox="64 64 896 896"
                width="1em"
              >
                <path
                  d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
                />
              </svg>
            </span>
          </span>
        </a>
      </div>
    </div>
  </div>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:815:29)

Each failure log is accessible here:
CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices is null
CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices exists, server and cashtab prices array length do not match
[[https://build.bitcoinabc.org/viewLog.html?tab=buildLog&logTab=tree&filter=debug&expand=all&buildId=719637&_focus=205331&guest=1 | CashTab Unit Tests: useWallet hook rendering in different localforage states Verify a processChronikWsMsg() new block event updates the aliasServerError state var upon a /prices/ endpoint error]]
CashTab Unit Tests: useWallet hook rendering in different localforage states An incoming tx message from the websocket causes the wallet to update
CashTab Unit Tests: <App /> A new user can import a mnemonic

Failed tests logs:

====== CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices is null ======
Error: expect(received).toStrictEqual(expected) // deep equality

Expected: {"note": "alias-server is in beta and these prices are not finalized.", "prices": [{"fees": {"1": 558, "10": 551, "11": 551, "12": 551, "13": 551, "14": 551, "15": 551, "16": 551, "17": 551, "18": 551, "19": 551, "2": 557, "20": 551, "21": 551, "3": 556, "4": 555, "5": 554, "6": 553, "7": 552, "8": 551, "9": 551}, "startHeight": 823950}]}
Received: null
    at Object.toStrictEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:274:44)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices exists, server and cashtab prices array length do not match ======
Error: expect(received).toEqual(expected) // deep equality

- Expected  - 26
+ Received  +  0

@@ -25,33 +25,7 @@
          "8": 551,
          "9": 551,
        },
        "startHeight": 823944,
      },
-     Object {
-       "fees": Object {
-         "1": 558,
-         "10": 551,
-         "11": 551,
-         "12": 551,
-         "13": 551,
-         "14": 551,
-         "15": 551,
-         "16": 551,
-         "17": 551,
-         "18": 551,
-         "19": 551,
-         "2": 557,
-         "20": 551,
-         "21": 551,
-         "3": 556,
-         "4": 555,
-         "5": 554,
-         "6": 553,
-         "7": 552,
-         "8": 551,
-         "9": 551,
-       },
-       "startHeight": 823950,
-     },
    ],
  }
    at Object.toEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:399:44)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states Verify a processChronikWsMsg() new block event updates the `aliasServerError` state var upon a /prices/ endpoint error ======
Error: expect(received).toStrictEqual(expected) // deep equality

Expected: [Error: Invalid response from alias prices endpoint]
Received: false
    at Object.toStrictEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:588:49)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states An incoming tx message from the websocket causes the wallet to update ======
Error: expect(received).toBe(expected) // Object.is equality

Expected: true
Received: undefined
    at toBe (/work/cashtab/src/hooks/__tests__/useWallet.test.js:740:15)
====== CashTab Unit Tests: <App /> A new user can import a mnemonic ======
Error: Unable to find an element by: [data-testid="balance-xec"]

Ignored nodes: comments, script, style
<body>
  <div
    class="ant-notification ant-notification-topRight css-dev-only-do-not-override-1rqnfsa ant-notification-stack ant-notification-stack-expanded"
    style="right: 0px; top: 24px;"
  >
    <div
      class="ant-notification-notice-wrapper"
      style="transform: translate3d(0, 0, 0);"
    >
      <div
        class="ant-notification-notice ant-notification-notice-success ant-notification-notice-closable"
      >
        <div
          class="ant-notification-notice-content"
        >
          <div
            class="ant-notification-notice-with-icon"
            role="alert"
          >
            <span
              class="ant-notification-notice-icon"
            >
              <div
                class="ant-image css-dev-only-do-not-override-1rqnfsa"
                style="width: 24px; height: 24px;"
              >
                <img
                  class="ant-image-img css-dev-only-do-not-override-1rqnfsa"
                  height="24px"
                  src="test-file-stub"
                  style="height: 24px;"
                  width="24px"
                />
              </div>
            </span>
            <div
              class="ant-notification-notice-message"
            >
              Success
            </div>
            <div
              class="ant-notification-notice-description"
            >
              <a
                href="https://explorer.e.cash/tx/ce727c96439dfe365cb47f780c37ebb2e756051db62375e992419d5db3c81b1e"
                rel="noopener noreferrer"
                target="_blank"
              >
                Transaction successful. Click to view in block explorer.
              </a>
            </div>
          </div>
        </div>
        <a
          class="ant-notification-notice-close"
          tabindex="0"
        >
          <span
            class="ant-notification-notice-close-x"
          >
            <span
              aria-label="close"
              class="anticon anticon-close ant-notification-notice-close-icon"
              role="img"
            >
              <svg
                aria-hidden="true"
                data-icon="close"
                fill="currentColor"
                fill-rule="evenodd"
                focusable="false"
                height="1em"
                viewBox="64 64 896 896"
                width="1em"
              >
                <path
                  d="M799.86 166.31c.02 0 .04.02.08.06l57.69 57.7c.04.03.05.05.06.08a.12.12 0 010 .06c0 .03-.02.05-.06.09L569.93 512l287.7 287.7c.04.04.05.06.06.09a.12.12 0 010 .07c0 .02-.02.04-.06.08l-57.7 57.69c-.03.04-.05.05-.07.06a.12.12 0 01-.07 0c-.03 0-.05-.02-.09-.06L512 569.93l-287.7 287.7c-.04.04-.06.05-.09.06a.12.12 0 01-.07 0c-.02 0-.04-.02-.08-.06l-57.69-57.7c-.04-.03-.05-.05-.06-.07a.12.12 0 010-.07c0-.03.02-.05.06-.09L454.07 512l-287.7-287.7c-.04-.04-.05-.06-.06-.09a.12.12 0 010-.07c0-.02.02-.04.06-.08l57.7-57.69c.03-.04.05-.05.07-.06a.12.12 0 01.07 0c.03 0 .05.02.09.06L512 454.07l287.7-287.7c.04-.04.06-.05.09-.06a.12.12 0 01.07 0z"
                />
              </svg>
            </span>
          </span>
        </a>
      </div>
    </div>
  </div>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:819:29)

Each failure log is accessible here:
CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices is null
CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices exists, server and cashtab prices array length do not match
[[https://build.bitcoinabc.org/viewLog.html?tab=buildLog&logTab=tree&filter=debug&expand=all&buildId=719895&_focus=208286&guest=1 | CashTab Unit Tests: useWallet hook rendering in different localforage states Verify a processChronikWsMsg() new block event updates the aliasServerError state var upon a /prices/ endpoint error]]
CashTab Unit Tests: useWallet hook rendering in different localforage states An incoming tx message from the websocket causes the wallet to update
CashTab Unit Tests: <App /> A new user can import a mnemonic

Failed tests logs:

====== CashTab Unit Tests: useWallet hook rendering in different localforage states XEC price is set in state on successful API fetch ======
Error: expect(received).toBe(expected) // Object.is equality

Expected: 0.00003
Received: null

Ignored nodes: comments, script, style
<html>
  <head />
  <body>
    <div />
  </body>
</html>
    at toBe (/work/cashtab/src/hooks/__tests__/useWallet.test.js:97:46)
    at runWithExpensiveErrorDiagnosticsDisabled (/work/cashtab/node_modules/@testing-library/dom/dist/config.js:47:12)
    at checkCallback (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:124:77)
    at checkRealTimersCallback (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:118:16)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states XEC price is set in state to fiat currency of user settings on successful API fetch ======
Error: expect(received).toBe(expected) // Object.is equality

Expected: 0.00003132
Received: null

Ignored nodes: comments, script, style
<html>
  <head />
  <body>
    <div />
  </body>
</html>
    at toBe (/work/cashtab/src/hooks/__tests__/useWallet.test.js:153:46)
    at runWithExpensiveErrorDiagnosticsDisabled (/work/cashtab/node_modules/@testing-library/dom/dist/config.js:47:12)
    at checkCallback (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:124:77)
    at checkRealTimersCallback (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:118:16)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states Cashtab loads wallet, settings, cache, and contactlist from localforage to context if they are present ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at /work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26769:9
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices is null ======
Error: expect(received).toStrictEqual(expected) // deep equality

Expected: {"note": "alias-server is in beta and these prices are not finalized.", "prices": [{"fees": {"1": 558, "10": 551, "11": 551, "12": 551, "13": 551, "14": 551, "15": 551, "16": 551, "17": 551, "18": 551, "19": 551, "2": 557, "20": 551, "21": 551, "3": 556, "4": 555, "5": 554, "6": 553, "7": 552, "8": 551, "9": 551}, "startHeight": 823950}]}
Received: null
    at Object.toStrictEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:274:44)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices exists, server and cashtab prices array length do not match ======
Error: expect(received).toEqual(expected) // deep equality

Expected: {"note": "alias-server is in beta and these prices are not finalized.", "prices": [{"fees": {"1": 558, "10": 9999999999999, "11": 551, "12": 551, "13": 551, "14": 551, "15": 551, "16": 551, "17": 551, "18": 551, "19": 551, "2": 557, "20": 551, "21": 551, "3": 556, "4": 555, "5": 554, "6": 553, "7": 552, "8": 551, "9": 551}, "startHeight": 823944}, {"fees": {"1": 558, "10": 551, "11": 551, "12": 551, "13": 551, "14": 551, "15": 551, "16": 551, "17": 551, "18": 551, "19": 551, "2": 557, "20": 551, "21": 551, "3": 556, "4": 555, "5": 554, "6": 553, "7": 552, "8": 551, "9": 551}, "startHeight": 823950}]}
Received: null
    at Object.toEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:399:44)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() does not refresh alias prices when aliasPrices exists, server and cashtab array length do match ======
Error: expect(received).toStrictEqual(expected) // deep equality

Expected: {"note": "alias-server is in beta and these prices are not finalized.", "prices": [{"fees": {"1": 558, "10": 9999999999999, "11": 551, "12": 551, "13": 551, "14": 551, "15": 551, "16": 551, "17": 551, "18": 551, "19": 551, "2": 557, "20": 551, "21": 551, "3": 556, "4": 555, "5": 554, "6": 553, "7": 552, "8": 551, "9": 551}, "startHeight": 111111}, {"fees": {"1": 558, "10": 551, "11": 551, "12": 551, "13": 551, "14": 551, "15": 551, "16": 551, "17": 551, "18": 551, "19": 551, "2": 557, "20": 551, "21": 551, "3": 556, "4": 555, "5": 554, "6": 553, "7": 552, "8": 551, "9": 551}, "startHeight": 823950}]}
Received: null
    at Object.toStrictEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:553:44)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states Verify a processChronikWsMsg() new block event updates the `aliasServerError` state var upon a /prices/ endpoint error ======
Error: expect(received).toStrictEqual(expected) // deep equality

Expected: [Error: Invalid response from alias prices endpoint]
Received: false
    at Object.toStrictEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:588:49)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states Verify refreshAliases() updates the `aliases` state variable on a successful /address/ endpoint response ======
Error: expect(received).toStrictEqual(expected) // deep equality

- Expected  - 14
+ Received  +  1

  Object {
    "pending": Array [],
-   "registered": Array [
-     Object {
-       "address": "ecash:qpmytrdsakt0axrrlswvaj069nat3p9s7cjctmjasj",
-       "alias": "jane",
-       "blockheight": 792418,
-       "txid": "0c77e4f7e0ff4f1028372042cbeb97eaddb64d505efe960b5a1ca4fce65598e2",
-     },
-     Object {
-       "address": "ecash:qpmytrdsakt0axrrlswvaj069nat3p9s7cjctmjasj",
-       "alias": "john",
-       "blockheight": 792417,
-       "txid": "ec92610fc41df2387e7febbb358b138a802ac26023f30b2442aa01ca733fff7d",
-     },
-   ],
+   "registered": Array [],
  }
    at Object.toStrictEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:641:40)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states Verify refreshAliases() updates the `aliasServerError` state variable upon an /address/ endpoint error ======
Error: expect(received).toStrictEqual(expected) // deep equality

Expected: "Error: Unable to retrieve aliases"
Received: false
    at Object.toStrictEqual (/work/cashtab/src/hooks/__tests__/useWallet.test.js:678:49)
====== CashTab Unit Tests: useWallet hook rendering in different localforage states An incoming tx message from the websocket causes the wallet to update ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at /work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26769:9
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <CreateTokenForm /> User can input valid token parameters, generate a token, and view a success notification ======
Error: Unable to find an element with the placeholder text of: Enter a name for your token

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByPlaceholderText (/work/cashtab/src/components/Etokens/__tests__/CreateTokenForm.test.js:104:26)
====== CashTab Unit Tests: <SignVerifyMsg /> Notification is rendered upon successfully signing a message ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at flushActQueue (/work/cashtab/node_modules/react/cjs/react.development.js:2667:24)
    at act (/work/cashtab/node_modules/react/cjs/react.development.js:2582:11)
    at /work/cashtab/node_modules/@testing-library/react/dist/act-compat.js:46:25
    at Object.eventWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:107:28)
    at Object.wrapEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/wrapEvent.js:6:28)
    at Object.dispatchEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:45:22)
    at Object.dispatchUIEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:22:26)
    at Mouse.up (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/pointer/mouse.js:100:30)
    at PointerHost.release (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/pointer/index.js:84:28)
    at pointerAction (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:59:47)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at processTimers (node:internal/timers:514:7)
    at Object.pointer (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:32:9)
    at Object.asyncWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:88:22)
    at Object.<anonymous> (/work/cashtab/src/components/SignVerifyMsg/__tests__/SignVerifyMsg.test.js:94:9)
====== CashTab Unit Tests: <SignVerifyMsg /> Notification is rendered upon successfully verifying a message ======
TestingLibraryElementError: Unable to find an element with the placeholder text of: XEC Address

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at Object.getElementError (/work/cashtab/node_modules/@testing-library/dom/dist/config.js:37:19)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:76:38
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:52:17
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:95:19
    at Object.getByPlaceholderText (/work/cashtab/src/components/SignVerifyMsg/__tests__/SignVerifyMsg.test.js:137:20)
====== CashTab Unit Tests: <SignVerifyMsg /> Notification is rendered upon signature verification error ======
TestingLibraryElementError: Unable to find an element with the placeholder text of: Enter message to verify

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at Object.getElementError (/work/cashtab/node_modules/@testing-library/dom/dist/config.js:37:19)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:76:38
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:52:17
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:95:19
    at Object.getByPlaceholderText (/work/cashtab/src/components/SignVerifyMsg/__tests__/SignVerifyMsg.test.js:178:20)
====== CashTab Unit Tests: <CreateToken /> If wallet has sufficient XEC, renders CreateTokenForm ======
Error: Unable to find an element with the text: Create a Token. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Etokens/__tests__/CreateToken.test.js:84:29)
====== CashTab Unit Tests: <CreateToken /> If wallet has insufficient XEC, renders component but does not render CreateTokenForm ======
Error: Unable to find an element with the text: You need at least 5.5 XEC ($0.0002 USD) to create a token. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Etokens/__tests__/CreateToken.test.js:113:26)
====== CashTab Unit Tests: <Configure /> We can add, delete, rename, contacts from the Configure screen, and add a savedWallet as a contact ======
Error: Unable to find an element by: [data-testid="contact-list-items"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Configure/__tests__/Configure.test.js:134:22)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <Configure /> We can rename the active wallet or a saved wallet, we can add a wallet, we can import a wallet, we can delete a wallet ======
Error: Unable to find an element with the text: alpha. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Configure/__tests__/Configure.test.js:348:29)
====== CashTab Unit Tests: <CashtabTestWrapper /> With default props, renders App component ======
Error: Unable to find an element with the text: 9,513.12 XEC. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/fixtures/__tests__/CashtabTestWrapper.test.js:91:29)
====== CashTab Unit Tests: <CashtabTestWrapper /> We can render other pages by passing the route ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <Receive /> Renders as expected on desktop, including copy paste functionality of clicking on the QR code ======
Error: Unable to find an element with the text: 9,513.12 XEC. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Receive/__tests__/Receive.test.js:109:29)
====== CashTab Unit Tests: <Receive /> Renders the Receive screen with QR code of expected width for smallest supported mobile view ======
Error: Unable to find an element by: [data-testid="receive-ctn"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/Receive/__tests__/Receive.test.js:168:29)
====== CashTab Unit Tests: <Receive /> Renders the Receive screen with QR code of size that is fully viewable in extension dimensions ======
Error: Unable to find an element by: [data-testid="receive-ctn"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/Receive/__tests__/Receive.test.js:217:29)
====== CashTab Unit Tests: <Home /> Renders the loading component while loading, then the Home screen ======
Error: Unable to find an element with the text: 9,513.12 XEC. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Home/__tests__/Home.test.js:99:29)
====== CashTab Unit Tests: <Home /> Renders the Home screen with API error ======
Error: Unable to find an element with the text: Error in chronik connection. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Home/__tests__/Home.test.js:122:26)
====== CashTab Unit Tests: <Home /> Renders backup warning and QR Code if user loads with a new wallet ======
Error: Unable to find an element with the text: Backup your wallet. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Home/__tests__/Home.test.js:139:22)
====== CashTab Unit Tests: <Alias /> Registered and Pending Aliases are correctly rendered ======
Error: Unable to find an element by: [data-testid="registered-aliases-list"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Alias/__tests__/Alias.test.js:119:22)
====== CashTab Unit Tests: <Alias /> Registered and Pending Aliases are correctly rendered when pending list is empty ======
Error: Unable to find an element by: [data-testid="registered-aliases-list"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Alias/__tests__/Alias.test.js:167:22)
====== CashTab Unit Tests: <Alias /> Registered and Pending Aliases are correctly rendered when registered list is empty ======
Error: Unable to find an element by: [data-testid="pending-aliases-list"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Alias/__tests__/Alias.test.js:220:22)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <Alias /> Registered and Pending lists still renders when aliasValidationError is populated and aliasServerError is false ======
Error: Unable to find an element by: [data-testid="registered-aliases-list"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Alias/__tests__/Alias.test.js:257:22)
====== CashTab Unit Tests: <Alias /> Registered and Pending lists do not render when aliasValidationError is false and aliasServerError is populated ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <SendXec /> Renders the SendXec screen with send address input ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <SendXec /> Pass valid address to Send To field ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at flushActQueue (/work/cashtab/node_modules/react/cjs/react.development.js:2667:24)
    at act (/work/cashtab/node_modules/react/cjs/react.development.js:2582:11)
    at /work/cashtab/node_modules/@testing-library/react/dist/act-compat.js:46:25
    at Object.eventWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:107:28)
    at Object.wrapEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/wrapEvent.js:6:28)
    at Object.focusElement (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/focus.js:24:19)
    at Mouse.down (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/pointer/mouse.js:81:19)
    at PointerHost.press (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/pointer/index.js:37:24)
    at pointerAction (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:56:43)
    at Object.pointer (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:32:15)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at processTimers (node:internal/timers:514:7)
    at Object.type (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/utility/type.js:18:9)
    at Object.asyncWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:88:22)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:142:9)
====== CashTab Unit Tests: <SendXec /> Pass valid alias to Send To field ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at flushActQueue (/work/cashtab/node_modules/react/cjs/react.development.js:2667:24)
    at act (/work/cashtab/node_modules/react/cjs/react.development.js:2582:11)
    at /work/cashtab/node_modules/@testing-library/react/dist/act-compat.js:46:25
    at Object.eventWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:107:28)
    at Object.wrapEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/wrapEvent.js:6:28)
    at Object.focusElement (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/focus.js:24:19)
    at Mouse.down (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/pointer/mouse.js:81:19)
    at PointerHost.press (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/pointer/index.js:37:24)
    at pointerAction (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:56:43)
    at Object.pointer (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:32:15)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at processTimers (node:internal/timers:514:7)
    at Object.type (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/utility/type.js:18:9)
    at Object.asyncWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:88:22)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:208:9)
====== CashTab Unit Tests: <SendXec /> Pass an invalid address to Send To field and get a validation error ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at flushActQueue (/work/cashtab/node_modules/react/cjs/react.development.js:2667:24)
    at act (/work/cashtab/node_modules/react/cjs/react.development.js:2582:11)
    at /work/cashtab/node_modules/@testing-library/react/dist/act-compat.js:46:25
    at Object.eventWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:107:28)
    at Object.wrapEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/wrapEvent.js:6:28)
    at Object.focusElement (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/focus.js:24:19)
    at Mouse.down (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/pointer/mouse.js:81:19)
    at PointerHost.press (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/pointer/index.js:37:24)
    at pointerAction (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:56:43)
    at Object.pointer (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:32:15)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at processTimers (node:internal/timers:514:7)
    at Object.type (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/utility/type.js:18:9)
    at Object.asyncWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:88:22)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:264:9)
====== CashTab Unit Tests: <SendXec /> Pass a possibly valid alias without .xec suffix to Send To field and get expected error ======
Error: expect(element).toHaveValue(aliasnosuffix)

Expected the element to have value:
  aliasnosuffix
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:308:32)
====== CashTab Unit Tests: <SendXec /> Pass a valid alias to Send To field that has not yet been registered and get expected error ======
Error: expect(element).toHaveValue(notregistered.xec)

Expected the element to have value:
  notregistered.xec
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:369:32)
====== CashTab Unit Tests: <SendXec /> Get expected error msg and send disabled if bad response from alias server ======
Error: expect(element).toHaveValue(servererror.xec)

Expected the element to have value:
  servererror.xec
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:425:32)
====== CashTab Unit Tests: <SendXec /> Pass a valid address and bip21 query string with valid amount param to Send To field ======
Error: expect(element).toHaveValue(ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=500)

Expected the element to have value:
  ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=500
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:471:32)
====== CashTab Unit Tests: <SendXec /> Pass a valid alias and bip21 query string with valid amount param to Send To field ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at flushActQueue (/work/cashtab/node_modules/react/cjs/react.development.js:2667:24)
    at act (/work/cashtab/node_modules/react/cjs/react.development.js:2582:11)
    at /work/cashtab/node_modules/@testing-library/react/dist/act-compat.js:46:25
    at Object.eventWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:107:28)
    at Object.wrapEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/wrapEvent.js:6:28)
    at Object.dispatchEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:45:22)
    at Object.dispatchUIEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:22:26)
    at commitInput (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/input.js:150:14)
    at editInputElement (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/input.js:120:9)
    at Object.input (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/input.js:42:9)
    at /work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/behavior/keypress.js:36:26
    at Object.dispatchEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:41:13)
    at Object.dispatchUIEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:22:26)
    at KeyboardHost.keydown (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/keyboard.js:86:22)
    at keyboardAction (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/keyboard/index.js:28:35)
    at Object.keyboard (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/keyboard/index.js:17:15)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at processTimers (node:internal/timers:514:7)
    at Object.type (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/utility/type.js:23:5)
    at Object.asyncWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:88:22)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:536:9)
====== CashTab Unit Tests: <SendXec /> Pass a valid address and bip21 query string with invalid amount param (dust) to Send To field ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at flushActQueue (/work/cashtab/node_modules/react/cjs/react.development.js:2667:24)
    at act (/work/cashtab/node_modules/react/cjs/react.development.js:2582:11)
    at /work/cashtab/node_modules/@testing-library/react/dist/act-compat.js:46:25
    at Object.eventWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:107:28)
    at Object.wrapEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/wrapEvent.js:6:28)
    at Object.dispatchEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:45:22)
    at Object.dispatchUIEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:22:26)
    at commitInput (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/input.js:150:14)
    at editInputElement (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/input.js:120:9)
    at Object.input (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/input.js:42:9)
    at /work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/behavior/keypress.js:36:26
    at Object.dispatchEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:41:13)
    at Object.dispatchUIEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:22:26)
    at KeyboardHost.keydown (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/keyboard.js:86:22)
    at keyboardAction (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/keyboard/index.js:28:35)
    at Object.keyboard (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/keyboard/index.js:17:15)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at processTimers (node:internal/timers:514:7)
    at Object.type (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/utility/type.js:23:5)
    at Object.asyncWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:88:22)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:595:9)
====== CashTab Unit Tests: <SendXec /> Valid address with valid bip21 query string with valid amount param rejected if amount exceeds wallet balance ======
Error: expect(element).toHaveValue(ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=1000000)

Expected the element to have value:
  ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=1000000
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:644:32)
====== CashTab Unit Tests: <SendXec /> Pass a valid alias and bip21 query string with invalid amount param (too many decimals) to Send To field ======
Error: expect(element).toHaveValue(chicken.xec?amount=500.123)

Expected the element to have value:
  chicken.xec?amount=500.123
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:713:32)
====== CashTab Unit Tests: <SendXec /> Pass a valid address and an invalid bip21 query string ======
Error: expect(element).toHaveValue(ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?notaparam=500)

Expected the element to have value:
  ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?notaparam=500
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:771:32)
====== CashTab Unit Tests: <SendXec /> Pass a valid address and bip21 query string with op_return_raw param to Send To field ======
Error: expect(element).toHaveValue(ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?op_return_raw=0401020304)

Expected the element to have value:
  ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?op_return_raw=0401020304
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:820:32)
====== CashTab Unit Tests: <SendXec /> Pass a valid address and bip21 query string with valid amount and op_return_raw params to Send To field ======
Error: expect(element).toHaveValue(ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=500&op_return_raw=0401020304)

Expected the element to have value:
  ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=500&op_return_raw=0401020304
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:877:32)
====== CashTab Unit Tests: <SendXec /> Pass a valid address and bip21 query string with valid amount and invalid op_return_raw params to Send To field ======
Error: expect(element).toHaveValue(ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=500&op_return_raw=notahexstring)

Expected the element to have value:
  ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=500&op_return_raw=notahexstring
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:934:32)
====== CashTab Unit Tests: <SendXec /> Clicking "Send" will send a valid tx with op_return_raw after entry of a valid address and bip21 query string with valid amount and op_return_raw params to Send To field ======
Error: expect(element).toHaveValue(ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=17&op_return_raw=04007461622263617368746162206D6573736167652077697468206F705F72657475726E5F726177)

Expected the element to have value:
  ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=17&op_return_raw=04007461622263617368746162206D6573736167652077697468206F705F72657475726E5F726177
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:1000:32)
====== CashTab Unit Tests: <SendXec /> We can calculate max send amount with and without a cashtab msg, and send a max sat tx with a cashtab msg ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at flushActQueue (/work/cashtab/node_modules/react/cjs/react.development.js:2667:24)
    at act (/work/cashtab/node_modules/react/cjs/react.development.js:2582:11)
    at /work/cashtab/node_modules/@testing-library/react/dist/act-compat.js:46:25
    at Object.eventWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:107:28)
    at Object.wrapEvent (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/wrapEvent.js:6:28)
    at Object.focusElement (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/event/focus.js:24:19)
    at Mouse.down (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/pointer/mouse.js:81:19)
    at PointerHost.press (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/system/pointer/index.js:37:24)
    at pointerAction (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:56:43)
    at Object.pointer (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:32:15)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:540:9)
    at processTimers (node:internal/timers:514:7)
    at Object.type (/work/cashtab/node_modules/@testing-library/user-event/dist/cjs/utility/type.js:18:9)
    at Object.asyncWrapper (/work/cashtab/node_modules/@testing-library/react/dist/pure.js:88:22)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:1110:9)
====== CashTab Unit Tests: <SendXec /> If the user has minFeeSends set to true but no longer has the right token amount, the feature is disabled ======
Error: expect(element).toHaveValue(ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=17&op_return_raw=04007461622263617368746162206D6573736167652077697468206F705F72657475726E5F726177)

Expected the element to have value:
  ecash:qp89xgjhcqdnzzemts0aj378nfe2mhu9yvxj9nhgg6?amount=17&op_return_raw=04007461622263617368746162206D6573736167652077697468206F705F72657475726E5F726177
Received:

    at Object.toHaveValue (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:1204:32)
====== CashTab Unit Tests: <SendXec /> We can send a tx with amount denominated in fiat currency ======
TestingLibraryElementError: Unable to find an element by: [data-testid="currency-select-dropdown"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at Object.getElementError (/work/cashtab/node_modules/@testing-library/dom/dist/config.js:37:19)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:76:38
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:52:17
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:95:19
    at Object.getByTestId (/work/cashtab/src/components/Send/__tests__/SendXec.test.js:1318:20)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid. ======
Error: Unable to find an element with the text: 9,513.12 XEC. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:127:29)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid. Invalid bip21 string is ignored. ======
Error: Unable to find an element with the text: 9,513.12 XEC. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:164:29)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and value present as undefined ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and no value key present ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Params are ignored if only value param is present ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Params are ignored if param is duplicated ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params are not parsed as bip21 even if the bip21 param appears in the string ======
Error: Unable to find an element with the text: 9,513.12 XEC. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:448:29)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 param with amount and op_return_raw is parsed as expected ======
Error: Unable to find an element with the text: 9,513.12 XEC. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:513:29)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - an invalid bip21 param shows validation errors but cannot be changed ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL No params. Send screen loads normally with no rendered input. ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <SendToken /> Renders the SendToken screen with send address input ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:136:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <SendToken /> Accepts a valid ecash: prefixed address ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:169:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <SendToken /> Accepts a valid etoken: prefixed address ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:200:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <SendToken /> Accepts a valid alias ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:232:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <SendToken /> Displays a validation error for an invalid address ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:292:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <SendToken /> Displays a validation error for an alias without .xec suffix ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:317:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <SendToken /> Displays a validation error for valid alias that has not yet been registered ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:344:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <SendToken /> Displays expected error if alias server gives a bad response ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:391:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <SendToken /> Displays a validation error if the user includes any query string ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:431:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <SendToken /> Renders the send token notification upon successful broadcast ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:469:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <SendToken /> Renders the burn token success notification upon successful burn tx broadcast ======
Error: Unable to find an element with the text: BEAR. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at Object.<anonymous> (/work/cashtab/src/components/Send/__tests__/SendToken.test.js:513:22)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <App /> Navigation menu routes to expected components ======
Error: Unable to find an element by: [data-testid="home-ctn"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:118:22)
====== CashTab Unit Tests: <App /> Adding a contact to to a new contactList by clicking on tx history adds it to localforage and wallet context ======
Error: Unable to find an element by: [data-testid="home-ctn"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:196:22)
====== CashTab Unit Tests: <App /> Adding a contact to an existing contactList by clicking on tx history adds it to localforage and wallet context ======
Error: Unable to find an element by: [data-testid="home-ctn"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:259:22)
====== CashTab Unit Tests: <App /> A user with legacy blank contactList in localstorage is migrated on startup ======
Error: Unable to find an element by: [data-testid="wallet-info-ctn"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:315:26)
====== CashTab Unit Tests: <App /> Clicking "reply" on a Cashtab Msg correctly populates the SendXec to address and amount fields ======
Error: Unable to find an element by: [data-testid="wallet-info-ctn"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:335:26)
====== CashTab Unit Tests: <App /> We do not see the camera auto-open setting in the config screen on a desktop device ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <App /> We do see the camera auto-open setting in the config screen on a mobile device ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <App /> Setting "Send Confirmations" settings will show send confirmations ======
Error: Unable to find an element by: [data-testid="home-ctn"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:440:22)
====== CashTab Unit Tests: <App /> If Cashtab starts up with some settings keys missing, the missing keys are migrated to default values ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <App /> Setting "ABSOLUTE MINIMUM fees" settings will reduce fees to absolute min ======
Error: Unable to find an element by: [data-testid="home-ctn"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:585:22)
====== CashTab Unit Tests: <App /> Wallet with easter egg token sees easter egg ======
Error: Unable to find an element with the alt text: tabcash

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByAltText (/work/cashtab/src/components/__tests__/App.test.js:719:29)
====== CashTab Unit Tests: <App /> If Cashtab starts with 1.5.* cashtabCache, it is wiped and migrated to 1.6.* cashtabCache ======
TypeError: scripts is not iterable
    at scripts (/work/cashtab/src/hooks/useWallet.js:475:30)
    at updateWebsocket (/work/cashtab/src/hooks/useWallet.js:795:9)
    at commitHookEffectListMount (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
    at commitPassiveMountEffects_complete (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
    at commitPassiveMountEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
    at flushPassiveEffects (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
    at performSyncWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26076:3)
    at flushSyncCallbacks (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
    at commitRootImpl (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26959:3)
    at commitRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:26682:5)
    at finishConcurrentRender (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25981:9)
    at performConcurrentWorkOnRoot (/work/cashtab/node_modules/react-dom/cjs/react-dom.development.js:25809:7)
    at workLoop (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at performWorkUntilDeadline (/work/cashtab/node_modules/scheduler/cjs/scheduler.development.js:533:21)
    at Timeout.task [as _onTimeout] (/work/cashtab/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
    at listOnTimeout (node:internal/timers:573:17)
    at processTimers (node:internal/timers:514:7)
====== CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup ======
Error: Unable to find an element by: [data-testid="balance-xec"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:861:29)
====== CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with pre-2.1.0 valid wallets in savedWallets has them all migrated to new storage keys and new shape ======
Error: Unable to find an element by: [data-testid="balance-xec"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:892:29)
====== CashTab Unit Tests: <App /> Migrating (version >= 1.6.0 and < 2.1.0): A user with an invalid wallet stored at wallets key has that wallet migrated ======
Error: Unable to find an element by: [data-testid="balance-xec"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:923:29)
====== CashTab Unit Tests: <App /> Migrating (version >= 1.6.0 and < 2.1.0): A user with multiple invalid wallets in savedWallets has them migrated ======
Error: Unable to find an element by: [data-testid="balance-xec"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:958:29)
====== CashTab Unit Tests: <App /> Cashtab version >= 1.6.0 and < 2.1.0: A user with an invalid Cashtab wallet as the active wallet is migrated on startup ======
Error: Unable to find an element by: [data-testid="balance-xec"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:981:29)
====== CashTab Unit Tests: <App /> A user with all valid wallets in savedWallets does not have any savedWallets migrated ======
Error: Unable to find an element by: [data-testid="balance-xec"]

Ignored nodes: comments, script, style
<body>
  <div />
</body>
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByTestId (/work/cashtab/src/components/__tests__/App.test.js:1001:29)

Each failure log is accessible here:
CashTab Unit Tests: useWallet hook rendering in different localforage states XEC price is set in state on successful API fetch
CashTab Unit Tests: useWallet hook rendering in different localforage states XEC price is set in state to fiat currency of user settings on successful API fetch
CashTab Unit Tests: useWallet hook rendering in different localforage states Cashtab loads wallet, settings, cache, and contactlist from localforage to context if they are present
CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices is null
CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() refreshes alias prices when aliasPrices exists, server and cashtab prices array length do not match
CashTab Unit Tests: useWallet hook rendering in different localforage states processChronikWsMsg() does not refresh alias prices when aliasPrices exists, server and cashtab array length do match
[[https://build.bitcoinabc.org/viewLog.html?tab=buildLog&logTab=tree&filter=debug&expand=all&buildId=719943&_focus=57381&guest=1 | CashTab Unit Tests: useWallet hook rendering in different localforage states Verify a processChronikWsMsg() new block event updates the aliasServerError state var upon a /prices/ endpoint error]]
[[https://build.bitcoinabc.org/viewLog.html?tab=buildLog&logTab=tree&filter=debug&expand=all&buildId=719943&_focus=57384&guest=1 | CashTab Unit Tests: useWallet hook rendering in different localforage states Verify refreshAliases() updates the aliases state variable on a successful /address/ endpoint response]]
[[https://build.bitcoinabc.org/viewLog.html?tab=buildLog&logTab=tree&filter=debug&expand=all&buildId=719943&_focus=57387&guest=1 | CashTab Unit Tests: useWallet hook rendering in different localforage states Verify refreshAliases() updates the aliasServerError state variable upon an /address/ endpoint error]]
CashTab Unit Tests: useWallet hook rendering in different localforage states An incoming tx message from the websocket causes the wallet to update
CashTab Unit Tests: <CreateTokenForm /> User can input valid token parameters, generate a token, and view a success notification
CashTab Unit Tests: <SignVerifyMsg /> Notification is rendered upon successfully signing a message
CashTab Unit Tests: <SignVerifyMsg /> Notification is rendered upon successfully verifying a message
CashTab Unit Tests: <SignVerifyMsg /> Notification is rendered upon signature verification error
CashTab Unit Tests: <CreateToken /> If wallet has sufficient XEC, renders CreateTokenForm
CashTab Unit Tests: <CreateToken /> If wallet has insufficient XEC, renders component but does not render CreateTokenForm
CashTab Unit Tests: <Configure /> We can add, delete, rename, contacts from the Configure screen, and add a savedWallet as a contact
CashTab Unit Tests: <Configure /> We can rename the active wallet or a saved wallet, we can add a wallet, we can import a wallet, we can delete a wallet
CashTab Unit Tests: <CashtabTestWrapper /> With default props, renders App component
CashTab Unit Tests: <CashtabTestWrapper /> We can render other pages by passing the route
CashTab Unit Tests: <Receive /> Renders as expected on desktop, including copy paste functionality of clicking on the QR code
CashTab Unit Tests: <Receive /> Renders the Receive screen with QR code of expected width for smallest supported mobile view
CashTab Unit Tests: <Receive /> Renders the Receive screen with QR code of size that is fully viewable in extension dimensions
CashTab Unit Tests: <Home /> Renders the loading component while loading, then the Home screen
CashTab Unit Tests: <Home /> Renders the Home screen with API error
CashTab Unit Tests: <Home /> Renders backup warning and QR Code if user loads with a new wallet
CashTab Unit Tests: <Alias /> Registered and Pending Aliases are correctly rendered
CashTab Unit Tests: <Alias /> Registered and Pending Aliases are correctly rendered when pending list is empty
CashTab Unit Tests: <Alias /> Registered and Pending Aliases are correctly rendered when registered list is empty
CashTab Unit Tests: <Alias /> Registered and Pending lists still renders when aliasValidationError is populated and aliasServerError is false
CashTab Unit Tests: <Alias /> Registered and Pending lists do not render when aliasValidationError is false and aliasServerError is populated
CashTab Unit Tests: <SendXec /> Renders the SendXec screen with send address input
CashTab Unit Tests: <SendXec /> Pass valid address to Send To field
CashTab Unit Tests: <SendXec /> Pass valid alias to Send To field
CashTab Unit Tests: <SendXec /> Pass an invalid address to Send To field and get a validation error
CashTab Unit Tests: <SendXec /> Pass a possibly valid alias without .xec suffix to Send To field and get expected error
CashTab Unit Tests: <SendXec /> Pass a valid alias to Send To field that has not yet been registered and get expected error
CashTab Unit Tests: <SendXec /> Get expected error msg and send disabled if bad response from alias server
CashTab Unit Tests: <SendXec /> Pass a valid address and bip21 query string with valid amount param to Send To field
CashTab Unit Tests: <SendXec /> Pass a valid alias and bip21 query string with valid amount param to Send To field
CashTab Unit Tests: <SendXec /> Pass a valid address and bip21 query string with invalid amount param (dust) to Send To field
CashTab Unit Tests: <SendXec /> Valid address with valid bip21 query string with valid amount param rejected if amount exceeds wallet balance
CashTab Unit Tests: <SendXec /> Pass a valid alias and bip21 query string with invalid amount param (too many decimals) to Send To field
CashTab Unit Tests: <SendXec /> Pass a valid address and an invalid bip21 query string
CashTab Unit Tests: <SendXec /> Pass a valid address and bip21 query string with op_return_raw param to Send To field
CashTab Unit Tests: <SendXec /> Pass a valid address and bip21 query string with valid amount and op_return_raw params to Send To field
CashTab Unit Tests: <SendXec /> Pass a valid address and bip21 query string with valid amount and invalid op_return_raw params to Send To field
CashTab Unit Tests: <SendXec /> Clicking "Send" will send a valid tx with op_return_raw after entry of a valid address and bip21 query string with valid amount and op_return_raw params to Send To field
CashTab Unit Tests: <SendXec /> We can calculate max send amount with and without a cashtab msg, and send a max sat tx with a cashtab msg
CashTab Unit Tests: <SendXec /> If the user has minFeeSends set to true but no longer has the right token amount, the feature is disabled
CashTab Unit Tests: <SendXec /> We can send a tx with amount denominated in fiat currency
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid.
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid. Invalid bip21 string is ignored.
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and value present as undefined
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and no value key present
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Params are ignored if only value param is present
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Params are ignored if param is duplicated
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params are not parsed as bip21 even if the bip21 param appears in the string
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 param with amount and op_return_raw is parsed as expected
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - an invalid bip21 param shows validation errors but cannot be changed
CashTab Unit Tests: <SendXec /> rendered with params in URL No params. Send screen loads normally with no rendered input.
CashTab Unit Tests: <SendToken /> Renders the SendToken screen with send address input
CashTab Unit Tests: <SendToken /> Accepts a valid ecash: prefixed address
CashTab Unit Tests: <SendToken /> Accepts a valid etoken: prefixed address
CashTab Unit Tests: <SendToken /> Accepts a valid alias
CashTab Unit Tests: <SendToken /> Displays a validation error for an invalid address
CashTab Unit Tests: <SendToken /> Displays a validation error for an alias without .xec suffix
CashTab Unit Tests: <SendToken /> Displays a validation error for valid alias that has not yet been registered
CashTab Unit Tests: <SendToken /> Displays expected error if alias server gives a bad response
CashTab Unit Tests: <SendToken /> Displays a validation error if the user includes any query string
CashTab Unit Tests: <SendToken /> Renders the send token notification upon successful broadcast
CashTab Unit Tests: <SendToken /> Renders the burn token success notification upon successful burn tx broadcast
CashTab Unit Tests: <App /> Navigation menu routes to expected components
CashTab Unit Tests: <App /> Adding a contact to to a new contactList by clicking on tx history adds it to localforage and wallet context
CashTab Unit Tests: <App /> Adding a contact to an existing contactList by clicking on tx history adds it to localforage and wallet context
CashTab Unit Tests: <App /> A user with legacy blank contactList in localstorage is migrated on startup
CashTab Unit Tests: <App /> Clicking "reply" on a Cashtab Msg correctly populates the SendXec to address and amount fields
CashTab Unit Tests: <App /> We do not see the camera auto-open setting in the config screen on a desktop device
CashTab Unit Tests: <App /> We do see the camera auto-open setting in the config screen on a mobile device
CashTab Unit Tests: <App /> Setting "Send Confirmations" settings will show send confirmations
CashTab Unit Tests: <App /> If Cashtab starts up with some settings keys missing, the missing keys are migrated to default values
CashTab Unit Tests: <App /> Setting "ABSOLUTE MINIMUM fees" settings will reduce fees to absolute min
CashTab Unit Tests: <App /> Wallet with easter egg token sees easter egg
CashTab Unit Tests: <App /> If Cashtab starts with 1.5.* cashtabCache, it is wiped and migrated to 1.6.* cashtabCache
CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup
CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with pre-2.1.0 valid wallets in savedWallets has them all migrated to new storage keys and new shape
CashTab Unit Tests: <App /> Migrating (version >= 1.6.0 and < 2.1.0): A user with an invalid wallet stored at wallets key has that wallet migrated
CashTab Unit Tests: <App /> Migrating (version >= 1.6.0 and < 2.1.0): A user with multiple invalid wallets in savedWallets has them migrated
CashTab Unit Tests: <App /> Cashtab version >= 1.6.0 and < 2.1.0: A user with an invalid Cashtab wallet as the active wallet is migrated on startup
CashTab Unit Tests: <App /> A user with all valid wallets in savedWallets does not have any savedWallets migrated

bytesofman added inline comments.
cashtab/src/chronik/index.js
410 ↗(On Diff #46190)

token decimals is now cached and passed as a param to token tx building functions

439 ↗(On Diff #46190)

This is an incomplete refactor to match current Cashtab behavior for tx parsing (i.e. we only support slpv1 txs)

Will iterate on this to support other token types in later diffs

cashtab/src/components/Send/SendToken.js
733 ↗(On Diff #46190)

this info is not yet available from in-node endpoints. can be fetched with some manual workarounds. imo it is not high priority enough to block this migration and can be added later. The way we handle token info caching needs to be improved in other ways before this is supported anyway.

cashtab/src/config/chronik.js
9 ↗(On Diff #46193)

we may change this before landing, current interation of chronik-native.fabien.cash has slow websocket timings. the test prod version at netlify is using pay2stay

note that you get the usual cashtab "instant" txs best when you send and receive from the same chronik instance, so you may want to open cashtab at the netlify url in 2 different browsers to test

cashtab/src/slpv1/__tests__/index.test.js
265 ↗(On Diff #46190)

no need to support nng utxos ever again

modules/mock-chronik-client/index.js
108 ↗(On Diff #46193)

the mock-chronik-client changes are isolated in D15697

Will land that and rebase here before landing, they are not material to this diff review

rebase, move slower API to backup spot

Failed tests logs:

====== CashTab Unit Tests: <CreateToken /> If wallet has insufficient XEC, renders component but does not render CreateTokenForm ======
Error: Unable to find an element with the text: You need at least 5.5 XEC ($0.0002 USD) to create a token. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div>
    <div
      class="ant-spin-nested-loading css-dev-only-do-not-override-1rqnfsa"
    >
      <div
        class="ant-spin-container"
      >
        <div
          class="sc-kZmsYB fQnjNb"
        >
          <div
            class="sc-iGPElx gCHnuu"
          >
            <div
              class="sc-kasBVs lhkNTc"
            >
              <div
                class="sc-iSDuPN iRujPb"
              >
                <div
                  class="sc-hgHYgh dHoKCw"
                >
                  <img
                    alt="cashtab"
                    class="sc-eInJlc eaQkcG"
                    src="test-file-stub"
                  />
                </div>
                <div
                  class="sc-bYSBpT dbDmUC"
                  data-testid="wallet-info-ctn"
                >
                  <div
                    class="sc-chbbiW htWHZo"
                  >
                    <div
                      class="sc-kxynE kQEGv"
                    >
                      Transaction Fixtures
                    </div>
                    <div>
                       
                      <button
                        aria-checked="true"
                        class="ant-switch ant-switch-small css-dev-only-do-not-override-1rqnfsa ant-switch-checked"
                        role="switch"
                        type="button"
                      >
                        <div
                          class="ant-switch-handle"
                        />
                        <span
                          class="ant-switch-inner"
                        >
                          <span
                            class="ant-switch-inner-checked"
                          >
                            <svg
                              class="sc-cSHVUG bgwEHu"
                            />
                          </span>
                          <span
                            class="ant-switch-inner-unchecked"
                          >
                            <svg
                              class="sc-kAzzGY fUTkYj"
                            />
                          </span>
                        </span>
                      </button>
                    </div>
                  </div>
                  <div
                    class="sc-cooIXK Gxkby"
                    data-testid="balance-xec"
                  >
                    9,513.12
                     
                    XEC
                     
                  </div>
                  <div
                    class="sc-fcdeBU eNHrWm"
                    data-testid="balance-fiat"
                  >
                    $
                    0.29
                     
                    USD
                  </div>
                  <p
                    class="sc-gmeYpB ddoKuI"
                    data-testid="ecash-price"
                  >
                    1 
                    XEC
                     = 
                    0.00003000
                     
                    USD
                  </p>
                </div>
              </div>
              <div
                class="sc-btzYZH hekFVg"
              >
                <div
                  class="sc-bsbRJL gLPXlJ"
                >
                  <h3>
                    Create a Token
                  </h3>
                  <div
                    class="sc-cvbbAY kdxSAu"
                  >
                    <form
                      class="ant-form ant-form-horizontal ant-form-small css-dev-only-do-not-override-1rqnfsa"
                      style="width: auto;"
                    >
                      <label
                        class="sc-lhVmIH ffziWj"
                      >
                        Token Name
                      </label>
                      <div
                        class="ant-form-item css-dev-only-do-not-override-1rqnfsa ant-form-item-with-help"
                      >
                        <div
                          class="ant-row ant-form-item-row css-dev-only-do-not-override-1rqnfsa"
                        >
                          <div
                            class="ant-col ant-form-item-control css-dev-only-do-not-override-1rqnfsa"
                          >
                            <div
                              class="ant-form-item-control-input"
                            >
                              <div
                                class="ant-form-item-control-input-content"
                              >
                                <input
                                  class="ant-input ant-input-sm css-dev-only-do-not-override-1rqnfsa ant-input-outlined"
                                  name="newTokenName"
                                  placeholder="Enter a name for your token"
                                  type="text"
                                  value=""
                                />
                              </div>
                            </div>
      ...
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/Etokens/__tests__/CreateToken.test.js:113:26)

Each failure log is accessible here:
CashTab Unit Tests: <CreateToken /> If wallet has insufficient XEC, renders component but does not render CreateTokenForm

price api impact need to change this test

patch flaky fiat price test

emack requested changes to this revision.Mar 15 2024, 10:46
emack added a subscriber: emack.

Edge case: Send a token tx where you're sending the entire remaining token balance so that it needs to automatically route out of the SendToken.js and back to Home. The following bad state use warning is shown:

image.png (337×354 px, 48 KB)

cashtab/src/chronik/index.js
89 ↗(On Diff #46206)

why is this still using the old script endpoint instead of in-node's address().utxos()?

848 ↗(On Diff #46206)

Isn't one of the benefits of ALP is that it can handle more than 1 token tx types in the same tx? In either case I checked https://docs.chronik.xyz/docs/chronik-js/txs and it's not obvious that tokenEntries will always have exactly 1 element.

cashtab/src/components/Home/Tx.js
491 ↗(On Diff #46206)

subject to the tokenEntries[0] comment above

cashtab/src/components/Send/SendToken.js
738–746 ↗(On Diff #46206)

I would've thought it'd be relatively straightforward to supply these via in-node chronik, but I guess not for this diff's scope. Once we start the NFT work we'll need things like initial quantity.

cashtab/src/hooks/useWallet.js
420 ↗(On Diff #46206)

Why is this the case? To my knowledge Cashtab doesn't have any functions sitting there waiting for a new block to be found.

This revision now requires changes to proceed.Mar 15 2024, 10:46

Edge case: Send a token tx where you're sending the entire remaining token balance so that it needs to automatically route out of the SendToken.js and back to Home. The following bad state use warning is shown:

will check this out

bytesofman added inline comments.
cashtab/src/chronik/index.js
89 ↗(On Diff #46206)

will be a bigger refactor to move all of this over, since the getHashArray function in Cashtab is all over the place. Should be handled separately imo, this diff is designed to move to in-node chronik while changing as little as possible

T3461

848 ↗(On Diff #46206)

Yes, this function needs extended refactoring. For now, this refactor supports only slpv1.

this "should" be handled as for now we have

let isEtokenTx = isSlpV1; -- and slpv1 txs should only have 1 token entry. but, it could use some sample alp txs to confirm they are simply not parsed, as expected.

going forward, of course we will parse all of them. but imo that should happen after the migration.

i'll add some tests to confirm expected behavior with non slpv1 txs.

cashtab/src/components/Home/Tx.js
491 ↗(On Diff #46206)

same answer as above. will add some tests.

will get ALP support in soon but imo that is a separate scope from the migration.

cashtab/src/components/Send/SendToken.js
738–746 ↗(On Diff #46206)

we are missing endpoints for things like total burned.

However, we can get things like initial quantity and whether or not it was a fixed supply token on mint in a relatively straightforward way.

the main reason I am choosing not to do so here is because we need a bigger refactor in how token data is cached and managed by Cashtab, and imo that is where it should happen -- after the migration.

T3461

cashtab/src/hooks/useWallet.js
420 ↗(On Diff #46206)

lol you wrote them man!

they handle alias registrations

nng chronik always subscribes to blocks when you subscribe to a script

with in-node, you need to do it explicitly

so -- this is maintaining existing behavior.

518 ↗(On Diff #46206)

here's an example of using the block subscription -- these are tested in useWallet.test.js

bytesofman marked 3 inline comments as done.

Edge case: Send a token tx where you're sending the entire remaining token balance so that it needs to automatically route out of the SendToken.js and back to Home. The following bad state use warning is shown:

will check this out

I think this related to the useNavigate, which should be implemented differently.

  1. Same issue exists in master
  2. It does not impact behavior, just throws an error

So, will clean this up in a separate diff T3463

tobias_ruck added inline comments.
cashtab/src/chronik/index.js
848 ↗(On Diff #46206)

slpv1 txs should only have 1 token entry

Even in pure SLPv1 world, a tx can have multiple token entries, e.g. if an input of a different token type is burned. This has always been difficult to represent (aka SlpBurns) but ALP kinda made it clear that simply having a list with them all is cleanest.

However, we do guarantee that the tokens mentioned in the OP_RETURN (if they are correct) will always come first, so for a valid SLPv1 tx, the first entry will always be the one of the OP_RETURN.

Hope this helps

cashtab/src/chronik/index.js
848 ↗(On Diff #46206)

Nice. Will need to upgrade Cashtab tx parsing in many ways going forward...not really happy with the shape of parsed I'm returning here either. Still tho -- will be handled in later diffs.

The assumption I'm making here that could bust Cashtab -- we will always have a tokenId in tokenEntries[0], if tokenEntries[0] exists and this is an slpv1 tx.

... no reason I need to assume this tho, will update the code so that if I can't get it, it's not parsed as an slpv1 tx.

make sure you have entry.tokenid

This revision is now accepted and ready to land.Mar 16 2024, 08:40
This revision was automatically updated to reflect the committed changes.